da mein Kommentar doch für etwas mehr Wirbel gesorgt hat, als ich es erwartet habe, kommt nun doch ein kleiner Bericht zur Infrarot- beziehungsweise Ein-Darht-Bus-Übertragung zwischen Zugmaschine und Anhänger.
Die Grundidee ist, die Datenübertragung sämtlicher Lichtsignale, dh. Blinker re/li/warn, Abblendlicht, Bremslicht, Rückfahrlicht, Rundumkennleuchten, sonstige Funktionen, vom Zugfahrzeug zum Anhänger, ohne Zweitempfänger und zusätzliche Regler. Einen groben Überblick bietet dieses Schema:
Wird die IR-Übertragung genutzt, kommt diese Funktion zum Tragen: Empfängt die Empfangsplatine für eine kurze Zeit kein Signal (z.B. weil der Anhänger abgekuppelt wurde und das Zugfahrzeug weiter gefahren ist), werden sämtliche Lichtfunktionen abgeschaltet, bis wieder ein Signal empfangen wird. Alternativ kann ein weiterer Ausgang vom Emfpänger (im Schema der F-Ausgang zB des Deltang-Rx) genutzt werden, um das Senden zu (de)aktivieren.
Die Platinen sind etwa so groß: Links der Sender, rechts der Empfänger 20160224_153552-1.jpg - Bild entfernt (keine Rechte)20160224_153418-1_2.jpg - Bild entfernt (keine Rechte)
Nun zu den Bausteinen selber:
Sender Wie aus obigem Schema hervor geht, hat der Sender mindesten 3 Eingänge. - Zum einen den gewöhnlichen Servoeingang für die Taststeuerung der Lichtfunktionen (1x links = Blinker links an/aus etc). Der Sender ersetzt das normale Lichttiny komplett. Das hat den Vorteil, dass auch eigene Wünsche an Blinkfolgen möglich sind.
- Zum anderen werden die Ausgänge des Reglers, die Brems- und Rückfahrlicht ansteuern, zusätzlich zum Sender geführt. Damit werden Brems- und Rückfahrlichtsignale zum Anhänger geschickt.
Ein Ausgang ist für die Datenübertragung reserviert (entwerde wie auf dem Bild der Platine mit Vorwiderstand der IR-LED oder ihne Widerstand für den Drahtbus). Alle anderen Ausgänge sind natürlich mindestens mit Blinker, Abblendlicht, Rundumkennleuchten belegt (RFL und BL kommen ja vom Regler). So können im Zugfahrzeug auch ggf Frontblitzer und Arbeitsscheinwerfer oder Heckwarneinrichtungen realisiert werden.
Empfänger Er hat nur einen Eingang, nämlich der der Datenübertragung (für IR-Übertragung sind zwingend noch ein Transistor und zwei Widerstände erforderlich). Alle anderen Ausgänge sind frei programmierbar.
Technische Daten Die Infrarot-Übertragung erbringt recht gute Reichweiten. Das gemessene Maximum liegt bei 1,2cm zwischen IR-LED und Empfangstransistor. Durch gute Abstrahlwinkel können selbst engste Kurvenradien gemeistert werden, wie die Tests gezeigt haben:
Die Verzögerung zwischen Sender und Empfänger ist minimal. Nur wenn man genau hinschaut, erkennt man sie. Ich habe mit meinem Oszilloskop eine Toleranz von ca. 75 Millisekunden ausgemessen, was denke ich nicht sonderlich stört.
Funktionsweise Die Daten werden Blockweise in 8-Bits übertragen. Dabei spielt das Timing eine zentrale Rolle. Das folgende Bild zeigt
Folgendes Timing liegt zugrunde: Funktion (high-Zeit in us/ low-Zeit in us) Init (400/100) kennzeichnet den Beginn einer Übertragung Reinit (500/100) kennzeichnet den Beginn des nächsten Datenbytes High-Data (200/100) Daten-Bit 1 Low-Data (100/200) Daten-Bit 0 Complete (600/100) kennzeichnet das Ende einer Übertragung
Mein Code ist komplett in C geschrieben. Für die Übertragung habe ich zwei Bibliotheken verfasst, die das Timing enthalten und eine für die eigentliche Lichtsteuerung. Da ich einige Tage (und Nächte) an der eigentlichen Auswertung des Protokolls gesessen bin, möchte ich euch um Nachsehen bitten, wenn ich hier nicht den kompletten Quellcode veröffentlichen will. Für einzelne Ausschnitte könnt ihr mich trotzdem gerne anschreiben. Nur halt komplett preis geben möchte ich mein "Werk" nicht. Sollte für die Umsetzung von eurer Seite aber noch die wichtigste Information fehlen, einfach hier drunter kommentieren, da kann es dann auch jeder lesen der will.
Zu Prinzip und Codegrundlage sei vereinfacht gesagt: ich messe stets die Pulsweite, die am Empfängereingang anliegt. Dann checke ich, in welchem Bus-Status (Init, Data, Reinit, Complete) sich der Bus befindet. In einem Status kann nur eine bestimmte Pulsweite erlaubt sein. Befinde ich mich zB im Status Init, darf als nächstes nur die Pulsweite des Init-Pulses kommen. Ist dies der Fall, so muss regulär als nächstes ein Datenbit (0 oder 1) folgen. Ist dies nicht der Fall, wird das Lesen abgebrochen und bis zum nächsten Init gewartet. Natürlich sind Toleranzen +-50us möglich, falls Empfänger und Sender, die ja ohne externen Quarz auskommen, nicht 100%ig aufeinander abgestimmt sind.
Wichtig sind auch immer nur die High-Zeiten der Pulse, ich habe keinerlei Informationen in der Low-Zeit drin. Unterschiede bei High- und Low-Data dienen nur dem einfacheren Debugging am Oszilloskop.
Ausblick Derzeit ist ein weiterer Punkt in fortgeschrittener Planung und Umsetzung: die Übertragung von Servosignalen. Ich kann schon einen 16-Bit Wert übermitteln und korrekt auslesen. Bisweilen tüftle ich bnoch an der Auswertung eines weiteren PWM Kanals senderseitig und der Erzeugung des PWM-Signals empfängerseitig. Das benötigt noch etwas Zeit.
Das Wichtigste zum Schluss: ich möchte mich auf keinen Fall geheimnistuerisch verstecken. Ich finde, hier sind so viele schlaue und kreative Köpfe unterwegs, da entstehen mehr und mehr Ideen, von denen ich noch nicht gewagt habe, zu träumen. Also bloß nicht abhalten lassen, hier etwas zu ergänzen/korrigieren/verbessern.
Weitere Bilder werden nachgereicht, vor allem wenn ihr Wünsche habt.
Ach ja: Das Video muss noch gemacht werden, ich hoffe, ich komme in den nächsten zwei Tagen dazu.
danke für das Lob. Ich habe mal ein kurzes Video gemacht, in dem die groben Lichtfunktionen und die Empfangsunterbrechung zu sehen ist. Der Link dazu ist: https://youtu.be/LM8crpFgbhw
Die einzelnen Datenbits im ersten Datenbit haben eine feste Bedeutung. Alle weiteren Bytes sind je nach Wunsch definierbar. Aber vorne bleibt alles konstant:
Datenbit 0: 1 = Licht an; 0 = Licht aus
Datenbit 1: 1 = Blinker LED links an; 0 = Blinker LED links aus Datenbit 2: 1 = Blinker LED rechts an; 0 = Blinker LED rechts aus
Datenbit 4: 1 = Bremslicht LED an; 0 = Bremslicht LED aus Datenbit 5: 1 = Rückfahrlicht LED an; 0 = Rückfahrlicht LED aus
Datenbits 6 und 7: frei für Zusatzfunktionen
Bei weiteren Bytes wäre zum Beispiel denkbar, dass das zweite Byte eine Servoposition codiert (0 bis 255), oder Byte 2 und Byte 3 ein Servosignal (1000us bis 2000us).
wenn du das mit mindestens einem Servo noch hinbekommst, würde ich meinen neuen Tieflader damit ausstatten. Hier habe ich das Problem, dass sich der Schwanenhals vom Rest trennen soll und somit auf konventionelle Weise kein Licht installiert werden kann, ausser man installiert einen weiteren Empfänger.
da kann ich einfach nur sagen GENIAL !!! Ich hatte mir ja eigentlich etwas ähnliches in Bascom vorgenommen. Ich wollte lediglich einen einfach IR Sender und IR Empfänger bauen. Aber wenn ich mir dein Projekt anschaue mache ich mir ernsthaft Gedanken, ob ich das mit Bascom hinbekomme ...
Ich bin froh, dass ich einen eigenen Fahrtregler mit 3 fach wählbarer PWM Frequenz, Rückfahr- und Bremslicht hinbekommen habe.
@Klaus: Beim Servo bin ich nah dran. Krone wäre dann, auch langsame Bewegungen zu übertragen. Wäre cool, das System mal in einem Modell zu sehen, bei mir auf dem Tisch sieht das alles so steril aus
@Sven: Zunächst mal Danke, freut mich, wenn es gefällt Ja, in C ist es denke ich übersichtlicher, die Busauswertung und Lichtsteuerung in ein Programm zu packen, wobei das sicher auch möglich ist (habe 0 Erfahrungen mit Bascom)
Für Bascom gibt es einen recht einfachen Weg, den RC5 Code auszuwerten. Ich hatte mir schon mal überlegt, damit evtl. Versuche mit zu machen. Oder denkst du, das ist gleich zum Scheitern verurteilt ?
Das sind doch schonmal sehr gute Fortschritte! Warum verwendest du aber ein eigenes eigenes Übertragungsprotokoll? Hat dein Mikrokontroller keine serielle Schnittstelle oder gibt es andere Vorteile (interner Takt zu ungenau für UART?)? Meine Überlegung ist, die zu Übertragenden Daten einfach auf den UART/USART zu packen, und dann damit entweder eine IR-Diode zu füttern oder einen FET, der das Signal auf die Versorgungsspannung moduliert. Die Zeichenfolge für den UART wäre ein einfacher String von fester Länge (zB. 16 Zeichen) und würde etwa so aussehen:
Zeichenfolge zur Indentifizierung auf die der Empfänger bei einem Interrupt auf dem UART reagiert, zB. "HiDu", gefolgt von dem aktuellen Wert für den ersten Servokanals "255" ("000" wäre Vollausschlag der anderen Seite und "127" die Mitte), gefolgt von dem aktuellen Wert für den zweiten Servokanals "255" (dito erster Kanal), gefolgt von dem aktuellen Wert für externe Schaltfunktionen "255" (Wertetabelle für Kombination von verschiedenen Eingangssignalen, hier zB. alle 8 Eingänge -> 2^8 = 256 mögliche Kombinationen)
Der Übersicht halber alles duch Kommas getrennt (kann auch entfallen) ergibt das einen Kommandostring nach folgendem Muster:
"HiDu,255,255,255"
Je kürzer der String, desto höher die Wiederholrate. Die Zeit, die der Empfänger zur Auswertung und Ausgabe braucht muss natürlich berücksichtigt werden.
Das ist bisher alles nur Theorie ich habe bisher noch nicht versucht, den USART an einem ATMEGA ohne externen Quarz/Oszillator zu benutzen. Vielleicht funktioniert es aber bei niedrigen Baudraten (bis 4800Baud) ja zuverlässig.
Was hast du denn für einen µC vorgesehen? Auf den Fotos kann ich das nicht erkennen.
ich arbeite mit dem ATtiny84, der hat leider garkeine Schnittstellen außer SPI...
Größere Controller sind zwar möglich, brauchen halt auch Platz
RC5 kann auch funktionieren. Ich habe deshalb ein eigenes Protokoll gewählt, damit ich zwischen der "Eingabe" über die Fernsteuerung und die Ausgabe an die IR-LED möglichst wenig Zeit verliere. So umgehe ich fremde UART-Libs und kann natürlich am Ende sagen, dass ich unabhängig von irgendwelchen Urheberrechten bin.
Außerdem erlaubt mein Protokoll eine schnelle und effektive Fehlererkennung, die ich mit eingebaut habe.
Ups, in der Zeit wo ich getippt habe, ist ja schon einiges passiert. Bei nochmaligem Überlegen ist die Wertetabelle für 8 Eingänge schon quatsch, bei der geringen Anzahl kann man auch gleich eine Stelle im String für jeden Eingang verwenden...
Ach und nochwas: die Übertragung eines Bytes braucht circa 4ms. Da ich als Start der Übertragung immer das einkommende Servosignal vom Empfänger nutze, kann ich sehr gut 4 Bytes übertragen. Das reicht aus und ich brauche keine große Konvertierung von Byte in String und danach wieder String in Daten
Eine Zeichenkette als Erkennung wären dann auch wieder viele Bytes, die an sich ja unnötig sind. Ich sage jemandem ja auch nicht zwölf mal Hallo bevor ich auf den Punkt komme ;)
Da hat leider die Fräse meines Kumpels was dagegen ^^ für spätere Versionen sehr gerne, und wenn ich dann reich bin und mir die Platinen fertigen lassen kann :)
4ms pro Byte finde ich sehr gut, da sind selbst bei 4 Byte noch ca. 60 Wiederholungen pro Sekunde drin. Auf deinem Video habe ich ja gesehen, dass es bereits gut funktioniert. Da bin ich natürlich gern bereit, meine Theorie über den Haufen zu werfen und mich deiner anzuschließen. Aber den ATMEGA8 nehme ich trotzdem