PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Adresshandling/(-konflikte) in Bussystemen (TWI)



Schottky
19.04.2009, 08:31
Ich habe ein TWI-Bussystem mit einem Master und vielen Slave. Dieser Bus ist sehr dynamisch d.h. es kommen Slave hinzu oder weg. Aber das nur nebenbei, denn es geht eigentlich um das Prinzip.

Zwar erhalten die Slave ja normalerweise statische Adressen bei der programmierung. Nun muss man von jedem TWI-Slave die Adresse wissen, ist ab und zu nicht leicht, wenn die Anzahl etwas grösser ist. Auf einmal geht gar nix mehr im Bus, Also den letzten Slave nochmal raus, schauen ob es jetzt geht, die Adresse ändern und wieder rein.

Jetzt suche ich nach einer Möglichkeit in einem solchen Fall die Adresse von einem Slave auf eine noch freie Adresse zu ändern. Ich suche nur die Vorgehensweise, also konkreter Code ist nicht nötig sondern nur wie man sowas löst.
Weil die Nachricht vom Master an die eine Adresse, die mehrmals belegt wird, wird von mehreren Slave beantwortet, das müsste der Master merken und allen Slave mit der Adresse zu einer neuen Adresse verhelfen. So nun ist das ja ein Bus, und wenn die Nachricht, ändere Adresse an eine Adresse geschickt wird machen wieder alle Slave das gleiche. Problem ist gleich geblieben. So nun könnte man den Slaves eine Funktion implementieren das sie eine pseudo-zufällige Adresse aussuchen und sich daraufhin beim Master melden und der sein ok gibt. und das solange bis keine Konflikte mehr vorhanden sind. Aber für ideal halte ich das nicht. Ich habe schon ein Problem damit überhaupt einen Adressenkonflikt Masterseitig zu erkennen. Wie erkennt man Softwaremässig beim Master ob mehrere Slave antworten. z. B. der ACK. der würde ja auch von allen Slave gegeben.

Ist das Problem lösbar? Gibt es da schon fertige Ansätze? Ich finde in Goolge nichts, wahrscheinlich falsche Suchbegriffe.

Jaecko
19.04.2009, 12:09
Ich würds so machen, dass jeder Slave von Anfang an eine bestimmte, feste ID hat; z.B. 0xFF. Der Master fragt die Adresse zyklisch ab. Steckt jetzt ein "neuer" Slave dran, wird er von der 0xFF auch ne Antwort kriegen. Jetzt kann man z.B. abfragen, was das für ein Slave ist und dem dann ne neue Adresse zuweisen.
Klappt nur, solange nicht mehrere Slaves gleichzeitig angesteckt werden.

Schottky
19.04.2009, 12:28
Aber auch zum Beispiel bei einem Neustart oder Spannungsausfall hat man das gleiche Problem wieder weil zum Beispiel 3 Slaves die gleiche programmierte adresse haben.

Die optimale Lösung wäre das die Slaves keine oder die gleiche haben z. B. 0xFF. und dann alle vom Master initialisiert werden und eine Adresse zugewiesen bekommen. Problem wäre gelöst.
Es ist nur noch die Vorgehensweise dieser initialisierung zu klären.

Das sind eigentlich alles AVR-µC. Ist damit ein Bus zu realisieren mit dem ein solches Problem umgangen werden kann? Ich bin nicht unbedingt gezwungen TWI zu verwenden.

Jaecko
19.04.2009, 12:41
Stimmt, sobald der Strom weg ist, "vergisst" der Slave halt seine ID; ausser er speichert sie im EEPROM, dann ist sie aber auch wieder "fest".

Ne Alternative wäre CAN.
Da wird dann kein bestimmter Teilnehmer angesprochen, sondern es wird einfach was mit einer bestimmten ID gesendet und jeder andere Teilnehmer, der die Info braucht, holt sie sich einfach. Anhand der ID kann festgestellt werden, wer gesendet hat bzw. was der Inhalt der Daten ist.

Zwar darf jeder Teilnehmer beliebig viele IDs senden, jede ID darf aber nur von max. 1 Teilnehmer gesendet werden => "automatische" Arbitrierung bzw. Auflösung von Kollisionen; senden 2 Teilnehmer gleichzeitig, gewinnt der mit der niedrigeren ID; der andere bricht dann ab und versucht es später nochmal.

Master und Slave gibts da dann auch nicht mehr.

Schottky
19.04.2009, 15:02
Aber da bräuchte ich wieder einen CAN-Controller?!

So einen Umbau kann ich mir schon rein Platztechnisch nicht leisten.
Wäre natürlich eine Überlegung wert auf CAN zu wechseln.

Wenn jemand noch eine Lösung parat hat kann er sie ja schreiben.

Ich werde mir wohl eine andere Lösung für mein Adressenproblem einfallen lassen müssen. Vll. klebe ich auf jeden Slave ein Ettiket mit den entsprechenden Informationen. Das wäre mal eine Versuch wert. Und vll. die Programmierung ebenfalls adresstechnisch ein wenig organisieren.
Ist zwar lange nicht so gut wie wenn das automatisch ginge.

PicNick
19.04.2009, 15:50
Wenn die Slaves hw-eingestellte Adressen haben, kann man wenig machen.

Wenn die Devices am Bus aber programmierbar sind, hab' ich folgende Möglichkeit gewählt:

Jeder Teilnehmer sendet jede Sekunde ein "heartbeat" als GCA , Dateninhalt ist die eigene TWI-Adresse und ein Symbolischer GeräteCode (z.B 0xA5 = Ein Servocontroller). Dieser Code ändert sich natürlich nie.
Wenn ein Bus-Teilnehmer von diesem Gerät was will, trägt er sich die aktuelle Adresse ein.

Kommt ein neuer Teilnehmer auf den Bus, kann er die GCA-Heartbeats auf dem Bus abhören und kann erkennen, welche TWI-Adresse gerade frei ist. Die nimmt er sich und sendet ebenfalls GCA-Heartbeats s.o

Also: Der symbolische Gerätecode ist vereinbart und fix, die TWI adresse kann aber variieren.

Schottky
19.04.2009, 17:26
Was machst du wenn dein ganzes System down ist und dann startet.
Jetzt hast du zufällig 2 Servocontroller mit der gleichen Adresse auf dem Bus.
Wie ist so ein Problem bei dir gelöst?
Es ist ein guter Ansatz aber es löst das Problem immer noch nicht zu 100%.
Aber das geht doch auch nur bei einem kleinen Bus oder?
Die Heartbeats verschlucken doch sonst die ganze Bandbreite?

PicNick
19.04.2009, 19:11
Der logische Gerätetyp ist eindeutig, d.h. zwei (beispiel) servocontroller haben auch verschiedene Codes, sie haben ja verschieden Aufgaben.
Aus diesem Code leite ich bei Buskonflikten die Zugriffs-Wiederhol-Zeit ab, damit die Gleichzeitigkeit (nach Möglichkeit) vermieden wird.
Um beim Beispiel zu bleiben: einer der Servocontroller startet, hört den Bus ab. Wurde das komplette System gerade gestartet, hört er eigentlich garnix, weil ja alle erstmal lauschen. Er nimmt sich also die erstbeste adresse und schickt nach seiner individuellen Code-Zeit sein Heartbeat mit der Adresse los. Die Geräte mit kürzerer Zeit haben da aber schon gesendet, er muss also ggf. wieder revidieren und eine andere Adresse nehmen. (Für Geräte danach gilt das Gleiche).

In der Praxis ist das weniger kompliziert, als es vielleicht klingt:
1 Ein Gerät wählt sich irgendeine Adresse aus und wartet eine gewisse Zeit.
1a Kommt kein GCA mit dieser Adresse, schickt er einfach sein Heartbeat los.
1b Wenn schon, nimmt er die nächste und --> 1

Im Betrieb:
Wann immer: Wird ein (fremdes) GCA-Heartbeat empfangen mit der gleichen Adresse wie man selbst, geht man wieder in den "Lausch-Modus".

Und die Geräte, die diese Info brauchen, müssen ev. immer wieder ihrern Adresseintrag korrigieren, da sie sich immer wieder ändern kann.

Du hast recht, bei sehr vielen Geräten kann es etwas dauern, bis sich alle halbwegs einig sind. Aber dafür kann man eben einfach anstecken.

aaaaaaber: Wenn man Geräte am Bus hat, die da nicht mitspielen, (und das hat man meistens) wird die Sache komplizierter.

Ich verwende die Heartbeats auch, um An- oder Abwesenheit von Geräten festzustellen, um eine Konfigurationstabelle zu erstellen ( das macht aber der PC, der hat mehr Platz.)

Remark: In der Realität ist das Ganze mehr eine Fingerübung. Soooo variabel sind die Netz nun meist garnicht.

robin
19.04.2009, 20:15
Hi,

wie wäre es, wenn ein Master mit einer Speziellen adresse, den Slaves eine adresse zu ordnet.

Also sobald ein neuer Slave an den Bus kommt, übernimmt dieser den Bus und sendet dem Master seine Funktion (z.B. Servocontroller) und erhällt dann eine vom Master eine Adresse, die noch nicht zugewiesen wurde.

Wenn alle Teilnehmer resettet wurden, dann kann immer nur einer nacheinander den Bus übernehmen und so wird jedem einzeln eine eigene Adresse, die noch nicht verwendet wird zugewiesen und zur Not eine Liste im Master mit allen Slaves und deren Funktion angelegt.

So sollte das funktionieren, sofern deine Slaves senden können.

mfg robin

PicNick
20.04.2009, 06:55
Das wäre so eine Art DHCP Lösung. Problem: der "Bus-Master" kann keine Antwort schicken, solange keine TWI-Adresse festliegt.

Büffelmässig einfach: Man probiert alle TWI-Adressen aus, bis man KEIN Ack mehr bekommt. Es sind ja nur <127 möglich, soooo schlimm ist das auch nicht. Problem: Trotzdem kann es zu Fehlern kommen, und wie behebt man das dann ?

Netzman
20.04.2009, 08:48
Das stört doch eigentlich nicht, dass noch keine gültige I²C Adresse vorhanden ist, wenn das neue Gerät den "AVR-DHCP-Server" als Master abfragt.

mfg

PicNick
20.04.2009, 09:19
mmh, ja, könnte gehen, wenn du sicherstellst, dass der "Adress-Depot-Server" nicht re-startet wird (und dadurch wieder die gleichen Adressen vergibt)
Er könnte einen GCA-Adress-Reset versenden, auf den die anderen mit neuer Adress-einholung reagieren.
Ergibt aber wieder einen "single-point-of-failure".
Irgendwie verzwickt ist es immer.

however, es gibt bestimmt noch andere Lösungen als meine.

robin
20.04.2009, 12:48
Hi,

Das neu vergeben der Adressen könnte man unterumständen mit einem general call umgehen... sprich, sobald der "Adress-Depot-Server" resettet wird, sendet er zu beginn einen general call, worauf alle am Bus angeschlossenen geräte wieder in die "hole Adresse" routine fallen.

Oder man restartet den Adress server einfach nicht^^

mfg robin

PicNick
20.04.2009, 13:04
Letzteres ist wahrscheinlich eh' das beste *g*

das überlassen wir dem Herrn Murphy, der wählt den optimalen Zeitpunkt :mrgreen: