PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Rs485 Protokoll Hilfe



Blamaster
11.02.2009, 16:37
Hi,

ich habe mir gerade mal wieder mein Rs485 Protokoll angesehen und bin auf ein Problem gestoßen, welches sich so noch nicht bemerkbar gemacht hatte:



Isrlabel:

Incr E_id
Daten(e_id) = Udr

If E_id = 1 And Daten(1) = S_id Or Daten(1) = 255 Then
Check = 1
Init = 1
Else
If Check = 0 Then
E_id = 0
End If
End If

If E_id = 3 And Check = 1 Then
For B = 1 To 3
Datenspeicher(b) = Daten(b)
Daten(b) = 0
Next B
Check = 2
E_id = 0
End If

If Check = 2 Then
If Crc8(datenspeicher(1) , 2) = Datenspeicher(3) Then
A = 1
Check = 0
Else
E_id = 0
Check = 0
End If
End If

Return


Gesendet werden an den Slave:

1. Byte Slave Id
2. Byte Eine Zahl von 1-99 anhand der im Slave eine Funktion ausgeführt wird.
3. Byte Crc Prüfsumme

Nun mein Problem welches ich nicht bedacht hatte, denn bei einem Slave macht das noch keine Probleme.

Der Slave bekommt nun also die 3 Bytes gesendet.

Wenn nun durch einen Übertragungsfehler ein Byte verschluckt wird oder nicht ankommt ist es nun bei einem slave so das nichts weiter passiert.

Spätestens nachdem dann 3 Bytes angekommen sind z.B. 2 Bytes durch die 1. Sendung und 1 Byte durch die 2. Sendung würde die Checksummen Kontrolle nicht aufgehen, das Protokoll zurückgesetzt und drauf gewartet das wieder die passende Slave ID ankommt.

Nun kommt aber ein Problem auf, sobald mehrere Slaves vorhanden sind.

Mal unter der annahme es gibt 3 Slaves und die haben die Id 1, 2, 3.

Nun sende ich dem Slave mit der Id 2 folgenden Befehl.

1. Byte = 2 (SlaveId)
2. Byte = 1 (Nummer für die auszuführende Funktion)
3. Byte Checksumme

Nun mag beim Slave mit der Id 2 auch alles richtig ankommen. Der Slave mit der Id 1 hat nun aber ein Problem, da er mit der SlaveId 2 zwar nichts anfangen kann mit dem 2. Byte welches die Zahl 1 einthält aber schon. Somit währe der Slave schonmal automatisch für eine kleine Übertragungszeit arbeitsunfähig.

Wenn man nun Viele Slaves hat und der Nummernkonflikt oft autaucht hat man also ein recht großes Problem.

Hat jemand eine Idee wie man das lösen könnte, außer zu sagen Werte von 1-50 sind mögliche Slave Id´s alles von 50 - 100 auszuführende Aktionen ?

mfg blamaster

Richard
11.02.2009, 17:58
Hi,

Wenn man nun Viele Slaves hat und der Nummernkonflikt oft autaucht hat man also ein recht großes Problem.

Hat jemand eine Idee wie man das lösen könnte, außer zu sagen Werte von 1-50 sind mögliche Slave Id´s alles von 50 - 100 auszuführende Aktionen ?

mfg blamaster

Moin moin.

Wie währe es mit einem für alle ohne ID gültigem Start/stop Byte?
Die ID kommt dann nach dem Startbyte und nur der Controller mit
der richtigen ID verarbetet dann die nächsten Bytes bis zum Stoppbyte.

Die Anderen warten/erwarten erst nach dem Stoppbyte ein neues
Startbyte. Lesen also quasie "leer" bis das Stoppbyte gekommen ist.

Gruß Richard

Blamaster
11.02.2009, 18:30
Wie kann denn so ein Start btw Stop byte aussehen ?

ThomasW
12.02.2009, 13:52
Hallo Blamaster

Ich mache das immer so.

Gesendet wird immer ein String also z.b >01_XXX_250_2F (also Ascii zeichen )


> =SyncByte
01 = Modul
xxx = Befehl
250 = wert
2F = Checksum ( erfunden, also keine Antworten Checksum stimmt nicht)





Const Sync_byte = 62
Dim Startbit As Bit
Dim Rxd_buffer As String * 32

startbit = 0

'########################## im RXD Interrupt
Rxd_byte = Udr

If Rxd_byte = Sync_byte And Startbit = 0 Then
Startbit = 1
Rxd_buffer = ""
Rxd_in_counter = 0
End If

If Startbit = 1 Then

Incr Rxd_in_counter

If Rxd_byte <> 13 Then
If Rxd_in_counter < 30 Then
Rxd_buffer = Rxd_buffer + Chr(rxd_byte)
End If
Else
Buffer = Rxd_buffer
Disable Urxc
Startbit = 0

End If
End If



Wenn jetzt > ( 62 ) ankommt wird das Sartbit auf 1 gesetzt und der Buffer geleert, jedes weitere Byte wird jetzt in den Buffer geschreiben bis die 13 (Return) ankommt, der Interrupt wird dann abgeschalten bis du z.B den String verarbeitet hast oder so ......

Man kann da so viel machen und jeder machts anders.

Mfg

Vitis
12.02.2009, 18:49
ich nehm gern Startbyte 0, da ich keine ID von 0 verwende

m.a.r.v.i.n
12.02.2009, 20:24
Hallo,

eigentlich verwendet man bei RS485 Übertragung den 9 Bit UART Mode. Das 9. Bit bestimmt dann, ob das übertragene Zeichen eine Adresse oder ein Datenbyte ist. Der Empfänger wird so programmiert, das er erst auf empfangene Zeichen reagiert, wenn er seine eigene Adresse empfängt (oder eine Broadcast Adresse). Folglich bekommt der Slave den Traffic, der zu den anderen Slaves geht, überhaupt nicht mit.
Die Atmel Controller mit UART sollten den 9Bit UART Mode unterstütze, heißt dort MPCM Mode. Ob BASCOM dafür Unterstützung bietet, weiss ich leider nicht.
Vielleicht hilft dir aber das weiter:
http://www.mikrocontroller.net/topic/53796
Ein Umsetzung mit AVR-GCC gibt es z.B. beim ROBIN Protokoll:
http://www.bdmicro.com/code/robin/

veit
12.02.2009, 22:33
hab startbyte 200 und endbyte 201.
wenn ich dann einen wert von 200 oder 201 übertragen will sende ich vorher das escape byte 202 und schicke den wert +10, die 202 lässt der slave dann unter den tisch fallen und zieht vom nächsten byte 10 ab.

Ceos
13.02.2009, 08:53
am wahrscheinlichsten ist ein übertragungsfehler durch einstreuung bei den bytes 0xaa und 0x55 quasi 10101010 und 01010101, die würd ich als start und stopsignal verwenden!