Hallo,
folgende Situation:
mehrere Funkmodule senden zu unbekannten (erratischen) Zeitpunkten (im
Schnitt vielleicht alle 30 Sekunden) auf der gleichen Frequenz
Datenpakete an einen Empfänger (Master). Wenn die Funkmodule nichts tun,
schlafen sie und sind taub (Strom sparen).
Die Funkmodule können halbduplex mit dem Master kommunizieren. Sie
können also beim Master anfragen, ob ihr Datenpaket angekommen ist oder
nicht.
Wie geht man nun am effektivsten mit Kollisionen (zwei oder mehrere
Module senden gleichzeitig und stören sich) um? Welche Strategie
minimiert die nötigen Re-Transmits am besten? Die Anwendung ist nicht
zeitkritisch und die Pakete sollten nur innerhalb von etwa 10 Sekunden
beim Master ankommen. Die Übertragung eines Datenpaketes dauert
technik-bedingt etwa 100ms.
lg,
Collider
Collider schrieb:> Wie geht man nun am effektivsten mit Kollisionen (zwei oder mehrere> Module senden gleichzeitig und stören sich) um?
Du könntest dir u.A. Shockburst, mit deinem Ack, des nRF24L01+ ansehen.
Das ist eine sehr stabile Strategie.
Collider schrieb:> Wie geht man nun am effektivsten mit Kollisionen (zwei oder mehrere> Module senden gleichzeitig und stören sich) um?
listen before talk
Collider schrieb:> Wie geht man nun am effektivsten mit Kollisionen (zwei oder mehrere> Module senden gleichzeitig und stören sich) um?
Indem man diesen Fall vermeidet, z.B. per CSMA
Collider schrieb:> Die Funkmodule können halbduplex mit dem Master kommunizieren. Sie> können also beim Master anfragen, ob ihr Datenpaket angekommen ist oder> nicht.
Das lass sie das machen. Oder lass den Master das Datenpaket wenn das
geklappt hat, ist es sicher angekommen. Der Rest sind
Wahrscheinlichkeiten, Timeouts und Zufall.
kenny schrieb:> listen before talk
Fertig überlegen, denn trotzdem können alle Funkmodule "gleichzeitig"
mit der Übertragung anfangen:
Alle wollen "zufällig" gleichzeitig anfangen und jeder hört, ob was los
ist. Weil alle nur hören, ist nichts los. Dann fangen alle gleichzeitig
an. In der Realität passiert das dann "zufällig" laufend (aka. Murphys
Law).
Wolfgang schrieb:> Indem man diesen Fall vermeidet, z.B. per CSMA
Das "funkt" aber nur, wenn sich der Sender auch selber "hören" kann. Bei
üblichen Funkmodulen ist das nicht der Fall.
Max M. schrieb:> CSMA/CD> Ist doch ein alter Hut!
Wie Lothar schon schrieb: in diesem Fall nicht anwendbar, da bei den
üblichen Funkmodulen keine Kanalkontrolle möglich ist. Der Sender kann
also nicht prüfen, ob er überhaupt etwas Empfangbares produziert hat
oder ob ein anderer Sender da reingepfuscht und das Signal gekillt hat.
Davon mal abgesehen: selbst wenn das Modul Fullduplex-fähig wäre, wäre
das Prinzip nicht wirklich brauchbar, denn natürlich ist das Verhältnis
der Signalstärken bei jedem der potentiellen Sender eine ganz andere als
beim eigentlichen Empfänger. Der Sender wüßte also nur, dass er selber
sein Signal erfolgreich empfangen hat. Das sagt leider wenig bis nichts
darüber aus, wie die Empfangssituation beim eigentlichen Empfänger war.
Nö, die Lösung ist natürlich ein Protokoll mit Acknowledge des
Empfängers und einem ordentlichen Schuss Zufall bei der Bestimmung des
Zeitpunktes für eine Wiederholung eines Paketes, für das kein Ack kam.
Dazu muß das Protokoll natürlich gewährleisten, dass aus dem Ack-Paket
hervorgeht, welches Paket genau damit eigentlich bestätigt wurde, sonst
könnte es zu der Situation kommen, das ein Sender das Ack für einen
anderen akzeptiert. D.h.: Sowohl im eigentlichen Paket als auch im Ack
dafür muss es mindestens eine Adresse geben, idealerweise auch noch eine
Sequenznummer. Oder (alternativ zu Adresse:Sequenznummer) eine Art GUID.
Schön, dass wir mal einer Meinung sind!
Fachlich klappt das ja manchmal....
Übrigens, in meinem vorherigen Posting, war ein (Sinn verzerrender ?)
Tippfehler.
Arduino Fanboy D. schrieb:> Du könntest dir u.A. Shockburst, mit deinem Ack, des nRF24L01+ ansehen.> Das ist eine sehr stabile Strategie.
sollte heißen:
> mit seinem Ack
Collider schrieb:> Wie geht man nun am effektivsten mit Kollisionen (zwei oder mehrere> Module senden gleichzeitig und stören sich) um?
0,2€ Uhrenquarz spendieren und TDMA verwenden?
Lothar M. schrieb:> Wolfgang schrieb:>> Indem man diesen Fall vermeidet, z.B. per CSMA> Das "funkt" aber nur, wenn sich der Sender auch selber "hören" kann. Bei> üblichen Funkmodulen ist das nicht der Fall.
Was verstehst du an "halbduplex" nicht?
Collider schrieb:> Die Funkmodule können halbduplex mit dem Master kommunizieren.
TDMA!!!einself schrieb:> 0,2€ Uhrenquarz spendieren und TDMA verwenden?
Wäre möglich, treibt aber den Aufwand hoch. Das Problem sind dabei nicht
die paar Cent für den Quarz. Am Ende erreichst du bezüglich der
Komunikation ein kaum besseres Ergebnis als mit reinem Zufall.
Sprich: lohnt den Aufwand normalerweise nicht. Das könnte allerdings
durchaus anders aussehen, wenn der Zweck breiter gefächert ist. Konkret:
wenn die Sender auch aus anderen Gründen über eine gemeinsame Zeitbasis
verfügen müssen oder das zumindest vorteilhaft wäre. Dann könnte das ein
durchaus lohnender Ansatz sein.
Collider schrieb:> Wie geht man nun am effektivsten mit Kollisionen (zwei oder mehrere> Module senden gleichzeitig und stören sich) um? Welche Strategie> minimiert die nötigen Re-Transmits am besten? Die Anwendung ist nicht> zeitkritisch und die Pakete sollten nur innerhalb von etwa 10 Sekunden> beim Master ankommen. Die Übertragung eines Datenpaketes dauert> technik-bedingt etwa 100ms.
Das CSMA meiner Nodes hat ungefähr so funktioniert, wie lkmiller das
beschrieb. Es kam also immer wieder zu Streitigkeiten, die erst nach
mehreren Minuten beigelegt werden konnten. Und das auch nur, weil die
CPUs der Nodes leicht unterschiedlich takteten, sonst hätten die sich
stunden- oder tagelang beharkt. Mit entsprechendem Stromverbrauch. Und
trotz bzw. gerade wegen ACK. Klar kann man die Node-ID mit einer
unterschiedlichen Wartezeit verknüpfen, aber es bleibt periodisch und
die zoffen sich unweigerlich (und nach Murphy tatsächlich viel öfter als
man denkt) wieder. Mit RNG ginge es vermutlich besser.
Meine Lösung war, daß die Nodes sich an timeslots und ansonsten die
Klappe halten. Das funktioniert so lange perfekt, wie die Anzahl der
Nodes und die Präzision des timeslots überschaubar bleibt.
Eine Node meldet sich beim Neustart beim Server, bekommt zusätzlich zum
ACK auch noch die Serverzeit zurückgemeldet. Und stellt dann den
nächsten Sendezeitpunkt so ein, daß er in das Zeitfenster Node-ID*1sec
fällt. Das funktioniert so gut, daß man CSMA wieder abschalten kann. Die
Nodes melden sich durch diese Regeleung wirklich zuverlässig wie entlang
eine Perlenschnur aufgereiht, ohne daß es zu überflüssigem traffic
kommt. Mit 1sec-timeslot kann man also 60 Nodes kollisionsfrei
betreiben. Sie justieren sich jede Minute neu.
Allerdings erfüllt es nicht Deine Voraussetzung, daß sie erratisch
senden dürfen.
Wolfgang schrieb:> Was verstehst du an "halbduplex" nicht?
Wieso sollte ich da an Halbduplex was falsch verstehen?
Und was hat die Kanalarbitration damit zu tun?
Hallo nochmal,
danke für die Rückmeldungen. Ganz so einfach ist es also doch nicht.
Mein jetziges Konzept sieht nun so aus, dass die Slaves für einen
gewissen Timeslot auf Empfang gehen, wenn sie ein Paket senden möchten.
Sie warten dann so lange bis der Master ein "Bereit-Signal" sendet.
Dieses Signal wird auch von Slaves empfangen, die zufällig ebenfalls ein
Packet an den Master senden wollen.
Jeder Slave sendet nun nach Empfang dieses Bereit-Signales sein Paket an
den Master. Hierbei hat jedoch jeder Slave sein individuelles
Sende-Delay (timeslot). Somit kommen alle Packete beim Master an ohne
sich zu überschneiden. Es ist keine komplizierte Zeitbasis nötig.
Nachteil der ganzen Geschichte: Der Master verbraucht relativ viel
Strom, da er in einem gewissen Intervall immer wieder sein Bereit-Signal
senden muss und anschließend für einen gewissen Timeslot auf Empfang
gehen muss. Zudem kann es passieren, dass die Slaves hin und wieder
etwas länger (maximal das komplette Zeitintervall des
Master-Bereit-Signales) warten müssen, bis sie ihr Paket loswerden.
VG,
Collider
Collider schrieb:> Mein jetziges Konzept sieht nun so aus, dass die Slaves für einen> gewissen Timeslot auf Empfang gehen, wenn sie ein Paket senden möchten.> Sie warten dann so lange bis der Master ein "Bereit-Signal" sendet.
Das ist nur sinnvoll, wenn die Slaves eine gemeinsame Zeitbasis haben.
Dann muß man aber auch ein Protokoll implementieren, welches genau diese
sicherstellt. Das ist nicht nur schwieriger, sondern oft auch bezüglich
der Energiebilanz der Slaves weniger effizient.
c-hater schrieb:> Collider schrieb:>>> Mein jetziges Konzept sieht nun so aus, dass die Slaves für einen>> gewissen Timeslot auf Empfang gehen, wenn sie ein Paket senden möchten.>> Sie warten dann so lange bis der Master ein "Bereit-Signal" sendet.>> Das ist nur sinnvoll, wenn die Slaves eine gemeinsame Zeitbasis haben.> Dann muß man aber auch ein Protokoll implementieren, welches genau diese> sicherstellt. Das ist nicht nur schwieriger, sondern oft auch bezüglich> der Energiebilanz der Slaves weniger effizient.
Ich würde jedem Slave einen eigenen Identifier geben, aus dem sich der
Slave sein persönliches Delay errechnen kann.
im einfachsten Falle zum Beispiel so:
Slave ID0: wartet 0ms und sendet dann sein Paket
Slave ID1: wartet 1ms und sendet dann sein Paket
Slave ID2: wartet 2ms und sendet dann sein Paket
usw...
Also sähe ein Vorgang beispielsweise so aus:
Slave_ID2 erwacht und stellt fest, dass er ein Paket an den Master
senden will. Also geht Slave_ID2 zunächst auf Empfang und wartet auf das
Bereit-Signal vom Master. Nachdem er dieses Signal empfangen hat, wartet
Slave_ID2 2ms und sendet dann sein Signal.
Zufällig ist auch Slave_ID3 und Slave_ID4 zur gleichen Zeit erwacht und
machen das gleiche. Slave_ID3 wartet jedoch 3ms und Slave_ID4 wartet 4ms
nach dem Bereit-Signal des Masters.
somit kommen die Pakete von Slave ID2,ID3 und ID4 auch in dieser
Reihenfolge beim Master an.
Jürgen S. schrieb:> Das CSMA meiner Nodes hat ungefähr so funktioniert, wie lkmiller das> beschrieb. Es kam also immer wieder zu Streitigkeiten, die erst nach> mehreren Minuten beigelegt werden konnten.
Nach dem Freiwerden der Frequenz sollten nicht alle Module gleichzeitig
anfangen zu versuche, ihre Daten los zu werden, sondern erst eine
zufallsgesteuerte Zeit später (und unmittelbar vor der Aussendung noch
mal per CS prüfen). Dann hacken sie nach einer Aussendung nicht alle
aufeinander rum.
Collider schrieb:> Also sähe ein Vorgang beispielsweise so aus:
[...]
Könnte man so machen. Sichert dann aber nicht den Erfolg der
Übertragung, denn ausser den konkurrierenden Slaves deines eigenen
Netzes gibt es ja reichlich weitere potentielle Störquellen...
Funk ist kein Kabel!