Moin,
ich möchte eine Sensorkette aufbauen. Die einzelnen Sensoren bekommen
jeweils einen kleinen µC, ich dachte an Atmel ATTINY... Es sollen also
kleine Module werden, die in einer Kette mit möglichst wenig Leitungen
verbunden werden sollen. Dazu soll die Platine an der einen Seite eine
Steckverbindung zum vorigen Modul und an der gegenüberliegenden Seite
eine Steckverbindung zum nächsten Modul haben.
Ich wollte mir nun einen µC heraussuchen mit UART und dann jeweils RxD
als Eingang vom vorigen Modul und TxD als Ausgang zum nächsten Modul
beschalten. Ansonsten würde nur noch die Spannungsversorgung
durchgeschleift. Jedes Modul würde die von RxD kommenden Daten einfach
an TxD weiterleiten und zusätzlich die eigenen Daten anfügen. Dazu
müsste man natürlich einen kleinen Puffer vorsehen und aufpassen, dass
die maximal mögliche Datenrate nicht überschritten wird. Jedes Modul
müsste seine Daten in ein Protokoll packen und mit einer "Herkunfts-ID"
versehen.
Am liebsten wäre es mir, wenn sich die Kette selbst konfigurieren
könnte. Also sprich, die Module schauen sich in ihrer Nachbarschaft um,
finden heraus, welches das erste ist, und konfigurieren sich
entsprechend eine ID für die Kommunikation anhand ihrer physikalischen
Reihenfolge. Eine Idee, wie man das Protokoll gestalten könnte?
Die Krönung wäre dann, wenn man sogar noch ein Softwareupdate aller
Module hinbekommen könnte, indem man den Programmer an den Anfang der
Kette anschließt.
Was meint ihr, wäre sowas umsetzbar? Wichtig wäre mir, dass die Module
einfach und klein bleiben. Klar könnte man vorhandene Schnittstellen wie
CAN etc. nutzen, aber ich möchte den hardwareseitigen Aufwand so gering
wie möglich halten.
Vor dem Programmieren habe ich keine Angst.
Hmmmmm im Prinzip ja. Ich würde das allerdings einfacher lösen:
Die µP hintereinander, den TxD vom einen an den RxD vom anderen,
ist noch OK. Protokoll mit "anhängen" ist suboptimal.
Einfacher jeder µP hat seine eigene ID. Der Master am Anfang
sendet eine Anfrage mit ID, die wir solange weitergereicht bis
der adresierte µP "gefunden" ist. Der µP ersetzt die Anfrage durch
seine Antwort (mit Adresse) und diese Antwort wird durch den
Rest der Kette an den Master zurückgereicht. Der Master wertet
die Antwort aus, nächste Anfrage. usw. Damit kommt man mit
definierten (kurzen) Stringlängen aus.
Nur die "Kette" hat einen Nachteil:
Wenn ein Mitglied ausfällt, warum auch immer, geht nix mehr.
Besser RS485, alle parallel schalten.
Derjenige, der dran ist belegt den Bus.
Rest wie gehabt: Master sendet Kommando, Slave antwortet.
Einfach, wirkungsvoll.
Ich habe beides schon erfolgreich eingesetzt,
mir sagt Lösung 2 eindeutig besser zu.
Sowas in der Art habe ich auch vor, nur will ich die Module per I²C
parallel schalten, was den Nachteil hat, dass man darüber nicht
adressierbaar machen kann. Deshalb mache ich eine oder evtl 2 Leitungen
Seriell durch. Der Master sendet einen Impuls und der erste setzt seine
Adresse auf 1, der nächste auf 2 usw. Somit kann man beliebig viele (bis
254) Module in beliebiger Reihenfolge (will mehrere verschiedene machen)
zusammenschalten. Ist der letzt erreicht, sendet er die anzahl an den
Master und der geht dann die Adressen durch um zu speeichern, welches
Modul unter welccher Adresse zu erreichen ist.
Ich habe hier eine Anwendung, welche die Adresse in jedem Chip
decrementiert. Ist die Adresse 0, ist der Chip gemeint.
So benötige ich keine unterschiedliche Konfiguration in den Chips.
Gruß
Jobst
Hallo,
ich habe genau einen solchen Aufbau für eine Anwendung mit LED-Strips
verwendet. Alledings habe ich dafür ATmega8 verwendet.
Die Kommunikation läuft dabei allerdings nur vom Master aus ab. Jeder µC
decrementiert die ID um 1, bei 0 ist dann das Ziel erreicht, wie weiter
oben beschrieben.
Weiterhin habe ich die µC mit einem Bootloader versehen, der ist etwas
modifiziert, so das er einfach das Signal weiterreicht wenn er selber
nicht gemeint ist. Funktionieren tut das auf jeden Fall ganz gut.
viele Grüße
Aike
Hallo in die Runde.
Das aktive Durchreichen von Daten an den nächsten µC fände ich unschön.
- fällt ein µC in der Kette aus, sind alle dahinter liegenden tot
- je weiter vorn der µC ist, desto mehr muß er Arbeiten
o unnötiger Stromverbrauch
o eventuell "Stille-Post"-Probleme
- je weiter hinten das Ziel, desto größer die Antwortzeit
Schöner würde ich eine Parallel-Schaltung aller Module finden.
- jedes Modul hat eine eindeutige ID
- nur wenn ID passt, gibt es eine Antwort
- dadurch garantierte Antwortzeiten
- passt ID nicht, kann µC in Stand-by gehen, aufwecken mit Rx-Interrupt
- Rundruf (z.B. an ID0) möglich - ID1 nach 1ms, ID2 nach 2ms usw.
- Ausfall eines Empfängers stört nicht den Rest
- mit etwas Hühnerfutter auch "1-wire" möglich
o Leitung mit Pull-up
o alle Rx parallel dran
o pro Tx eine Diode -> Pegel kann nur "runtergezogen" werden
-> Als Ergebnis sind nur 3 Leitungen nötig
-> µC könnte auch Richtigkeit SEINER gesendeten Daten selbst prüfen
er empfängt ja seine eigenen Daten
Nachteil der Parallelisierung:
- pro Modul an Tx eine Diode (oder Schutzwiderstand)
- pro Modul muß eine eindeutige ID hinterlegt sein
Diese 2 Nachteile würden aber (in meinen Augen) durch Stromersparnis,
Ausfallsicherheit und Geschwindigkeit der Datenübertragung mehr als
kompensiert.
Gruß...Harpax
Ingolf Geißler schrieb:> pro Modul muß eine eindeutige ID hinterlegt sein
Das war bei mir der Nachteil, dass ich mich entschieden habe "beides"
(grundsätzlich parallel, seriell zum identifizieren) zu benutzen. Aber
auch nur, weil ich 1. keine Lust habe, die Adressen jedes mal manuell zu
programmieren, 2. Ich verschiedene Arten an Modulen habe und 3. Ich
wissen will, welches Modul an welcher Stelle kommt. Wenn ich 15 Module
nebeneinander habe und will ein Modul an 2. Stelle einfügen, müsste ich
14 Module neu Programmieren, nur weil die Adresse um 1 hochgeht. So
initialisiere ich einfach und alles ist gut.
Man könnte auch die Weiterleitung extra (µC-Unabhängig) machen, mit
einem Glied, dass x Millisekunden wartet. In den Millisekunden kann der
µC seine Adresse einstellen und diese dem Master senden. Die anderen
Module, die noch nicht dran waren hören mit und merken sich, wieviele
Module sich schon gemeldet haben. Wenn die Flanke an der seriellen
Verbindung ist, weiß das Modul an welcher Stelle es ist und sendet es.
Sollte der µC ausfallen, kann er nicht senden, die anderen Module zählen
nicht hoch und das serielle Signal wird druch die externe Wartezeit
trotzdem durchgelassen. Und bei einem Kabeldefekt kann man halt nichts
machen, ob parallel oder seriell.
Allerdings, wenn du diese Flexibilität nicht brauchst und nur einmal
eine feste Kombination hast, würde ich die µCs auch mit der passenden
Adresse programmieren und dann ist gut.
Ingolf Geißler schrieb:> Stromersparnis
Da weiß ich jetzt nicht, was da groß an Stromersparnis ist. Was meinst
du damit?
Ingolf Geißler schrieb:> Geschwindigkeit der Datenübertragung
Das serielle wäre ja nur zum Initialisieren. Die Datenübertragung selbst
(Befehle, Antworten etc.) sind ja trotzdem parallel.
Hallo,
ich habe vor einiger Zeit mal sowas gemacht. Die Kommunikation lief über
IIC. Es konnten bis zu 250 SLAVES an den Bus gekoppelt werden.
Zusätzlich zu den IIC-Leitungen habe ich noch eine sog. CTRL-IN und
CTRL-OUT Leitung spendiert.
Vom MASTER geht der CTRL-OUT an die CTRL-IN von irgendeinen SLAVE
(zumeist der erste in der "Kette"). Wenn der MASTER die CTRL-OUT Leitung
setzt (ACTIVE L), dann reagiert der erste SLAVE auf das nachfolgende
IIC-Telegramm. Dieses Telegramm ist ein Adressierungs-Telegramm und
weist dem SLAVE die Adresse zu. Nach erfolgreichem Quittieren, setzt
dieser SLAVE dann seinerseits seine CTRL-OUT Leitung und diese geht dann
an die CTRL-IN vom nächsten SLAVE. Der MASTER sendet ein weiteres
Addressierungstelegramm usw. Nachdem somit alles SLAVES adressiert sind,
kann die eigentliche Kommunikation starten (Normalbetrieb). Der MASTER
weiss jetzt genau, wie viele SLAVES vorhanden sind - und wenn ein SLAVE
eingefügt oder entnommen wird, kann dieser auch wieder adressiert
werden. Der MASTER erkennt zudem, ob überhaupt noch alle SLAVES
vorhanden sind, indem er ein Pseudo-Telegramm sendet, auf welches nur
der letzte SLAVE in der Kette antwortet, denn wenn ein SLAVE aus der
Kette resettet, ist seine CTRL-OUT Leitung inaktiv. Dies erkennen alle
nachfolgenden SLAVES und reagieren nicht mehr auf Telegramme. Zusätzlich
sind noch weitere Maßnahmen integriert, die dem MASTER Informationen
über den Zustand aller SLAVES anzeigen - aber das geht jetzt zu weit und
ist wahrscheinlich auch nicht gefragt.
Gruß
TK
Warum kannst du nicht 3 oder 4 Portpins (je nach erforderlicher
Adresszahl) opfern, die du dann zur binären Einstellung der ID von
extern (mittels Lötbrücke) verwendest. Dann brauchst du nicht die
Controller unterschiedlich zu programmieren.
Ich hab mir für sowas auch schon mal gedanken gemacht, für ein Projekt,
was noch auf meiner TODO-Liste steht.
Jörg F. schrieb:> Warum kannst du nicht 3 oder 4 Portpins (je nach erforderlicher> Adresszahl) opfern, die du dann zur binären Einstellung der ID von> extern (mittels Lötbrücke) verwendest. Dann brauchst du nicht die> Controller unterschiedlich zu programmieren.
dazu bräuchte man gar nicht so viele Port Pins, eigentlich nur zwei.
einen eingang und einen Ausgang. die jeweils mit dem nächsten verbunden
werden.
die Initialisierung sieht so aus:
der hinterste µC in der Kette wird dauerhaft per Jumper gesetzt.
der Master fragt nun per Uart "init 0"
alle µCs, die noch nicht initilaisiert wurden schauen, ob ihr eingang
aktiv ist.
der µC mit gejumperten Eingang merkt sich die 0 als ID und setzt den
Ausgang zum nächsten in der Kette und schickt Antwort "init 0 done"
alle µCs, die noch nicht initilaisiert wurden schauen, ob ihr eingang
aktiv ist.
der mit aktiven Eingang setzt den Eingang des Nächsten und schickt "init
1 done"
usw
wird der Eingang des Masters gesetzt schickt der wieviele insgesamt
intialisert wurden
Es kann auf allen µCs das selbe Programm laufen und jeder sich abhängig
von seiner Position anders verhalten.
eigentlich bräuchte man hierfür noch nicht mal einen Master.
Guten Abend,
@ich (Gas)
Mit Stromersparnis meinte ich folgendes:
(Parallelschaltung)
Im Grundzustand (also niemand sendet) sind alle Sensor-Module (Slaves)
im Stand-by.Erst wenn der Master eine Zieladresse sendet, werden alle
Slaves durch Rx-Interrupt kurz aufgeweckt. Alle nicht angesprochenen
Slaves legen sich wieder hin. Nur der angesprochene Slave antwortet und
legt sich danach zu sein Kumpanen.
(Serien-Schaltung)
Master sendet Adresse des Ziel-Slaves an den 1. Slave. Dieser wacht auf.
Er fühlt sich nicht angesprochen, also muß er seinerseits selbst zum
Master für den 2. Slave werden. Er setzt das Telegramm ab und legt sich
dann hin. Irgendwann ist das Telegramm bis zum Ziel-Slave durchgereicht
und er antwortet. Nun geht die ganze Sache wieder zurück.
(Hab ich das System so richtig verstanden?)
Also System "Stille-Post".
- die Antwort von Slave-x dauert x-mal länger als bei Slave-1
- beim Stromverbrauch ist er 2*x-1 höher bevor die Daten zum Master
kommen
Finde ich ungeschickt.
Diese Überlegungen beziehen sich auf parallele bzw. serielle Anordnung
der Sensor-Module. Bei den hier vorgeschlagenen diversen Mischsystemen
greift das dann nur noch bediengt. :-) Aber dann sind auch meist mehr
Leitungen nötig.
Die Adresse könnte im EEPROM stehen, somit haben alle Slaves das gleiche
Programm. Firmwareupdate durch modifizierten Bootloader möglich.
@Vlad Tepesch
Meinst Du eine Daten-Ring-Leitung?
Master S-1 S-2 S-3
Tx---->Rx Tx--->Rx Tx--->Rx Tx-->I
Rx<------------------------------I
Wenn hier ein Slave bzw. ein Verbindung ausfällt, dann ist alles aus.
Gruß...Harpax
Ingolf Geißler schrieb:> @Vlad Tepesch> Meinst Du eine Daten-Ring-Leitung?>> Master S-1 S-2 S-3> Tx---->Rx Tx--->Rx Tx--->Rx Tx-->I> Rx<------------------------------I>> Wenn hier ein Slave bzw. ein Verbindung ausfällt, dann ist alles aus.
nein.
wie die Serielle Kommunikation gelöst wird ist unabhängig.
Ich würde die 1-wire Variante bevorzugen.
1
VCC
2
^
3
|
4
[¯]
5
[R]
6
[_]
7
|
8
| _________
9
+-->|--| TX IO | 3
10
+------| RX II |
11
| ¯¯¯¯¯¯|¯¯
12
| |
13
| ______|__
14
+-->|--| TX IO | 2
15
+------| RX II |
16
| ¯¯¯¯¯¯|¯¯
17
| |
18
| ______|__
19
+-->|--| TX IO | 1
20
+------| RX II |
21
| ¯¯¯¯¯¯|¯¯
22
| |
23
| ______|__
24
+-->|--| TX IO | 0
25
+------| RX II |
26
| ¯¯¯¯¯¯|¯¯
27
| |
28
|
29
_|_
30
31
32
II init in
33
IO init out
Ich würd für die Selbstkonfiguration zusätzliche Pins spendieren, sofern
die nicht Mangelware sind.
Zumindest die Selbstkonfiguration kann ohne Master passieren, so dass
auch der Master ermittelt werden kann.
Master wird nämlich der, dessen init-Eingang zu begin als low definiert
ist (aller anderen haben die Pullups aktiviert).
der am ende der Kette setzt nun den initout auf Ausgang und low und sagt
nun "init 1" oder so und alle die noch keine ID haben, schauen, ob ihr
eingang low ist.
Die II-IO-Kette kann man später ja noch für andere Sachen benutzen.
zb Sendetoken, oder so.
Wenn man bei der II-IO-Kette am Ende statt Masseverbindung einen
Pulldown setzt (eingänge alle ohne pullup und IOs von Anfang an auf High
und Ausgang) kann man hier auch einen Ring machen.
Allerdings würde ich bei dem System komplett auf Ring verzichten, da man
da ja Kabel von beginn der Kette zum Ende ziehen müsste.
Aber man will ja eigentlich nur einstecken.
Man könnte natürlich auch einfach eine Leitung parallel durch alle
Boards durchschleifen (ohne Verbindung zu den Controllern) und nur am
Anfang/Ende die Leitung mit den entsprechenden Pins verbinden
1
____ ____ ____ ____
2
/--|____|--|____|--|____|--|____|--\
3
\----------------------------------/
Edit:
das problem mit dem Ausfall besteht natürlich trotzdem.
Aber das besteht auch bei einem Bussystem.
Wenn zB im 1-Wire Bus ein µC rumspinnt und mit seinen TX den Bus
dauerhaft auf Low zieht oder gar RX auf Asugang stellt, ist der Bus auch
tot
Ingolf Geißler: Ich glaub, du hast nicht ganz verstanden wie ich das
meine. (Ich bin "ich (Gast)" )
Die einmalige Initialisierung sieht so aus:
Der Master sendet ein High aus. Dieser geht in den ersten µC / in das
erste Modul. Dann sendet der µC die Adresse "1" und seine Modul-ID (z.B.
0x55 für Temperatursensor und 0x66 für Drucksensor). Jetzt sind 2 Sachen
passiert. Der Master weiß, dass es ein Modul vom Typ x an der Adresse 1
existiert und die restlichen Slaves erkennen, dass an den Master die
Daten geschickt wurden und zählen einen Zähler hoch. Der erste µC
schaltet auf Normalbetrieb um. Durch die 1ms Verzögerung hat das Modul
Zeit, seine Daten zu senden. Das könnte man natürlich auch mit einem
Ausgang vom µC machen, nur darf dieser dann nicht ausfallen. Mit der 1ms
Verzögerung wird der µC umgangen und ein Defekt wird ignoriert. Nach
dieser Millisekunde bekommt der 2te µC / das 2te Modul das Highsignal.
Da passiert das gleiche. Durch seinen Zähler weiß er, dass er an 2ter
Position ist. Also sendet er an den Master seine Adresse ("2") und seine
Modul-ID. Das erste Modul bleibt unbeeindruckt, weil er die Adresse 1
hat, der Master aber 0. Die restlichen Module erkennen aber diese Null
und zählen wieder eins hoch.
Und so geht das weiter und weiter. Sollte ein µC ausfallen, wird das
High-Signal trotzdem nach einer Millisekunde weitergegeben und da in dem
Fall die restlichen Slaves nicht hochgezählt haben, da das Modul ja
nichts gesendet hat, bekommt das nächste heile Modul die nächste
Adresse. Ob ein Modul aktiv ist, kann man ja einfach mit einer grünen
LED an einem Ausgang vom µC sichtbar machen. So sieht man dann auch, ob
ein Modul geht oder nicht.
Der Master wartet grob 260-270ms auf Antworten (8bit Adressen => max.
254 Module) und danach weiß er, welche Module wo sind und wieviele es
insgesammt sind. Dann kann er in den Normalbetrieb schalten.
Alternativ dazu kann man auch eine Platinenseitige Rückführung machen.
(siehe alternative.PNG) Wenn der µC kein Signal am Eingang hat, ist kein
Modul mehr hinter ihm und somit kann der gleich hinter seinen Daten ein
"STOP" an den Master senden. Somit spart man die Zeit, die der Master
noch warten würde. Gerade, wenn man 16bit Adressen hat und (65535
Adressen = ) 65,5 Sekunden warten müsste.
Nach der Initialisierung kommt alles so, wie du es mit paralleler
Ansteuerung haben willst, nur dass der Master eine Liste hat, welche
Module/Slaves es mit welcher Adresse gibt. Somit ist die eigentliche
Kommunikation parallel, nur die Initialisierung "seriell". Richtig
seriell ist es auch nicht. Es wird halt ein Highsignal von Modul zu
Modul gereicht. Dieser sendet seine Antwort aber auch parallel zum
Master.
Wären insgesammt 5 Adern. 5V, GND, CLK, DATA und INIT. Ggf. eine sechste
Leitung für die Rückführung vom nächsten Modul. Bei 8bit Adressen glaube
ich aber, ich würde mich für die Wartezeit entscheiden, denn man spart
sich eine Ader und 260ms warten, bevor alles Startklar ist, sollte
ansich möglich sein.
Hier (allgemein bei Datenbusse mit Adressen) kann man auch schöne Sachen
machen wie Broadcast-Adresse(n). Adresse 255 sind alle Module (z.b. Für
Sensor abschalten) oder 254 für alle Drucksensoren und 253 für alle
Temperatursensoren. Und so weiter...
Und wieder Guten Abend!
@Vlad
Ahhh jetzt... also eine Mischung aus p und s.
@Michael
Ahhh jetzt... also eine Mischung aus p und s. :-)
Hmmm... würde die Konfiguration erheblich vereinfachen...hat was!
Habt Recht wenn die Anzahl der Sensor-Module eine gewisse Anzahl
überschreitet oder wenn die Module an schwer- oder un-zugänglichen
Punkten montiert sind wird es bei rein paralleler Lösung etwas schwierig
mit der Administration.
Ich glaube ich muß mich mal an dieser Stelle outen.
(Nein...bin hetero!)
Selber habe ich ein solches System (noch) nicht am Laufen - sind alles
nur Überlegungen. Ist halt wie bei Vlad...die To-Do-List...Wobei bei
meinem "irgendwann-wenn-Zeit-ist"-Projekt eine Funk-Lösung mit RFM12
angepeilt ist. Daher auch die Rx-Interrupt ,Stand-by und reine
"2-Draht"-Gedanken, weil Funk ja nur Rx/Tx hat und da kleine Solarzellen
zum Einsatz kommen sollen. Ach ja - Freizeit bräuchte Mann und das am
Stück und nicht geschnitten. :-) Und wenn die Freizeit dann urplötzlich
vor der Tür steht, dann ... ja dann sind bestimmt wieder andere Themen
wichtiger... Ist bestimmt nicht nur bei mir so.
@Michael Klennert
Was sind denn das für Module, die da einsetzen werden sollen, bzw. wie
sieht es mit der Datenrate aus - von Dir hat man ja nix mehr gehöhrt.
:-)
Vielleicht komm ich ja mit meinem Projekt einen kleinen Schritt voran.
Gruß...Harpax
Ingolf Geißler schrieb:> Daher auch die Rx-Interrupt ,Stand-by
Mit der UART kannst Du nicht Strom sparen. Ehe der Quarz aus die Hufe
kommt, sind die ersten Bytes schon vorbei.
Peter
Ingolf Geißler schrieb:> Ist bestimmt nicht nur bei mir so.
Ha, so ist es bei mir auch. Aber allmählich wirds was. Mein Problem ist,
dass meine To-Do-Liste ca 30 Einträge hat^^ Aber Manches davon ist echt
eher Pille-Palle bzw steht ganz weit unten. Z.b. Ein Signalgenerator
Sinus, Rechteck, Dreieck, Sägezahn. Das ist ein IC von AnalogDevice und
n PIC fürs Display und Bedienung.
Das was ich beschrieben habe ist quasi mein überlegtes Protokol für eine
Art SPS. Da will ich eine unbestimmte Anzahl an unbestimmten
"Einschüben" anstecken können, die Adressiert werden müssen. Ansich sind
die Planungen schon fertig. Nur entweder muss ich das Steuerprogramm vom
Master direkt in C schreiben und fest in den PIC programmieren (evtl
auch von SD-Karte gelesen werden) aber da muss ich mir noch was
überlegen in Richtung "Eigene Sprache" oder ein Programm in C, dass aber
mit einer größeren Lib arbeitet. Dass ich sagen kann "messwert =
get_adc(0,1);" wobei 0 das erste verfügbare ADC-Modul ist und davon der
2. Eingang. Da der Master ja eine Liste hat, weiß er welche Adresse das
erste ADC-Modul hat.
Wenn ich das Programm auf eine SD-Karte mache, dann nicht so derbe
überteuert wie von Siemens^^ Die wollen für ne 512KB!!! Karte ungefähr
70€ haben... Die haben doch n ** am kreisen. Zur Manuellen Bedienung und
Statusüberwachung etc. bekommt der Master noch ein Touch-Display.