Hallo liebe Comiunnity ich habe es nach langem hin und her geschafft das
RC5-Protokoll zu implementieren. Daher bin ich sehr stolz auf mich, da
meiner programmier erfahrungen rudimentär sind.
Ich bin zurzeit mit der Entwicklung von Schwarmrobotern beschäftigt. 20
sind es bisher, vielecht kommen noch mehr dazu, ist aber eine
Kostenfrage.
Diese sollten über eine simple Schnittstelle untereinander kommunizieren
können und natürlich auch über eine Fernbedienung angesprochen und
gesteuert werden. In meinem Fall ist es über IR mittels RC5-Protokoll.
(Ich weiss man könnte für diese paar wenigen befehle auch eine ganz
simples Protokoll realisieren. Aber ich möchte programmier Erfahrungen
sammeln und dazu habe ich eben das RC5-Protokoll auserwählt da es simpel
und im Netz gut dokumentiert ist.)
Demnach habe ich mir gedacht, dass, ich es mir zur Aufgabe mache, das
RC5-Protokoll zu implementieren. Da es für mich eine große
Herausforderung ist habe ich mich sehr intensiv mit der Materie
auseinandergesetzt daher auch oft herausgefunden, wie es nicht geht. :-)
Somit komme ich zu meinem Schaltungsaufbau.
Ich habe eine Roboter Leiterplatte entworfen und herstellen lassen.
Darauf sind verschiedenste Bauteile angebracht sind aber für diesen
Fall, nicht alle relevant,sofern beschränke ich mich hier auf das
wesentliche.
Atmel Studio 6 (Version: 6.2.1153)
Als Prozessor verwende ich den ATmega328p von Atmel der mit 3V / 8 MHz
gespeist wird.
Die Leiterplatten sind jeweils mit einer Ir LED und einem Ir Empfänger
(TSOP 34836) ausgestattet.
Zu Testzwecken sende ich nacheinander verschiedene RC5 Frames um die RGB
LED auf der Leiterplatte anzusteuern.
Also habe ich mit der Implementierung des Senders angefangen und nach
langen Recherchen ist es mir gelungen das Signal zu generieren und
auszugeben. Habe danach auch mit einem Oszilloskop das Ausgangssignal
betrachtet und sehe da, es läuft(zugegeben mit ein paar Macken zu
Anfang). Mein Programm generiert zuerst den binären RC5-Code danach
werden die bits mit 36 kHz Aufmodulation und mittels Manchestercode per
IR LED übertragen.
Die Codierung des Signals erwies sich wesentlich einfacher als die
Decodierung. Wusste Eifach nicht wie anfangen. Wusste ungefähr in
welcher Richtung konnte aber keinen Ansatz finden. Aber wer gewillt ist
gibt nicht auf. Per zufall und das ist auch meine Rettung, habe ich eine
gutes Skript zur RC5 Implementierung gefunden. Diese ist für ein
Arm-Prozessor gedacht aber man kann es genauso gut auch auf ein
avr-Prozessor portieren.
(RC5 Dokument)
Das habe ich nun gemacht (bzw. versucht) nach dem ersten Versuch habe
ich relativ schnell gemerkt das ich an der falschen Stelle im Skript
gelesen habe und daher ein völlig falsche Implementierung zustande kam.
Danach habe ich die für mich relevante Stelle im Skript lokalisiert und
Draufan mit dem programmieren losgelegt. Meiner Meinung nach sich ein
paar Details nicht so wie es sein sollte.. bin aber auch kein Experte in
der Sache.
Da ich das Mainboard des Roboter selbst entwickelt habe und auf diesem
keine Schnittstelle zur Datenübertragung auf den Computer realisier ist,
ist es sehr schwierig die Variablenwerte auszugeben und zu überprüfen.
Ich möchten euch jetzt eigentlich fragen was ihr zu meiner Arbeit denkt?
Natürlich auch ob ihr mir bei den einen oder anderen dingen auf die
Sprünge helfen könntet den ich stehe zurzeit ziemlich auf dem Schlauch.
In der angehängten Datei sind alle meine Daten zu finden.
In meinen Codes ist in den Kommentaren gut beschrieben, was da gerade
gemacht wird und wieso.
Mein erstes Problemchen:
Beim Code des Senders ist eigentlich meiner Meinung nach alles
gut(zumindest läuft es). Nur die compare match Frequenz stimmt irgendwie
nicht ganz die, sollte ca. 36kHz sein.
OCR0A = (Fclk / (2 1 Focr)) - 1 = ~110
den somit vergehen x(TIMER0_COMPA_vect) um ein halbes bit zu übertragen.
x = (889 us / (1/36000kHz)) * 2 = ~64
oder liege ich da falsch?
Aber irgendwie ist die Dauer eines halben bits länger als 899 us so um
die 1 ms laut Oszilloskop. Siehe bild (fieldbit 0 zoom)
Ich weis nicht, woher das kommt. Sieht vielleicht jemand von euch etwas?
Zu meinem zweiten Problemchen:
da die halb bit zeit in der Toleranz zeit des Empfängers ist geht auch
das entfangen so halbe. Aber nur beim ersten empfangen und danach stimmt
alles irgendwie nicht mehr und hier komme ich auch nicht wirklich weiter
den ich denke das ich die nötige Variablen zurückgesetzt habe um das
nächste Signal auszulesen das geht aber nicht.
Schlussendlich will ich eine Simplex Datenübertragung realisieren.mit
der dann die einzelnen Roboter untereinander Komunizieren können.
Ich habe mir bereits einige Gedanken gemacht, wie die Kommunikation
ablaufen sollte. Dies ist aber im Moment noch nicht allzu wichtig.
Fabio schrieb:> Beim Code des Senders ist eigentlich meiner Meinung nach alles> gut(zumindest läuft es). Nur die compare match Frequenz stimmt irgendwie> nicht ganz die, sollte ca. 36kHz sein.> OCR0A = (Fclk / (2 1 Focr)) - 1 = ~110> den somit vergehen x(TIMER0_COMPA_vect) um ein halbes bit zu übertragen.> x = (889 us / (1/36000kHz)) * 2 = ~64> oder liege ich da falsch?
Und ich kann in deinem Code weder Timer0 noch OCR0A finden.
Oder liege ich da falsch ?
Marc Vesely schrieb:
> Und ich kann in deinem Code weder Timer0 noch OCR0A finden.> Oder liege ich da falsch ?
Das hast du richtig bemerkt, und ich danke dir für deinen Hinweis.
Ich habe versehentlich in beiden Code Dateien den gleichen Code rein
kopiert.
Daher Entschuldige ich mich für die Verwirrung.
Hiermit reiche ich die richtigen Dateien nach. :-)
Ich danke euch allen vielmals für eure mühe und hoffe das wir gemeinsam
eine Lösung finden. ;-)
Freundliche Grüsse
Fabio
Sorry wenn ich nicht direkt auf die Frage eingehen kann, aber mir fallen
da ein paar Dinge auf, die mir unter den Nägeln brennen und auf die ich
dich hinweisen möchte (Am besten ohne große diskussion, dass der Thread
nicht verspamt wird, aber das liegt nicht ganz in meinen Händen). Ist
nix schlimmes, aber punkten an denen Man nochmal Google anschmeißen kann
und was lernen wird...
"const volatile uint16_t" interessant. du weißt was du da machst?
"#define nop() \ asm volatile ("nop")" '\' sagt dem Präprozessor, dass
der Befehl hier noch nicht am Ende ist und ggf. in der nächsten Zeile
weiter geht... Also mal ganz salopp beschrieben
Bei deinem Timing-Problem würde ich mal messen was der Quarz macht
(Frequenz) oder einfach mal versuchen eine 50% PWM mit 36kHz Takt
auszugeben. Da findet sich dann bestimmt irgendwo ein Fehler. Vielleicht
sind ja auch die Fuses falsch gesetzt und der läuft auf dem internen
RC-Oszillator. Sollte zwar eigentlich nicht so viel ausmachen aber man
weiß ja nie.
Alle Angaben ohne Gewähr, auch ich kann mich irren.
PS:
Was mir gerade so ganz am Rande auffällt: Versuchst du da einen
Interrupt alle 111 Prozessortakte auszuführen? ich glaube schon.
Ich habe zwar schon einen Interrupt in ~28 Taktzyklen durchlaufen
lassen, aber der musste dann - soweit ich mich gerade erinnere - auch
nicht viel mehr tun als einen uint16 zu inkrementieren. Und selbst da
habe ich dann mit assembler-code aufs Letzte optimieren müssen. Ist aber
schon lange her und war auf einem ATtiny13 glaube ich. Egal.
Jedenfalls wird mit den zig volatiles der Interrupt eher einige hundert
bis gut in die 1000 Zyklen rattern. Mit anderen Worten wir der arme µC
sich selbst in die Fersen treten und was das dann für Folgen hat kannst
du ja mal versuchen dir vorzustellen.
Er explodiert nicht (wie du siehst) aber nachvollziehbar wird das
Verhalten nicht mehr sein.
Fabio schrieb:> Demnach habe ich mir gedacht, dass, ich es mir zur Aufgabe mache, das> RC5-Protokoll zu implementieren. Da es für mich eine große> Herausforderung ist habe ich mich sehr intensiv mit der Materie> auseinandergesetzt daher auch oft herausgefunden, wie es nicht geht. :-)
IRMP [1] bzw. IRSND kennst du aber ;)? Selbst wenn du dich dazu
entscheiden solltest es selbst zu implementieren, um dabei etwas zu
lernen, kannst du ja mal einen Blick in die Quellen [2] werfen, um
aufkommende Fragen selbst beantworten zu können. Frank, der Autor von
o.g. Projekten, hilft dir bei Detailfragen zur Implementieren bzw. zu
den Protokollen an sich bestimmt auch gerne weiter. Dafür am Besten hier
[3] melden.
Mit freundlichen Grüßen,
Karol Babioch
[1]: https://www.mikrocontroller.net/articles/IRMP
[2]: https://www.mikrocontroller.net/svnbrowser/irmp/
[3]:
Beitrag "IRMP - Infrared Multi Protocol Decoder"
Leo B. schrieb:
> "const volatile uint16_t" interessant. du weißt was du da machst?
Ich nehme an das es nicht richtig initialisiert wird. Wenn du das so
fragst. :)
const: definier variable als constante und kann im weiteren Programm
verlauf nicht verändert werden.
volatile: der Compiler darf an dieser variable keine Optimierungen
Durchführen.
> "#define nop() \ asm volatile ("nop")" '\' sagt dem Präprozessor, dass> der Befehl hier noch nicht am Ende ist und ggf. in der nächsten Zeile> weiter geht... Also mal ganz salopp beschrieben
Ja ich weiss ging aber anfangs nicht daher hatte ich es danach so
definiert.
Schlussendlich wird die nop() Methode gar nicht verwendet sonder direkt
asm volatile ("nop");
Habe diese Zeile jetzt mal auskommentiert, da sie nicht verwendet wird.
Mir ist schon klar das in den ISR´s eigentlich zuviel durchgeführt wird.
Und daher der Prozessor nicht mehr nachkommt da die ISR Frequenz kürzer
ist, als das der Code dadrin abgearbeitet werden kann.
Karol Babioch schrieb:
> IRMP [1] bzw. IRSND kennst du aber ;)? Selbst wenn du dich dazu> entscheiden solltest es selbst zu implementieren, um dabei etwas zu> lernen, kannst du ja mal einen Blick in die Quellen [2] werfen, um> aufkommende Fragen selbst beantworten zu können. Frank, der Autor von> o.g. Projekten, hilft dir bei Detailfragen zur Implementieren bzw. zu> den Protokollen an sich bestimmt auch gerne weiter. Dafür am Besten hier> [3] melden.
Natürlich habe ich auch dort schon einen blick rein geworfen. Wollte es
aber mal selbst probieren. Da ich bei solchen lib´s mich zuerst sehr
intensiv damit beschäftigen muss bevor ich überhaupt verstehe das da
genau abgeht.
Aber ich werde es nun dennoch mal probieren um zu sehen ob der Code des
Senders soweit in Ordnung ist.