Hallo!
Ich versuche derzeit mit meinem Arduino Duemilanove ein einfaches
"Standby" signal mit dem Phillips RC5 Protokoll zu senden. Bisher habe
ich das so einfach wie möglich gefasst:
Aber "JUMP" wird nie ausgegeben und die LED leuchtet auch nicht
wirklich. und wenn dann nur sehr schwach, wie ein funke neben der Sonne
wenn die LED direkt über eine Konstantstromquelle an eine Batterie
angeschlossen ist.
Kann es sein, dass der Prozessor damit einfach nicht fertig wird?
Mfg Xaser
Xaser schrieb:> if(nPosition > 28)
nPosition wird aber nie > 28, folglich wird dieser IF-Zweig nie
abgearbeitet.
Unbekannter schrieb:> Lern mal ne anständige programmiersprache wie Assembler oder C, dann> klappt das schon.> Arduino ist wie VBasic für den PC: lahm und ressourcenhungrig.
Häh? Noch nie nen Arduino benutzt, was?
Der wird nämlich in C bzw. wahlweise auch in C++ programmiert. Es werden
lediglich ein Paar Libs zur Vereinfachung mitgeliefert; aber niemand ist
gezwungen diese zu benutzen.
Und dazu sei gesagt, dass ich sowohl ASM als auch C - C++ behersche
Ich versuche mich schon lange von dem Arduino Editor zu trennen, leider
unterstützt der Code Composer aber noch keinen AVR compiler, und ich
will nur 1 IDE für Microcontroller benutzen müssen..
PS: ich glaube die Arduino sprache wird auch als Processing bezeichnet.
Lege mich da aber nicht fest.
Ich würde in loop() noch einen SendBit() aufruf einbauen.
Hinterher wird dir noch das Serial.println(nPosition) das gewünschte
500µs Timing verfälschen.
Thomas schrieb:> Mit einer Digicam sollte man die Diode deutlich sehen können.> Kostantstrom brauchst du nicht, einfach Widerstand + LED reicht.
Warum keine Konstantstromquelle verwenden, wenn man schon eine hat, für
die LED ist das am verträglichsten und man erzielt das beste Ergebnis
damit!
Adam schrieb:> volatile int nPosition = 14;
bringt auch nix
Vielleicht sollte ich mal erläutern warum ich denke das der Arduino
dafür zu schwach ist!
Ganz einfach: bei einer Interrupt Period von 889 Microsekunden geht
nPosition einfach immer weiter hoch
bei 8890 wird jump schon ausgeführt.
Ich schätze einfach mal, das das was in SendBit passiert länger als 889
Microsekunden dauert.
Mfg
Also wenn etwas zu schwach ist, dann höchstens deine
Programmierfähigkeiten. ;)
Zwei Dinge sind mir ins Auge gesprungen:
Erstens:
Xaser schrieb:> boolean bCommand[28] = { 0,1, 0,1, 1,0, 1,0, 1,0, 1,0, 1,0, 1,0, 1,0, 0,1, 0,1,
1,0, 1,0 };
Du hast nur 26 Werte, also wäre wohl bCommand[25] richtiger.
Zweitens:
Xaser schrieb:> Ich schätze einfach mal, das das was in SendBit passiert länger als 889> Microsekunden dauert.
Das ist sehr wahrscheinlich. Das ist aber nicht ein Problem des
Arduinos, sondern ist schlicht falsche Programmierung. Grundregel:
Interruptroutinen so kurz wie möglich halten. Die Serielle Schnittstelle
ist lahm, im Interrupt etwas über die Serielle auszugeben kostet zuviel
Zeit. Zum ohnehin schon recht lansamen RS232-Timing kommen noch die
Verluste der Seriell-USB-Wandlung dazu. Sowas macht man keinesfalls in
der Interruptroutine.
Xaser schrieb:> Tishima schrieb:>> Ich verstehe den Ardunio Code kaum, aber ich sehe nicht wo das Signal>> mit, ich glaube bei RC5 mit 38kHz moduliert wird.>> Es sind 36Khz
Das mag ja sein, aber trotzdem erzeugst du die nirgendwo.
Die '1' bei den vereinfachten Angaben für eine RC5-Übertragung bedeuten,
dass da ein 36kHz Träger ausgesendet wird und nicht einfach nur die IR
LED angeschaltet wird.
Klaus Boenicke schrieb:> Du hast nur 26 Werte, also wäre wohl bCommand[25] richtiger
2 Start Bits + 1 Toggle Bit + 5 Adress Bits + 6 Command Bits = 14
14 Bits * 2 Teile = 28
Habe lediglich in der Aufzählung eine 0 Vergessen, und solange ich das
Array nicht überfülle kanns auch 1024 Elemente haben, das macht keinen
Unterschied ;)
Klaus Boenicke schrieb:> Sowas macht man keinesfalls in> der Interruptroutine.
Hatte ich Ursprünglich auch nicht implementiert, erst als mir die Kamera
sagte, dass die LED nicht leuchtet. Kurz gesagt, auch ohne Serial
passiert nichts.
Es passiert nichts, weil du die 36 kHz Trägerfrequenz nicht erzeugst.
889 Mikrosekunden entspricht, wenn du im Timer die LED einfach nur
toggeln würdest, etwa 562 Hz. Darauf wird kein IR-Empfänger reagieren.
Dann kann es auch noch sein, dass die Stromquelle zu langsam
einschwingt. Für solche Frequenzen sollte man einfach Vorwiderstände
verwenden.
Das Erzeugen der Trägerfrequenz kann man beispielsweise mit einem PWM
Ausgang machen. In meiner Fernsteuerung mache ich das in Assembler auf
einem ATtiny11 direkt mit Warteschleifen zyklusgenau - das geht auch.
Grüße,
Peter
Das wars ja noch nicht einmal, die LED leuchtete überhaupt nicht, aber
das konnte ich mittlerweile berichtigen.
Peter Diener schrieb:> Das Erzeugen der Trägerfrequenz kann man beispielsweise mit einem PWM> Ausgang machen. In meiner Fernsteuerung mache ich das in Assembler auf> einem ATtiny11 direkt mit Warteschleifen zyklusgenau - das geht auch.
Der PWM des Arduinos arbeitet mit 500hz, definitiv zu wenig für mein
Vorhaben, auf 36KHz zu kommen. Kann ich den PWM denn irgendwie
einstellen?
Ich kann zwar ASM aber kenne mich mit den AMTEL Bausteinen absolut nicht
aus, deswegen greife ich auf den Standartweg zurück.
Xaser schrieb:> Ich kann zwar ASM aber kenne mich mit den AMTEL Bausteinen absolut nicht> aus, deswegen greife ich auf den Standartweg zurück.
"Stehende Arten" gibbet nicht.
Wenn ich was auf nem AVR einstellen will, gehe ich einfach ins
Datenblatt, z.T. Timer1, Register Description und dann klappere ich alle
Register durch, also setze die entsprechenden Bits darin. Fertig.
Ohne Datenblatt braucht man sich nicht zu wundern, daß man den Chip
nicht kennt und das nix geht.
Ansonsten verstehe ich bei den Arduino-Befehlen auch nur Bahnhof.
Kann man auf den Arduino nicht ganz normale C-Programme laden, also mit
main usw.?
Ne Stromquelle würde ich auch nicht nehmen, nicht jede Schaltung schafft
36kHz. Ich sehe auch nirgends die 36kHz Erzeugung.
Ich würde nen 72kHz Interrupt mit Pin-Toggle nehmen und darin die Bits
senden. Dann hat man keinen Jitter.
Bei 8MHz hat der Interrupt 111 Zyklen Zeit, das ist in C zu schaffen.
Alle anderen Interrupts müssen beim Senden gesperrt sein.
Peter
Ich weiß echt nicht, was an einer Konstantstromquelle auszusetzen ist:
http://www.mikrocontroller.net/articles/Konstantstromquelle
das Ding wird lediglich zwischen LED und + - geklemmt, damit die
Stromstärke für die LED optimal ist.
ich habe jetzt die ganze zeit gesucht und schon einiges rausgefunden:
Der ATMEGA328 hat 6 Pins die mit PWM verwendet werden können, jeweils 2
teilen sich einen Timer/Counter Register: TCCR0B, TCCR1B, und TCCR2B.
Die letzten 3 Bits des Registers sind der Vorteiler, damit kann ich also
für die Anschlüsse OC1A, OC1B, OC2A, OC2B (Pins 9, 10, 11 und 3) eine
32KHz Frequenz modulieren.
ich brauche aber 36KHZ. Dass wird in einem Beispiel so gemacht:
1
TCCR2A=_BV(WGM21)|_BV(COM2A0);
2
TCCR2B=_BV(CS20);
3
// 36kHz carrier/timer
4
OCR2A=(F_CPU/(36000L*2L)-1);
TCCR2B und OCR2A sind geklärt. F_CPU ist beim ATMega328 16MHz 36000 ist
die gewünschte Frequenz (36KHz) auch klar.
Bleibt über die -1, das L hinter den Werten (Long?) sowie TCCR2A und die
_BV werte.
Dazu habe ich schon gewühlt aber noch nix gefunden was mich überzeugt
hat.
Xaser schrieb:> Ich weiß echt nicht, was an einer Konstantstromquelle auszusetzen ist:
Welche der vielen Schaltungen denn?
Wie schon gesagt, sind Schaltungen nicht unendlich schnell, 36kHz ist
schon ne ordentliche Hausnummer.
Peter
Peter Dannegger schrieb:> Welche der vielen Schaltungen denn?>> Wie schon gesagt, sind Schaltungen nicht unendlich schnell, 36kHz ist> schon ne ordentliche Hausnummer.
Eine ziemlich einfache, 2 dioden, 2 Wiederstände und ein Transistor,
aber das tut nix zur sache, ich habe den Thread nicht zur Diskussion
über eine Konstantstromquelle eröffnet^^, mich würde vielmehr die
Bedeutung der oben stehenden Begriffe interessieren.
Mfg Xas
Peter Dannegger schrieb:> Ansonsten verstehe ich bei den Arduino-Befehlen auch nur Bahnhof.> Kann man auf den Arduino nicht ganz normale C-Programme laden, also mit> main usw.?
Klar kann man. Niemand wird dazu gezwungen die Arduino-Erweiterungen zu
benutzen. Steht alles in der Doku zum Arduino. Allerdings gibts wohl
immer Leute, die nichts von Doku-Lesen halten...
Oskar schrieb:> Mann, du gehörst echt zu den lernresistenten Typen.
Oh ja, solche Leute liebe ich, die durch Foren streifen nur auf der
Suche nach Threads wo sie einen Klugscheißerkommentar loslassen können.
Super.
Klar wer liebt denn nicht vollkommen unbegründete 2 Sekundenkommentare.
So wie ich das dem Datasheet entnehme hat WGM21 was mit dem Typ der
Wavegenerierung zu tun sehe ich das richtig?
Moment mal, Peter wollte Euch helfen - jetzt werft Ihr ihm vor, daß er
sich nicht durch die komplette Doku einer, vorsichtig gesagt, exotischen
Entwicklungsumgebung wühlt ?
Gruß, Marcus
Marcus Müller schrieb:> Moment mal, Peter wollte Euch helfen - jetzt werft Ihr ihm vor, daß er> sich nicht durch die komplette Doku einer, vorsichtig gesagt, exotischen> Entwicklungsumgebung wühlt ?
Habe ich nie getan, von ihm stammen 90% der helfenden Antworten in
diesem Thread. geärgert hat mich Oskar..
@Xaser: Ja, der Arduino ist dafür wirklich zu langsam!!
Und die einfache Konstantstromquelle ist schnell genug. Geht locker bis
1MHz oder mehr, lass Dir da nicht reinquatschen - übrigens völlig egal
welcher Transi da drin ist, das schaffen wirklich ALLE!!
Hoffe Dir geholfen zu haben indem ich das gesagt habe, was Du hören
wolltest!
Vielleicht kann man mit der Tone Library
http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation
36kHz erzeugen. Hab es nicht getestet, aber es sollte nichts dagegen
sprechen.
Ansonsten kann man ja einfach eine eigene Bibliothek schreiben oder
direkt auf die Hardware zugreifen.
Wenn es mein Projekt wäre, würde ich eine eigene Bibliothek schreiben,
die einen der freien Timer zur PWM-Erzeugung benutzt. Die laufende PWM
kann man einfach modulieren, in dem man die Pulsweite auf Null setzt
(richtige waveform generation (up-down-mode) wählen, damit keine Spikes
entstehen).
Das sollte bei doppelt gepufferten Compareregistern (wie z.B. beim Timer
1) sogar richtig gut zu synchronisieren sein.
Die Modulation sollte dann entsprechend über den Overflowinterrupt des
verwendeten Timers aufsynchronisiert werden.
Alternativ schätze ich, dass die "halb-software-PWM" (Vorschlag von
Peter Dannegger) mit dem Toggeln des Pins im Interrupt genauso gut
funktioniert. Das ist einfacher umzusetzen, dafür wird etwas mehr
Rechenleistung verbraucht.
Grüße,
Peter
Moin,
ein neues Bit kommt bei RC5 ja grad mal alle 1,778ms. Da jetzt jeden
Toggle der IR-LED in nem IRQ zu machen ist mit kanonen auf spatzen.
Würde da eher den Wave Generator Mode des TImers nutzen, der toggled
dann selbsttätig den ausgangspin und setzt den timer zurück - so kommt
man dann zu den 36kHz, das passiert dabei alles im hintergrund in
hardware.
Im original passiert ein umtasten alle 32 Perioden von 36kHz, da das
aber eh immer von einem empfänger demoduliert wird bevors ausgewertet
wird, muss man sich da jetzt keinen allzugroßen kopp machen, weil dass
dann evtl nicht ganz stimmt vom timing her.
Den wave generator kann man ohne den timer zu stoppen vom pin
trennen/damit verbinden. damit erzeugt man das nutzsignal
(manchestercode für das RC5)
Also:
1) WGM nutzen für die 36kHz
2) mit Timer oder Delayloop alle 889µs den ausgang des WGM umschalten
gemäß manchester
3) glücklich sein, dass das plötzlich alles geht
Also vielen Dank für die vielen Beiträge (damit meine ich die nützlichen
hust), aber ich denke ich habs jetzt durchschaut:
Ich habe mir diesen Codeschnitzel den ich gefunden hatte vorgenommen und
dann mithilfe des Datasheets des ATMega328 entschlüsselt.
1
TCCR2A=_BV(WGM21)|_BV(COM2A0);
2
TCCR2B=_BV(CS20);
3
// 36kHz carrier/timer
4
OCR2A=(F_CPU/(36000L*2L)-1);
TCCR2A (Timer2 Counter Controll Register A?) wird neu beschrieben und
dazu muss man wissen, dass _BV ein define für (1 << x) ist. WGM21 und
COM2A0 sind dementsprechend Bits im Register.
Beide gesetzt heißt das soviel wie:
Toggle OC2A on Compare Match im Non-PWM Mode.
OC2A ist klar, Pin 11 des Arduino.
OCR2A (Output2 Control Register A?) beinhaltet dementsprechend den Wert
der andauernd verglichen wird, in unserem Fall ein Wert der so gesetzt
ist, dass er 72000x in der Sekunde zutrifft, also 36000 pro sekunde geht
die LED ein und aus.
Wie ich das jetzt noch ein und ausschalte ist ja relativ klar, einfach
andere Bits in TCCR2A setzen. Verbunden mit dem Timer1 der sich alle
889mikrosekunden meldet wird das schon klappen hoffe ich
Hallo,
ich verstehe auch nicht viel vom Arduino aber erstens warum sind da nur
26bits wenn Dein Array mit [28] definiert ist?
Dann wo schaltest Du die LED ein und aus? Im ersten Code sehe ich nur
LOW?
Der andere Kollege hat Recht wie kann es sein das man ohne Modulation
der 36kHz mit dem PWM Register und keinem Zeitlichen Abstand überhaupt
einen RC5 auftasten kann?
Das es funktioniert solltest Du die Startflanke der RC5 Pakete immer am
gleichen Zeitpunkt haben.
Ein Timer der den Raster des Starts vorgibt mit 1,8ms OVF (overflow und
timerint). Die PWM im Synchronmode mit 36kHz für die Bursts und wenn
mich nicht alles täuscht hat der RC5 auch unterschiedlich lange Pakete.
(das ist leider schon fast 20 Jahre her da haben wir einmal etwas für
S**y mit RC5 gemacht - die wollten sich zu diesem Zeitpunkt am Phi***s
immer mehr anpassen)
Interrupt Vektor:
12 0x0016 TIMER1 COMPA Timer /Counter1 Compare Match A
13 0x0018 TIMER1 COMPB Timer /Coutner1 Compare Match B
14 0x001A TIMER1 OVF Timer /Counter1 Overflow
Seite 65 im Datasheet
PWM - Output Compare Match:
OC0A
Seite 89 PortD.6
ist hier als Ausgang vorgesehen.
Seite 94 - 8bit PWM ebenfalls durchlesen hier wird erklärt das es 2
Compare Match Register gibt.
Ach ja noch etwas ich glaube Niemanden der sagt er kenne sich mit C++
aus!
In den meisten Fällen ist es so das der Compiler auch C++ compilieren
kann aber ich habe die letzten 30Jahre lediglich 3 Leute kennen gelernt
die Bjarne Strostrup richtig schreiben können.
MfG
weakbit
Ich denke, daß Xaser das Problem innerhalb der letzten dreieinhalb
Jahre gelöst hat.
(und das ist ein Zeitraum in dem man C++ lernen könnte ohne Strostrup zu
schreiben)