Es gibt eine Reihe von Konzepten, mit denen Sie Ihren Traum verwirklichen können. Ich kann Ihnen im Rahmen dieser Antwort nicht genau sagen, wie Sie das umsetzen sollen, was Sie wollen, aber ich kann Ihnen die Konzepte zeigen, die Ihnen bei der Umsetzung helfen.
Zunächst einmal gibt es das Konzept von der Busmaster . Dies ist nicht unbedingt das Gerät, das die Kommunikation instanziiert. Stattdessen ist dies das Gerät, das besitzt und den Bus steuert.
Wenn ein Gerät nicht vorhanden ist. Wenn der Busmaster auf dem Bus kommunizieren möchte, bittet er zuerst den Busmaster um Erlaubnis. Der alte Z80 (nun, ich sage "alt", aber sie werden heute noch in vielen Formen verwendet) verwendete dieses Konzept, um anderen Chips die Verwendung der Daten- und Adressbusse zu ermöglichen. Es besteht aus zwei Signalen - BUSRQ und BUSACK. Ein Gerät prüft zunächst, ob BUSRQ oder BUSACK aktiv sind, und aktiviert BUSRQ, wenn dies nicht der Fall ist. Wenn der Busmaster bereit ist, den Bus an das andere Gerät abzugeben (er verwendet ihn derzeit nicht), aktiviert er BUSACK und das andere Gerät weiß dann, dass es den Bus verwenden kann. Nichts anderes kann es verwenden, bis BUSRQ und BUSACK beide veröffentlicht wurden. Schön und einfach und elegant.
Aber nicht perfekt. Wenn zwei Geräte im selben Moment nach dem Bus fragen, erhalten Sie eine Kollision . Dies ist ein häufiges Problem bei gemeinsam genutzten Bussystemen wie diesem und verursacht unzählige Probleme, es sei denn, Sie wissen, wie Sie richtig damit umgehen.
Geben Sie das Konzept zuhören, während Sie sprechen . Dies beinhaltet, dass das Gerät, das auf dem Bus sendet, auch hört, was auf dem Bus über einen separaten Empfänger gesendet wird. Es kann dann wissen, ob das, was es im Bus gesendet hat, tatsächlich im Bus gelandet ist. Wenn beispielsweise zwei Geräte gleichzeitig kommunizieren und eines 10011001
und das andere 11001100
sendet, wird das Ergebnis, das auf dem Bus angezeigt wird, möglicherweise als etwas anderes angezeigt, z 11011101
oder möglicherweise 10001000
, je nachdem, wie die Bussignale erzeugt werden. Wenn Sie also wissen, dass das, was Sie gesendet haben, beschädigt wurde, können Sie jetzt etwas dagegen tun.
Nächstes Konzept: Zurücksetzen . Hier warten beide Absender kurz und versuchen erneut zu senden. Solange beide unterschiedlich lange warten, erhält der erste, der es versucht, den Bus und kann kommunizieren. Aber wie garantieren Sie, dass sich beide um unterschiedliche Zeiten verzögern? Sie denken vielleicht, die Antwort ist einfach: Verwenden Sie eine Zufallszahl wie rand ()
oder random ()
. Das ist aber auch problematisch:
Ein anderes Konzept: Der Pseudo Zufallszahlengenerator
Der Arduino generiert keine Zufallszahlen . Es wird lediglich eine komplexe mathematische Formel verwendet, um eine Folge von Zahlen zu erstellen, die für uns zufällig aussehen . Sie sind es aber nicht. Schreiben Sie ein kleines Programm, um 10 Zufallszahlen seriell zu drucken, und führen Sie es mehrmals aus (drücken Sie die Reset-Taste). Sie finden jedes Mal die gleichen "Zufallszahlen" in der gleichen Reihenfolge. Versuchen Sie es auf einem anderen Arduino und Sie erhalten wieder die gleichen Zahlen. Immer gleich.
Also, was tun? Die Antwort heißt Seeding des Zufallszahlengenerators. Die nächste von rand ()
et al. Generierte Nummer hängt von der zuletzt generierten Nummer ab. Ändern Sie also die erste Nummer und alle anderen Nummern ändern sich. Sie haben jedoch eine Catch-22-Situation. Sie benötigen eine Zufallszahl, um den Zufallszahlengenerator zu setzen, damit er zufällig eine Zufallszahl generiert, um den Zufallszahlengenerator zu setzen ... ad infinitum. Siehst du, wohin das führt? Sie können nicht aus rand ()
säen, da rand ()
nicht zufällig ist, bis Sie aus einer zufälligen Quelle gesät haben. Sie müssen also eine zufällige Quelle finden.
Und das ist keine leichte Aufgabe. Die beste Quelle für Entropie , wie sie genannt wird, ist weißes Rauschen . Dies kann auf verschiedene Weise mit verschiedenen Schaltkreisen erzeugt werden - vom Durchbruch eines Diodenübergangs bis zur Verstärkung der thermischen Schwankungen in einem Widerstand mit sehr hoher Verstärkung.
Alle sind ziemlich komplex für das, was Sie wirklich wollen, aber es gibt eine einfachere, wenn auch etwas weniger zufällige Methode - lesen Sie einen analogen Eingang, der mit nichts verbunden ist. Es hat nicht so viel Reichweite wie ein geeigneter Entropiegenerator, sollte jedoch genügend Zufälligkeit bieten, um eine vernünftige Chance zu bieten, dass jedes Gerät einen anderen Startwert erhält.
Ein weiteres nützliches Konzept ist der Interrupt.
Dies ist gut in einer Situation, in der Sie nicht die Komplexität eines Multi-Master-Busses mit all den Kollisionen usw. wollen. Sie haben einen einzelnen Master, der die gesamte Arbeit am Bus erledigt, und wenn Sie ein Slave sind Das Gerät hat etwas Wichtiges zu sagen, es stupst den Master mit einem Interrupt an. Der Meister sagt dann "Ja? Was willst du?" worauf der Sklave antwortet "Jemand hat meinen Knopf gedrückt".
Auf diese Weise fragt der Master den Slave nicht ständig ab, um festzustellen, ob die Taste gedrückt wurde. Es wird häufig in Busanordnungen wie SPI verwendet, und es gibt viele Chips, wie z. B. IO-Expander-Chips, die einen Interrupt auslösen können, wenn einer ihrer Eingangspins den Status ändert.
Wenn Sie jedoch 20 Geräte haben, ist dies der Fall meine du hast 20 Interrupt Pins? Nicht unbedingt. Neues Konzept: verdrahtet ODER .
Es ist durchaus möglich, mehrere verschiedene Slaves mit demselben Interrupt-Pin zu haben. Der Pin wird normalerweise mit einem Widerstand auf HIGH gehalten (es könnte sich um einen internen Pullup-Widerstand handeln), und jeder Slave verfügt über einen Open Drain -Ausgang, der mit diesem Pin verbunden ist. Ein Open-Drain-Ausgang ist, wenn er ausgeschaltet ist, mit nichts verbunden - es ist, als ob sich der Pin im Eingangsmodus befindet (tatsächlich kann er durch Umschalten zwischen Eingangs- und Ausgangsmodus auf Chips emuliert werden, die keinen offenen Drain haben). Wenn der Ausgang eingeschaltet ist, verbindet er den Pin mit Masse und zieht den E / A-Pin nach unten, genau wie es eine Taste tun würde.
Es ist dann Sache des Masters, sich um die ihm bekannten Slaves zu bewegen an diesen Interrupt gebunden, um zu sehen, wer Aufmerksamkeit braucht. Sie können natürlich eine Reihe verschiedener Interrupt-Pins mit jeweils unterschiedlichen Gruppen von Slaves implementieren - möglicherweise einen mit hoher Priorität mit nur einem Gerät und einen mit niedrigerer Priorität mit jeweils mehreren Geräten.
Das gleiche Konzept von verkabeltem ODER und offenem Abfluss kann verwendet werden, damit mehrere Geräte alle dieselben physischen Kabel gemeinsam nutzen können. Genau so funktioniert I2C - die beiden Busleitungen werden von Widerständen hochgezogen, und die darauf befindlichen Geräte verwenden Open-Drain-Ausgänge, um die Leitung auf Low zu bringen und wieder auf High zu bringen, um die verschiedenen Logikpegel zu erzeugen. Wenn zwei Geräte beide zusammen ziehen, ist es nur niedrig. Ohne die Open-Drain-Methode würden Sie, wenn ein Gerät eine 1 und ein anderes eine 0 ausgeben würde, grundsätzlich einen Kurzschluss zwischen den beiden erhalten und die Chips beschädigen.
Und dann haben Sie natürlich das Konzept der synchronen versus asynchronen Kommunikation, aber das ist ein ganz anderer Fischkessel. Einfach gesagt, Protokolle mit einer Uhr wie SPI und I2C, bei denen ein Master diese Uhr erzeugt, sind synchron. Protokolle wie UART und RS-232, RS-485 usw. sind asynchron - sie beruhen auf beiden Enden, die sich darauf einigen, wie schnell Daten gesendet werden (Baudrate), damit sie wissen, wie die Signale bei ihrem Eintreffen zu interpretieren sind.