Ich hatte mir schon lange gedanken über einen einfachen 1 Wire Bus gemacht der Multimasterfähig sein soll. Ich hab jetzt die Idee einfach den RS232 Aus und Eingang eines AVRs dafür zu nutzen. Schaltungstechnisch werden einfach beide Pins (RX sowie TX) miteinander verkoppelt. Dadurch brauch ich nur noch einen Draht für die Übertragung. Die Idee ist das wenn der Master selber sendet einfach der Interrupt für RX received abgeschaltet wird. Ausserdem kann man nach jedem gesendeten Byte sofort mit hilfe des RX eingangs kontrollerien ob die Daten richtig gesendet wurden (also das kein zweiter Master gerade sendet). Um das ganze richtig Multimasterfähig zu machen lass ich einfach per PIND (beim ATMega8515) 500 Zyklen überprüfen ob kein Signal gesendet wurde. Ist das nicht der fall so kann der Master senden. Bei einer Taktfrequenz von 4MHz und einer Bautrate von 9600 wird praktisch jeder 416,6te Zyklus des Prozessors zum Übertragen eines UART Signales benutzt. Somit bin ich mit 500 Zyklen zum überprüfen auf der sicheren Seite. Bzw. ich lass zwischen den Einzelnen Nachrichten eventuell 1000 Zyklen Zeit damit immer eine Nachricht fertig übertragen werden kann. Am Anfang jeder Nachricht steht das Byte 0 für neue Nachricht danach folgt die Adresse und dann der Inhalt. Das ganze ist für TTL Pegel gedacht. Hat jemand noch ne Idee, Anregung oder hat jemand sowas schon probiert und weiß eventuell auf welche Probleme ich stoßen könnte?
Auf viele - kurz gesagt. Habe zwar nichts in der Art bisher versucht - aber es wird glaube ich nicht ganz so einfach. Dann lieber einen draht mehr und dafür rs485 -> denn so wirklich MultiMaster fähig ist deiner ja nun auch nicht ;-) Oder aber, garkein draht und dafür Enocean - Funkmodule ;-) Die krachen dann erst richtig!
RS232 mit Open Collector hat schon mal jemand probiert. Nennt sich LIN Bus und ist sowas ähnliches wie CAN für Arme.
Zur Kollisionsvermeidung schau dir mal CSMA/CA oder Aloha, WLAN etc. an. Ich habe zwei Controller (Master-Slave) so über eine Leitung kommunizieren lasssen und es hat Sauber funktioniert. Was ich festgestellt habe, ist dass der Master ein Zeichen erkennt, wenn ich die Sendeinheit des Slaves abschalte. Nun habe ich da umgangen, indem ich einfach den receive Inrerrupt abstelle. Gruß, Slowflyer
hmm... Korrektur: Was ich festgestellt habe, ist dass der Master ein Zeichen erkennt, wenn ich die Empfangseinheit vor dem Senden des Slaves abschalte. Nun habe ich da umgangen, indem ich dise einfach nicht mehr abschalte.
Sooo. Soweit funktioniert der Bus jetzt schon. (Wenn er komplett fertig is kann ich den Quellcode hier gerne in C bereitstellen. Ist halt ein recht einfach zu bedienender Bus ohne viel Schaltungsaufwand) Im Moment hab ich einen ATMega8515 im STK500 stecken und für die Gegenstation hab ich mir'n kleines ComPort Programm am Rechner geschrieben. Funktioniert soweit auch ganz gut. Nur wenn ich jetzt die beiden Leitungen (TTL Pegel vor dem MAX232) zusammenschalte dann kann mein µC zwar senden aber der PC nicht mehr. Jemand ne Idee? Ist da eventuell am Comport eine art besetzt überprüfung nochmals vorhanden?
Wie verhinderst du, dass 2 Master gleichzeitig den TX Pin aktivieren? Einfach nur alle RX/TX-Pins zusammenkloppen dürfte nicht funktionieren, irgendwann wird immer mal der Zustand eintreten, dass dann zwei TX gegeneinander arbeiten. Und dieser Zustand ist ziemlich ungesund für alle Beteiligten. Wenn du der Ansicht bist, einen echten Multimaster ohne zentralen Arbiter und mit direkt gekoppelten TX-TX Anschlüssen ausschliesslich per Software realisieren zu können - nur zu, das wäre durchaus interessant. Mindestens OpenCollector/OpenDrain-Treiber (Notlösung: Diode) wirst du schon reinschalten müssen: TX => O.C.Treiber => RX, Bus => Pullup-Widerstand. Analog auch PC-Anschluss vom STK500
Meinst du das der Zustand ungesund ist? Was ist genau so ein OpenDrain Treiber? (Konnte bei Wikipedia nix drüber finden) Ich denk bei TTL Pegel dürfte es doch nichts machen wenn mal 2 oder mehrere Master das Signal versehentlich auf GND ziehen. Das 2 Master nicht gleichzeitig senden können mach ich ganz einfach. Wie oben schon gesagt lass ich vor dem Senden den RX Pin eine gewisse Zeit lang überprüfen das dieser 0 (also auf VCC) ist und in dem Zeitraum auch 0 bleibt. Danach sendet er einfach los. Es ist schon sehr unwarscheinlich das genau 2 Master exakt zur gleichen Zeit versuchen etwas zu senden. Aber auch dieses Problem werde ich noch lösen. Da Rx un Tx Pins ja zusammen verschaltet sind kann ich nach jedem gesendeten Byte ganz einfach überprüfen ob am Rx Pin auch das angekommen ist was ich am Tx Pin gesendet habe. Ist das nicht so, muss in diesem Moment ein anderer Master auch noch gesendet haben. Dann wartet jetzt jeder Master eine bestimmte Zeit + eine Delay Zeit (die aus der Geräte Adresse generriert wird). Damit ist es unmöglich das nun wieder beide zur gleichen Zeit senden können. Im Moment hängt in meim STK500 zwischen RX und TX ne Büroklammer (ich weiß nich gerade sauber aber zum testen reichts) ... Nur WARUM SENDET MEIN PC NICHT MEHR? ... ich werde jetzt dann gleich mal 2 µC auf ne Testplatine aufbauen und gucken ob die beiden wenigstens korrekt senden. Wenn ich das mit dem PC nicht lösen kann mache ich es anders. Dann kommt noch ein AVR Chip mit Dual UART rein. Eine Seite an den Bus und die andere an nen Rechner. So sollte es dann dort keine Probleme mehr geben.
>Ich denk bei TTL Pegel dürfte es doch nichts machen wenn mal 2 oder >mehrere Master das Signal versehentlich auf GND ziehen Nö, warum auch. Interessant wird es, wenn einer davon H-Pegel liefert und alle anderen das Signal gegen Masse ziehen.
Ja Raul das ist ja dann der Fall das praktisch der eigene Master was anderes am Rx empfängt als er eigentlich durch Tx gesendet hat.... und dann weiß eher aha hier is was faul und wartet.
Bis dein Controller das gemerkt hat, ist dein TX-Pin hin. >Ist das nicht so, muss in diesem Moment >ein anderer Master auch noch gesendet haben. Dann wartet jetzt jeder >Master eine bestimmte Zeit + eine Delay Zeit (die aus der Geräte >Adresse generiert wird). Damit ist es unmöglich das nun wieder beide >zur gleichen Zeit senden können. Das ist bei Multimasterbussen Standard. Würdest du einen CAN-Transceiver benutzen, wärst du auf der sicheren Seite. So wirst du dich immer wieder wundern, dass du mal wieder einen Controller bzw. dessen UART zerschossen hast.
Kannst du mir erklären was genau ein CAN-Transceiver macht? Und wenn ich vor jeden Rx und Tx pin nen kleinen Wiederstand schalte? Dann dürfte ich mir da doch eigenlich nix zerschießen.
"as anderes am Rx empfängt als er eigentlich durch Tx gesendet hat.... und dann weiß eher aha hier is was faul und wartet." Wenn einer runter und der andere hochzieht, ist das Ergebnis sehr undefiniert, kann sein einer liest 0 der andere 1. Kann auch zu Fehlverhalten oder Reset des Controller führen, schlimmstenfalls zum Ausfall des Pins oder des ganzen Controllers. Deshalb muss da eine O.C. Trennung rein.
Okay das mit den Optokopplern ist kleine schlechte Idee. Ich glaub die werd ich auch reinbauen.... dann kann ich mir auch meine Idee mit den Wiederständen spaaren.
Serienwiderstand geht aus dem gleichen Grund nicht. Pin bleibt zwar ganz, aber Pegel ist undefiniert. http://de.wikipedia.org/wiki/Open_circuit Ein passender OpenDrain Treiber wäre beispielsweise 74HC07, aber nur geeignet für kurze Entfernungen (<<1m) bei niedrigen Bitraten (zig Kbps max). Für mehr ist ein CAN Tranceiver dringen anzuraten.
O.C. steht nicht für Optokoppler sondern für Open Collector. Heutigerdings natürlich eher Open Dran, aber die alte Bezeichnung lebt trotzdem weiter.
>Open Drain
Klingt immer wie offener Abwasser-Kanal... ;)
Wenn man die Schnittstelle "händisch" programmieren würde, könnte man
das I²C- bzw TWI-Prinzip mit dem Wired-And (oder wired-or? Die
Ansammlung von OpenDrain-Ausgängen auf einer Leitung halt) benutzen
(dann könnte man aber auch gleich die Hardware-TWI benutzen...).
Hab gerade bei Reichelt wegen Can Tranceivern geschaut. Konnte leider keine als DIL finden alle nur SMD. Gibts denn auch welche als DIL? Also das heisst ich schalte praktisch so einen Tranceiver zwischen meinen µC und dem Bus und dann kümmert sich der um dieses Problem mit Low & High? Zum testen werdens aber trotzdem erst mal Wiederstände.
Hallo Markus, Der SeaTalkBus macht eigentlich genau das was Du vorhast. Das ist ein 1-wire bus, mit dem Navigationsgeräte miteinander verbunden werden können. Ich habe sowas mal mit einem AT90S8515 gemacht und das funktioniert sehr schön. Alle Devices sind Masters, die aber prioritisiert werden können. Kollisionen werden erkannt indem man seine eigene Aussendung "mithört". Der Bus läuft mit 0-12V. Nähere Beschreibung ist auf http://www.thomasknauf.de/seatalk.htm Gruß Reiner
Ahh super danke Reiner. Das ist genau das was ich will. DA kann ich mir noch anregungen zwecks meiner Schaltung holen. Nuuuuur hab ich immer noch das Problem das mein PC nicht mehr senden will wenn ich vor dem Max232 auf TTL seite die PINS zusammen verschalte ;-) Weiß da jemand was?
Da ist wohl genau der Effekt eingetreten, der hier schon mehrfach angesprochen wurde: Da ist was kaputt.
Na sobald ich die verbindung der Pins wieder trenne geht es ja. Also direkt kaputt ist nichts.
Markus, Ich verstehe nicht was Du vorhast. Von den beiden TTL "Leitungen" des MAX 232 ist eine ein Input und eine ein Output. Der Output ist ein Totem Pole und kein Open Collector Ausgang. Ich nehme an Du willst folgendes machen: RX 1wire RX ----------------- TX TX Dazu brauchst Du auf jeder Seite des 1wire einen Combiner wie z.B in http://www.thomasknauf.de/seatalk.htm beschrieben Reiner
Ach ich war irgendwie grad bissal daneben. Und bin jetzt grad total verwirrt. Ich will praktisch eine Schaltung wie im Anhang machen. Nur wie genau muss ich die Ausgänge davon nun entkoppeln damit jeder µC das Signal auf 1 (low) ziehen kann? Ich muss da ja irgendwie nun einen Can Tranceivern einbauen, richtig? Nur wie genau?
Billiglösung, für kurze Distanzen: VCC + | | .-. | | | |1K '-' | | RX o----------------o-----------------o RX | | | TX o---|<-----------o----------->|----- TX 1N4148 1N4148
Alternative, aber immer noch kurze Distanzen: VCC | .-. | | | |1K '-' | | RX o--------------------o--------------------o RX | | |\ | /| TX o---------o >O-------o------O< |----------o TX |/ \| 1/6 74HC07 1/6 74HC07 PS: Falsches Symbol im Bild, AACircuit hat kein Bild eines Treiber-Gatters drin.
Für grössere Distanzen CAN-Transceiver. Das ändert aber nur die Distanz, nicht die Arbeitsweise, d.h. du kannst erst mal mit den o.A. Varianten anfangen und später umsteigen. Der PC-COM-Port passt da genauso dran.
PS: Die Diodenvariante taugt nur fur 5V, bei 3V ist der Low-Pegel etwas kritisch.
Soo vielen Dank erst mal. Mein Schaltplan (im Anhang) müsste praktisch genau der gleiche wie deiner sein. Jetzt noch kurz zum Verständniss für mich und bitte korrigier mich wenn ich das falsch sehen. Ich brauch die Dioden deshalb: Wenn der Tx Port nix (0) überträgt zieht er normal den Pegel auf High = VCC. Wenn er ne 1 überträgt dann zieht er den Pegel auf Low = GND. Ist die Diode nicht drinn und der Port ist auf Hight aber ein anderer möchte ihn auf low ziehen so gibts praktisch mischmasch bzw. kurzschluss. Wenn die Diode drinnen ist so kann der Port den Pegel nicht mehr auf high setzen aber auf low runterziehen, richtig? Warum ändert der Can Transreceiver was an der Distanz? Was macht der anders, als die Diode?
Ähhh neee. So stimmt dann auch der Schaltplan .... mensch is ja nich einfach X von T zu unterscheiden ;_)
"Wenn er ne 1 überträgt dann zieht er den Pegel auf Low = GND" Nur wenn du auf dem Kopf stehst. Füer die Asynchrone gilt TTL-seitig 1=high, 0=low. Seitens RS232 ist das anders, aber da sind wie hier nicht. Die Serienwiderstände solltest du weglassen, die können dir den Low-Pegel soweit versauen, dass es nicht funktioniert. Und die Dioden machst du bitte an TX, nicht an RX. CAN: Signale sind korrekt abgeschlossen wodurch Störungen durhc Leitungsrelexionen vermieden werden. Es werden seitens des Empfängers Differenzen gemessen, wodurch Störungen von Aussen weitgehend ausgefiltert werden.
Na wenn 1=high=VCC ist warum soll ich dann einen Pull Up wiederstand und keinen Pulldown reinmachen? Somit hab ich ja die ganze Zeit die Leitung auf 1 wenn nichts gesendet wird. Das mit dem Can hab ich jetzt verstanden .... kenne das vom DMX Signal her.
Wenn sich auf einer asynchronen Leitung nichts rührt, ist sie auf 1=high. Mit dem Startbit geht's los, und das ist 0=low. Jetzt klar?
Aha ;-) Wikipedia meint 1 = Low und 0 = High. http://de.wikipedia.org/wiki/1-Wire Aber du hast oben gemeint das es nur bei RS232 so ist und bei TTL anders. Sorry wenn ich jetzt grad so blöd frag aber ich bin verwirrt und möchte das gerne wissen. Wenn 1 = Low ist, dann ist mir das mit dem PullUp Widerstand auch klar.
Na super und Wiki sagt bei TTL auch 1=VCC http://de.wikipedia.org/wiki/Transistor-Transistor-Logik Ähh? Somit ist das Startbit keine 1 sondern eine 0?
"Wikipedia meint 1 = Low und 0 = High" Nein. So nützlich die Wikipedia ist, manchmal ist sie saublöd formuliert. So auch hier. Die Dallas-Doku dazu ist weit besser. Erstens ist ein Bus aus einem Draht nicht automatisch ein Dallas-1-Wire-Bus. Zweitens fängt bei 1-Wire zwar die Bitübertragung mit "low" an (vgl Startbit beim UART), aber nach 15µs wird das Datenbit gesampled und da gilt 1=high und 0=low. Anders ist es bei RS232, da gilt 1=-12V, 0=+12V.
Um das nochmal klarzustellen: Was hier aufgebaut wird, hat bis auf die Anzahl Leitungen rein garnichts mit Dallas-1-Wire zu tun. Ist auch gut so, denn der kostet Geld.
Okay danke für die Mühe.... jetzt hab ich's kapiert. Läuft jetzt auch prima ... nur das ich jetzt ein Softwareproblem hab... aber Hardwaretechnisch funktioniert es grad super.
Ich muss den Bus, Software sowie Hardwareseitig jetzt noch testen und noch Softwareverbesserungen machen. Wenn es soweit gescheit läuft post ich ma den Code hier wenn Interesse besteht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.