Hallo!
Seit einiger Zeit bin ich am grübeln wie man am Besten eine automatische
Geräteerkennung auf einem RS485-Bus realisieren kann.
Im jetzigen Zustand kann man 64 Geräte an den RS485-Bus anschließen und
jeder Slave besitzt eine eindeutige 16-Bit Adresse.
Wie kann eine automatische Erkennung ablaufen? Es ist bekannt das RS485
nicht wirlich für solche Aufgaben geeignet ist aber das kann ich jetzt
leider nicht mehr ändern.
Ist es nötig daß der RTS485-Slave die gesendeten Daten zur
Kollisionskontrolle wieder einliest oder gibt es unter Umständen eine
andere Möglichkeit das zu vermeiden ? Aktuell wird nämlich beim Senden
der Empfänger abgeschalten und die Hardware kann ich so schnell nicht
ändern.
Der Master hat übrigens eine Möglichkeit die gesendeten Daten wieder
zurückzulesen.
Da der Bus mit 9600 Baud betrieben wird kann leider ein Scan mit allen
Adressen leider nicht durchgeführt werden, würde zu lange dauern...
Grüße,
Bernhard
Hallo Bernhard,
das abscannen geht trotz 9600B und 64 Slaves bei RS485 trotzdem recht
schnell.
Wenn Du die Möglichkeit hast, den Portpin für RXD am Master zusätzlich
auch als Eingang einzulesen, so kannst Du das Prinzip der "Successiven
Approximation" einsetzen.
Eine Protokollanpassung musst Du hier natürlich vornehmen.
Folgender Ablauf:
Busscan aller Teilnehmer (16Bit Adresse)
1. Sende ein Request an alle Teilnehmer die eine Adresse mit Bit 15 = 1
haben. Diese senden dann eine 1 als definierten Impuls mit Zeitlänge
x
zurück. Du wertest den Portpin als Eingang aus.
Keine Reaktion ? So liegen alle Adressen weiter unten.
2. Ansonsten Request für Bit 14 = 1
3. 13=1
.....
Und so näherst Du Dich jeder Slave Adresse Stück für Stück an.
Die erkannten Teilnehmer, nehmen bei Scan für den nächsten Slave nicht
mehr
Teil.
So benötigst Du für jeden Teilnehmer 16 Requests (x 64)
Nach meiner Rechnung dürfte der Busscan für alle Slaves etwa 2-3 Sek.
dauern.
Oder ist das zu lange?
Micelli
Wir hatten auch mal dieses Problem. Die weltweit eindeutige Kennung von
Devices war 11 Bytes. Der Bus war 16 bitadressiert. Und devices kamen
und gingen beliebig, mit speziellen Vorgaengen. Dh wir muessten zuerst
erkennen was ist neu da, dem eine dynamische 16bit adresse zuweisen und
dann ueber die 16 bit adresse kommunizieren.
RS485 ist nicht besser oder schlechter als andere Systeme auch.
Was taten wir? Das Protokol wurde speziell so aufgesetzt. Jedes Device
hatte ein internes Flag : Adresse zugewiesen, mit mehreren
Zwischenschritten. Dann gab es das Command Unbekannte meldet euch, mit
einer Maske und als parameter.
Die maske sagte wieviele Bit der urspruenglichen Adresse zu maskieren
waeren. Dadurch gibt man dem Command eine Wahrscheinlichkeit mit, mit
derer sich dfas Device melden soll. Dann gab es noch eine Zufallszahl im
Device drin, die kann man mit einem Parameter neu anfordern. Diese
Zufallszahl wird mit der 11Byte kennung verknuepft. Und dann gibt es
noch einen Befehl, der den Devices sagt, dass sie die Zufallszahl zu
incrementieren haetten. Wenn nun die Verknuefpungen von ID, Zufallszahl
und maske hinkam, musste sich das Device mit der, dem Befehl
mitgegebenen Adresse melden. Ein separater Task auf dem zentralen
controller hat nun immer den Bus nach neuen abgefragt. Das ging
eigentlich sehr gut.
Hallo Micelli,
der Master hat leider keine Möglichkeit den RXD-Eingang auch als
normalen Port-PIN zu verwenden (Embedded-CPU). Was bei Deiner Idee unter
Umständen problematisch werden kann, ist, daß die Adressen der Slaves
sehr nach beieinander liegen können (10 Stück aus einer Charge haben
fortlaufende Adressen), oder?
Leider ist das Kollisionsverhalten bei RS485 nicht wirlich definiert, da
wäre es wohl besser RS485 mit CAN-Transceivern zu machen..
Grüße,
Bernhard
@Bernhard
Der Bus muß natürlich FailSave terminiert sein.
Sind alle Sender (TX) vom Bus abgeschaltet, darf an de Empfängern (RX)
kein undefiniertes Signal ankommen.
So ist der Zustand ja auch im Umschaltmoment von Senden auf Empfangen.
Mit etwas Rafinesse könntest Du das auch über RXD-Empfang realisieren.
Es können theoretisch alle Adresse hintereinander kommem aber warum soll
das problematisch werden?
Übringens ist das nicht nur eine Idee sondern bereits realisiert
(Hausbus) und funktioniert.
Es gibt noch einige Möglichkeiten um den Busscan auf die Hälfte oder ein
viertel der Zeit zu bringen.
Ein großartiges Kollisionsvorkommen tritt hier garnicht auf.
Die Treiber arbeiten nicht gegeneinander sondern lediglich in eine
Richtung
miteinader.
In wie weit sich so etwas in Deiner Appliaktion realsieren lässt, kann
ich
natürlich nicht beurteilen. Vorallem, wenn die Hardware schon komplett
steht.
Mici
@Micelli:
Ich erkläre kurz den vorhandenen Aufbau:
Master:
Sendet auf der seriellen Schnittstelle die Daten an den RS485
Transceiver und erhält alle gesendeten Daten auch gleich zurück
(Kollisions- und Buskontrolle). Frame-Fehler können z.B. nur vom UART
abgefragt werden, eine Verwendung des RXD-Eingangs als PIO ist leider
nicht möglich.
Der Bus ist am Master mit einem (abschaltbaren) Spannungsteiler auf
einen bestimmten Pegel geschalten und somit auf einem definierten
Zustand.
Slave:
Alle Slave empfangen die Daten auf dem Bus und werten diese aus. Beim
Senden wird der der RS485-Transceiver aktiviert und Empfangen
abgeschalten. Somit hat der Controller keine Möglichkeit die gesendeten
Daten zu verifizieren.
Das hätte ich gleich im ersten Posting schreiben sollen :)
@Cobb:
Ganz habe ich es noch nicht verstanden wie es funktionieren soll aber
ich muss mir das noch ein paar Mal durchlesen :)
Unsere aktuellen Slaves haben leider nur eine 16-Bit Adresse und eine
per Protokoll konfigurierbare fortlaufende Nummer. Darüber könnte man ja
die Unterscheidung Initialisiert/Neu angesteckt machen.
Bernhard,
nochmals. Das System hatte eigentlich keine Detektion von Contention.
Die Meldungen hatten alle einen CRC, der war richtig oder falsch. Wenn
bei diesem Login-Prozess eine Antwort der Devices kam, aber einen
falschen CRC hatte, wurde angenommen, das mehrere Devices gleichzeitig
geantwortet hatten, und danach wurde die Wahrscheinlichkeit zur Antwort
verringert. Wir hatten bis zu 1000 Devices am Bus. Der Kern waren die
Befehle. Die Zuweisungsbefehle hatten verschieden moeglichkeiten, die
wurden in einem Union-Struct, dh fallabhaengigem Record, mitgesandt.
Folgende Moeglichkeiten waren auswaehlbar.
1) Das bestehende Zuweisungsverfahren ist aufgehoben. Nach 2 maligem
Senden hat das jeder begriffen
2) Neue Zufallszahl generieren, aufgrund irgendwelcher interner
Variablen.
3) Zufallszahl incrementieren
Mit dem Befehl dabei war eine Wahrscheinlichkeit als maske. 0 = kein bit
maskiert, 16 = 16bit maskiert.
Hmm... ist schon ein Weile her ... die Zufallszahl AND die Maske = 0
heisst das Device soll sich melden. Ah, ja. Die Zufallszahl hatte was
mit der ID tun, als startwert fuer den Generator. oder so.
Mehr muesste ich nachschauen.
@Bernhard
Nach der Beschreibung Deiner Netzwerkumgebung würde dieses Prinzip
einwandfrei funktionieren.
Welche Ausdehnung (Länge) hat Dein Datennetz?
Was heisst "abschaltbarer Spannungsteiler" ?
Abschlußwiderstand + FailSave Widerstände nach + und - ?
Mici
Die sauberste Lösung wäre, die RS485-Treiber durch CAN-Treiber
(PCA82C250) zu ersetzen (sind sogar billiger).
Das CAN-Signal ist auch differentiell, hat aber einen dominanten Pegel
(Low).
Dadurch ist der Pegel auch definiert, wenn 2 gleichzeitig senden.
Wenn also einer 0xFF und gleichzeitig ein anderer 0x00 sendet, liest der
Master immer 0x00.
Man könnte dann leicht eine bitweise Adreßerkennung wir bei 1-Wire
machen.
Peter
@Peter
Da hast Du schon recht.
Nur das CAN Treiber billiger als RS485 sind???
Das hängt wohl ganz vom Typ ab. (Anzahl Nodes, Übertragungsrate,
Stromverbrauch, etc.)
Nur wie er schon schrieb, er hat eine bestehende Hardware und muß also
mit dem auskommen, was er hat.
Mici
@Mici:
Normalerweise sind am Master drei Widerstände am Bus um diesen auf einem
Level zu halten und diesen zu terminieren:
------ ------- ------
+5V ---| R1 |---[RS485-A]---| Rterm |---[RS485-B]---| R2 |---GND
------ ------- ------
Bei unserer Hardware kann man jeweils R1/R2 oder Rterm je nach Bedarf
zu- und wegschalten. Vielleicht kann man diese Funktion irgendwie für
einen Busscan "missbrauchen".
Grüße,
Bernhard