Multiplexing serieller Leitung

Ich habe diesen ID-Sensor für eine Scalextric-Slotcar-Strecke gebaut , basierend auf einem PIC12F629. Der ID-Sensor sendet die ID eines erkannten Autos als RS232-Signal auf einem Pin (TTL-Pegel).

Meine Frage ist, wie kann ich Daten von etwa vier dieser Mikrocontroller in den USART eines anderen Mikrocontrollers (PIC18F2550) empfangen?

Ich bin auf diese Möglichkeiten gekommen:

  1. Schließen Sie einfach alle seriellen Leitungen "direkt" an den RX-Pin des PIC18 an und hoffen Sie, dass zwei Autos nicht so nah an einem Sensor vorbeifahren, sodass sich die Signale überlappen. Dies könnte tatsächlich ein guter Anfang sein und wird wahrscheinlich in 99,9 % der Fälle funktionieren. Ich meine, die rechnerische Wahrscheinlichkeit, dass zwei Autos so nah an der Zeit entdeckt werden, kann den Aufwand der anderen Vorschläge nicht wert sein ... schließlich ist es ein Hobbyprojekt.
  2. Implementieren Sie ein Besetztzeichen, das ausgelöst wird, wenn der ID-Sensor Daten sendet, und vor dem Senden überprüft wird.
  3. Fügen Sie einen ausgefallenen Multiplexer-Chip hinzu, der die seriellen Signale frisst und sie auf einer einzigen Leitung ausgibt.

Jeder ID-Sensor-Chip wird mit einer Kennung codiert, die als Teil der Daten gesendet wird, damit sie auf der Empfängerseite getrennt werden können.

Update: Weitere Informationen zur Sensorhardware hinzugefügt.

Das ist wirklich eine Aufgabe für CAN. Mit einem UART dafür ein Kludge.
CAN zieht viel Protokollgepäck mit sich und schränkt Ihre Auswahl an Mikrocontrollern ein, aber wenn Sie es schwingen können, sicher.
Eigentlich denke ich, dass CAN eine sehr übertriebene Lösung für dieses kleine Projekt ist. Ich möchte es so einfach wie möglich halten.
Ich schätze alle Ihre Antworten und Kommentare. Ich möchte es aber trotzdem viel einfacher halten (ich bin kein Experte für Elektronik, aber ich lerne...). Wie ich in meiner ersten Alternative erwähnt habe, ist die Wahrscheinlichkeit sehr gering, dass es jemals zu einer Datenkollision kommt, und wenn doch, ist das kein Weltuntergang (es ist immerhin ein Spielzeugding). Ich kann die Lösung in Zukunft upgraden, wenn sie mir zu "fragil" ist. Bitte geben Sie ein Beispiel, wie Sie alle diese Sensor-PICs einfach an denselben RX-Pin auf dem empfangenden PIC anschließen können. Danke!

Antworten (5)

Wenn Sie Ihr Protokoll so einrichten, dass die Autos nur auf Anfragen des Controllers antworten, können Sie (zumindest auf der logischen Ebene) einfach alle miteinander verbinden.

Der Trick ist, ob Sie echtes RS-232 (mit 1 = -6 bis -12 V und 0 = 6 bis 12 V) oder nur eine Standardlogikleitung (1 = VCC, 0 = GND) haben. Darauf sollte entweder das Datenblatt oder ein Geltungsbereich antworten.

Wenn es Standardlogik ist, könnte es wirklich einfach sein. Wenn Ihre Sensoren ihre Ausgangstreiber steuern können, programmieren Sie sie so, dass sie den Ausgang nicht ansteuern, es sei denn, eine Nachricht wird ausgegeben. Wenn Sie den Ausgangstreiber die ganze Zeit eingeschaltet lassen müssen, lassen Sie ihn einen oder zwei Transistoren ansteuern, um eine "Open-Collector" -Konfiguration zu erstellen, verbinden Sie alle Kollektoren der Sensoren miteinander und ziehen Sie die angeschlossene Leitung an VCC hoch und schließen Sie sie an den RX-Pin Ihres Hauptcontrollers. Dies funktioniert, weil das RS-232-Protokoll im Zustand logisch 1 im Leerlauf ist. Wenn RS-232-Signalpegel verwendet werden, müssen Sie die Transistorkonfiguration ein wenig ändern, aber es bleibt im Kern immer noch Open-Collector.

Die Hauptsteuerung fragt einfach jeden Sensor nacheinander nach seinen Daten. Jeder Sensor antwortet auf Anfrage. Auf diese Weise haben Sie nicht mehr als einen, der gleichzeitig die RX-Linie fährt, was das Hauptziel ist.

Nun, wenn Sie Ihre Sensoren nicht dazu bringen können, nur dann zu sprechen, wenn Sie angesprochen werden ... dann wurde Ihr Problem sehr schwierig. So sehr, dass die einfache Antwort darin besteht, jedem Sensor einen eigenen seriellen Anschluss zu geben, möglicherweise unter Verwendung von 8-Pin-Controllern als Sensormanager, die dann an einen kooperativen seriellen Bus angeschlossen werden können. Andere Techniken, wie z. B. die Kollisionserkennung mit erneuter Nachrichtenübertragung (wie es 10base-T-Ethernet tat), sind viel komplexer.

Nachdem ich mir den geposteten Link sehr kurz angesehen habe, würde ich erwarten, dass es für die Fernbedienungen schwierig wäre, gleichzeitig nach einem Befehl von einer entfernten CPU Ausschau zu halten, während sie nach einem Auto Ausschau halten. Was sie jedoch tun könnten, wäre, auf ein ankommendes Auto zu warten und dann aufhören, nach Autos Ausschau zu halten, während sie auf eine Gelegenheit warten, das gesehene zu schicken.
@supercat Ja, das ist auch meine Vermutung. Ich möchte jedoch die Push-Logik verwenden, ohne die ID-Sensor-PICs abzufragen, sodass jeder Sensor die gleiche Verzögerung von der Erkennung bis zum Computer hat, da dies für die Rundenzeit der Autos verwendet wird.
@Anttu: Wenn es Ihnen nichts ausmacht, den Code für die Sensoren zu ändern, können Sie möglicherweise den Bericht von jedem Sensor so erweitern, dass die übertragenen Daten die Zeit zwischen dem Auslösen des Sensors und dem Senden des Berichts enthalten. Andernfalls, wenn die Datenrate und Reaktionsfähigkeit der Sensoren schnell genug sind, können Sie möglicherweise jeden Sensor 100 oder sogar 1000 Mal/Sekunde abfragen.
Sie sollten den Hauptcontroller eine Synchronisierungsnachricht senden lassen, die alle integrierten Timer des Sensors einstellt, damit die Sensoren ihre Daten mit einem Zeitstempel versehen können. Was eine Push-Lösung betrifft, siehe meinen letzten Absatz. Es wird hart auf hart kommen; es ist nur eine Frage der Zeit.
@MikeDeSimone diese Autos sind im Maßstab 1:32 oder 1:45. Ich bin mir sicher, dass seine Controller nur der PIC mit Logikpegelausgängen sind.

Wenn Ihr Sensor eine "bereite" Leitung aufnehmen und alle Ereignisse, die eintreffen, wenn sie nicht aktiviert sind, verschieben und sie übertragen kann, wenn dies der Fall ist, ist es am besten, eine separate Besetztleitung an jeden Sensor zu senden und ein "UND"-Gatter zu verwenden Kombinieren Sie die Signale aller Sensoren. Ich würde vorschlagen, dass Sie, wenn Sie vier Sensoren haben, die "bereiten" Drähte in Round-Robin-Manier mit etwas "toter" Zeit zwischen ihnen radeln sollten (wenn niemand "bereit" ist); Wenn ein Byte während der "toten" Zeit eintrifft, nehmen Sie an, dass es vom letzten aktiven Sensor gesendet wurde. Stellen Sie die "Bereitschafts"-Zeit lang genug ein, damit ein Sensor reagieren kann, und die Totzeit lang genug, damit ein Sensor Zeit hat, die Übertragung eines Ereignisses zu beenden, das auftritt, kurz bevor seine "Bereitschafts"-Leitung deaktiviert wurde.

Bearbeiten

Basierend auf weiteren Beschreibungen, da anscheinend jeder Sensor eine eindeutige bekannte ID-Nummer hat, denke ich, dass der beste Ansatz darin bestehen könnte, eine einzelne serielle Leitung zu haben, die über einen parallelen Widerstand und eine Diode mit einem PWM-Ausgang verbunden ist, so dass sie gezogen wird alle 2 ms für 1.900 us angehoben, aber für 200 us heruntergezogen (wenn man einen PWM-Schalter zwischen Active-Low und Floating haben könnte, wäre das noch besser). Sobald ein Auto gesehen wird, sollte ein Sensor die folgende Zustandsmaschine starten und verfolgen, wie viele zehn Mikrosekunden seit Beginn der Ausführung vergangen sind.

  1. Warten Sie, bis die Datenleitung hoch ist.
  2. Warten Sie, bis die Datenleitung niedrig ist.
  3. Line-Low-Timer löschen
  4. Warten Sie, bis die Datenleitung auf High geht, und erhöhen Sie während des Wartens den Line-Low-Timer (und den Haupt-Timer).
  5. Wenn der Timer anzeigt, dass die Leitung weniger als 200 us niedrig war, gehen Sie zurück zu Schritt 2
  6. Inkrementieren Sie den Line-Low-Timer weiter, während Sie darauf achten, dass die Leitung auf Low geht, bis dieser Timer eine bestimmte Dauer erreicht, die für die ID des Knotens eindeutig ist. Wenn die Leitung innerhalb dieser Zeit niedrig wird, gehen Sie zurück zu Schritt 3.
  7. Stellen Sie die Datenleitung auf Ausgang, übertragen Sie die Daten mit einer Rate von etwa 16 us/Bit (wobei die Leitung aktiv sowohl für High als auch für Low angesteuert wird) und beginnen Sie mit der Suche nach dem nächsten Auto. Beachten Sie, dass die Daten die Anzahl der 10-us-Intervalle enthalten sollten, die zwischen dem Erkennen des Fahrzeugs und dem Beginn der Übertragung verstrichen sind.

Unter Verwendung eines UART sollte dieser Ansatz es einem ermöglichen, Autos, die auf einem beliebigen Sensor ankommen, in beliebiger Reihenfolge zu verarbeiten und ihre Timings innerhalb von 10 us aufzulösen, mit der Maßgabe, dass Autos sequentiell mit einer Rate von einem alle 2 ms verarbeitet werden, und Sensoren werden dies tun "blind" zwischen dem Zeitpunkt, an dem sie ein Auto sehen, und der Haupt-CPU, um es zu verarbeiten. Wenn es nicht eine wirklich große Anzahl von Sensoren gibt, sollte das kein Problem darstellen. Beachten Sie, dass die Haupt-CPU kein genaues Timing für irgendetwas anderes als ihren PWM-Ausgang haben muss. Alles weitere ist dem seriellen Datenstrom zu entnehmen (auch die „langen Pausen“ durch die PWM-„Low“-Pulse).

Wie ich in einem anderen Kommentar geschrieben habe, hätte ich gerne eine Push-Lösung. Wie wäre es, wenn die Sensor-PICs stattdessen eine gemeinsame "Sendeleitung" hochziehen und diese Leitung vor dem Senden der Daten überprüfen lassen?
@Anttu: Wie in meinem Kommentar zu Ihrem früheren Kommentar erwähnt, sollte der Sender die genaue Zeit zwischen dem gesehenen Auto und dem Beginn der Übertragung notieren, um die erforderliche Genauigkeit zu erzielen, selbst wenn zwei Autos gleichzeitig auf verschiedene Sensoren treffen. Man könnte alle Knoten auf einem extern hochgezogenen Bus sitzen lassen und ein Kollisionsauflösungsprotokoll verwenden, aber das würde wahrscheinlich mehr Unsicherheit zu den Übertragungszeiten hinzufügen als die Abfrage. Übrigens, eine Sache, die man beim Polling beachten sollte, die ich oben vergessen habe zu erwähnen: ...
@Anttu: Für Mikrocontroller ist es oft einfacher, konsistente Timings für ausgehende Signale zu generieren, als die Timings eingehender Signale genau zu messen. Wenn der Sensor mit dem Senden bis zur fallenden Flanke seiner Sendeleitung gewartet hat und der Hauptprozessor die fallende Flanke für jeden Sender genau einmal alle 40 ms (100 Abfrageintervalle pro Sekunde, viergeteilt) erzeugt hat, wenn er weiß, wann er gesendet hat Der Abfrageimpuls und die gemeldete Zeit (vom Sensor) zwischen dem Ereignis und dem Impuls würden es der Haupt-CPU ermöglichen, Zeiten mit einer Genauigkeit von weniger als einer Millisekunde aufzulösen.
Da hast du wahrscheinlich Recht. Das einzige Problem ist dann, dass der empfangende PIC18F2550 nur 2 Pins zur Verfügung hat. In diesem Fall müsste ich also auf einen PIC18F4550 aufrüsten, der mehr E / A-Pins hat.
@Anttu: Ich würde vorschlagen, dass Sie die Verwendung eines externen Zählerchips in Betracht ziehen, der von einer der PWM-Leitungen des PIC angesteuert wird. vielleicht so etwas wie ein 74HC4017. Vielleicht speisen Sie einen der Ausgänge von diesem an einen Wechselrichter, der über einen Widerstand mit dem "Bus" verbunden ist (so würde er 9/10 der Zeit hochgezogen und 1/10 heruntergezogen, sodass Sie erkennen können, welcher Zustand der ist Zähler ist drin). Wenn Sie den Ausgang für den PWM-Betrieb konfigurieren können, könnte er schöne präzise Timings erzeugen, unabhängig davon, was der Code tut.

Sie können ein MODBUS-Protokoll im RTU-Modus mit RS485-Schnittstelle implementieren, das auf PIC gut funktioniert (bei Ihrem PIC nicht so sicher).

Sie können eine Multidrop-Leitung haben, um Ihre verschiedenen Mikrocontroller-Geräte auszuruhen und eine gute Kommunikation zwischen ihnen auf dem seriellen UART zu haben.

Sie können Ihren PIC18F2550 als Master machen, der die Transaktion von allen anderen 4 Controllern initiiert.

Bitte schreiben Sie Ihre Antwort in der richtigen Sprache neu; Diese Seite zielt darauf ab, eine dauerhafte Referenz zu schaffen, die besser ist, wenn sie richtig formatiert ist.
Entschuldigung, wenn Sie die Sprache als unpassend empfinden. Ich habe nur das Standardformat verwendet. Können Sie bitte sagen, wo das eigentliche Problem liegt?
Kümmern Sie sich nur um die Grammatik und verwenden Sie keine Abkürzungen oder ähnliches. Ich habe Ihre Antwort für Sie bearbeitet. Willkommen!
@clabacchio Ok. Ich werde ab dem nächsten Mal aufpassen.

Verwenden Sie Zeitmultiplex. Der Master sendet auf einer separaten Leitung einen Sync-Impuls, mit dem die Slaves einen Timer zurücksetzen. Wenn ein Slave Daten zu senden hat, wartet er, bis der Timer gleich (Slave-Nummer * Zeitfensterbreite) tickt, bevor er sendet. Der Zeitschlitz sollte lang genug sein, um das Paket zu senden und Taktungenauigkeiten zwischen Sensoren zu berücksichtigen.

Elektrisch gesehen möchten Sie vielleicht die gemeinsame TX-Leitung hochziehen und zwischen 0 und Tristate umschalten, um zu senden, anstatt Strom zu liefern, um eine 1 zu bestätigen.

Es hat einige Vorteile, wenn alle Prozessoren der Sensoren den gleichen Code ausführen; Es hat auch einige Vorteile, wenn alles auf denselben Drähten sitzt (anstatt z. B. einen 74HC4017 zu verwenden, um jeden Sensor nacheinander abzutasten). Eine Komplikation, die ich beim Zeitmultiplexen sehe, ist jedoch, dass ich nicht sicher bin, wie viel die Sensor-CPU leisten kann, während sie auf ein Auto wartet. Wenn man TDM verwenden würde, würde es eher auf ein Auto warten, dann auf den nächsten Synchronisationsimpuls warten und dann die Daten senden. Falls gewünscht, könnte die Datenleitung auch problemlos den Synchronisationsimpuls handhaben, wenn er länger als die Daten wäre.
Die Sensoren kennen jeweils bereits ihre eindeutige ID. Es muss nichts ausmachen, wenn dem Mikro ein Synchronimpuls fehlt. Konfigurieren Sie den 16-Bit-Timer des Mikros so, dass er dieselbe Periode wie der Sync-Impuls hat, setzen Sie den Timer auf einen Sync-Impuls zurück und warten Sie, bis der Timer vor dem Senden gleich (ID-Nummer) * (Timer-Ticks pro Zeitschlitz) ist.

Ich habe diese Seite mit einer Lösung namens BlackNet gefunden. Es basiert auf einem ziemlich einfachen Protokoll, bei dem die Idee darin besteht, dass jeder Knoten im Netzwerk einen eigenen Zeitschlitz hat. Dh es ist eine Art Round-Robin-Logik. Das letzte Bild auf der Seite zeigt ein Schema mit der geringsten Menge an Komponenten, die zum Funktionieren benötigt werden.

Ich habe diese Idee verwendet und einfach die beiden Sensoren, die ich gebaut habe, direkt an den RX-Pin des PIC18F2550 angeschlossen. Ich habe jedoch nicht das Round-Robin-Protokoll implementiert, sondern die Daten nur bitweise auf die Leitung gerammt (und gehofft, dass jeweils nur einer sendet). Bisher hat es eigentlich ganz gut funktioniert...

Für zukünftige Leser: Wenn es wichtig ist, dass Ihre Daten immer durchkommen, ist die von mir verwendete Lösung wahrscheinlich keine gute Idee. Wenn Sie jedoch selten Daten senden und mit der Möglichkeit leben können, dass es zu Kollisionen kommt, und Sie eine möglichst einfache Lösung wünschen, ist diese meiner Meinung nach gut genug.