Hallo,
ich möchte eine RGB Led mit einem Atmega8 von meinem PC aus steuern.
Die Led hängt an den 3 PWM Pins des Atmega8.
Die Ansteuerung übernimmt ein Python Programm.
Das Python Programm zeigt eine Farbpalette und übermittelt via serielle
Schnittstelle die RGB Daten an den Controller.
Die RGB Daten werden in Form von Hexadezimalzahlen (z.B. "FFE0F3")
verschickt.
Die RGB Daten werden in R, G und B aufgesplittet und dann in einen
Zahlenwert umgerechnet und den PWM Pins zugewiesen.
Bei "FFFFFF" würde dann Rot, Grün und Blau mit voller Leistung leuchten,
da FF umgerechnet 255 darstellen.
Leider weiss ich gerade nicht mehr weiter.
Vielleicht seht ihr ja den Fehler oder kann mir eine andere Lösung
vorschlagen.
Der Code befindet sich im Anhang.
Die Led blinkt sogar für einen sehr kurzen Moment auf (aber nur eine
Farbe), aber geht dann sofort wieder aus.
Gruss, Tymm
@Michael Wilhelm wo?
Du meinst in den Registern OCR1A, OCR1B und OCR2?
strtol liefert long int zurück.
Ich weiss jetzt nicht ob das ein Problem ist und wenn ja wie man es
löst.
Gruss, Tymm
@OP:
Werd' mal das '#include "uart.c"' los, das macht man nicht! (die
.c-Dateien werden im Makefile/im AVR-Studio-Projekt eingetragen).
Bist du sicher, dass dein string vom PC mit "\n"-endet (Unter Windows
wäre das eher "\r\n") ? (Als ersten Ansatz, mach mal "char Line[7]" zu
"char Line[10]").
hth. Jörg
ps. Deine Timereinstellungen hab ich mir noch garnicht angeschaut
@Jörg X. :
Ich benutze ausschließlich Linux. Von daher kein AVR Studio und Strings
die ganz sicher mit \n enden (echo "FFFFFF" > /dev/ttyUSB0).
Danke für den Tipp mit den Makefiles.
Aber wieso Line[10]? Ich habe doch nur 7 Zeichen: "FFFFFF" (6 Zeichen)
und ein "\0" (1 Zeichen).
Gruss, Tymm
>Ich benutze ausschließlich Linux.
hättest du evtl. andeuten können ...
Aber wie schon _Stefan Ernst (sternst)_ schrieb:
>> Überprüfe mal deine Timer-Konfiguration.
Die muss nämlich so (bzw. so ähnlich) aussehen:
1
// Timer1 init
2
TCCR1A=(1<<WGM10)|(1<<COM1A1)|(1<<COM1B1);
3
TCCR1B=(1<<CS10);
4
5
// Timer2 init for PWM on Pin PB3
6
7
TCCR2=(1<<WGM20)|(1<<CS20)|(1<<COM21);
Du brauchst zwar für eine LED nicht unbedingt drei Hardware
PWM-Einheiten, aber das kannst du ja später noch ändern ;)
rtfm, Jörg
>> Überprüfe mal deine Timer-Konfiguration.
Danke, das eine |(1<<CS10) war zuviel.
Allerdings funktioniert PWM auch mit dem |(1<<CS10) zuviel.
Am PWM liegt es leider nicht...
Funktioniert die serielle Kommunikation denn überhaupt?
Mach doch mal ein "echo" in das Programm, und schaue, was auf dem PC so
zurückkommt. Also z.B. ein "uart_puts(Line);" nach dem uart_gets.
Die serielle Kommunikation funktioniert, allerdings nicht wirklich gut
wie ich gerade festgestellt habe.
Komischerweise kommen bei einem 'echo -n "Hallo" > /dev/ttyUSB0' die
"Hallo"s häufiger vollständig zurück als bei einem 'echo "Hallo" >
/dev/ttyUSB0'.
(echo -n gibt kein \n am Ende aus, echo ohne option schon)
In einem Terminal gibt es auch häufiger Aussetzer.
Am Atmega8 hängt ein 8Mhz Quarz und die Fuse Bits habe ich bei Low auf
0xEE und bei High auf 0xD9.
Trotzdem glaube ich dass es nicht am UART liegt, weil irgendwann ja
immer mal was ganz durchkommt.
In einem anderen Programm steuere ich die Led mit einzelnen Buchstaben
('R' = Rot wird heller, 'r' = Rot wird dunkler usw.) und das
funktioniert tadellos.
Langsam verzweifel ich...
Es geht!
Es gab zwei Probleme:
1. Das Problem mit dem kurzen Aufleuchten habe ich gelöst indem ich
bevor ich die empfangenen Daten verarbeite, abfrage ob es sich um
hexadezimal Ziffern handelt (UART_NO_DATA funktionierte bei mir nicht).
2. Nachdem ich hinter das uart_gets per Zufall ein paar Befehle
geschrieben hatte, wurde das UART aufeinmal stabiler.
Ich habe jetzt ein paar delays hinter dem uart_gets und vor der
Verarbeitung der ankommenden Daten und es geht.
Ein Problem bleibt aber:
Wenn ich sehr schnell viele Farbcodes an den Atmega schicke, wird das
UART anscheinend wieder instabiler und falsche Farben werden erzeugt.
Im Anhang befindet sich der funktionierende Code + Python Programm zur
Ansteuerung.
Gruss, Tymm
@ tymm (Gast)
>2. Nachdem ich hinter das uart_gets per Zufall ein paar Befehle>geschrieben hatte, wurde das UART aufeinmal stabiler.>Ich habe jetzt ein paar delays hinter dem uart_gets und vor der>Verarbeitung der ankommenden Daten und es geht.
AUA!
>Ein Problem bleibt aber:>Wenn ich sehr schnell viele Farbcodes an den Atmega schicke, wird das>UART anscheinend wieder instabiler und falsche Farben werden erzeugt.
Und das wundert dich?
Du bremmst deinen AVR TIERISCH aus, der muss nach jedem empfangenen
String 5s! warten, ehe er wieder was machen darf. Da läuft garantiert
ein Empfangsbuffer über. Solche delays sind totaler Mist.
MfG
Falk
>Du bremmst deinen AVR TIERISCH aus, der muss nach jedem empfangenen>String 5s! warten, ehe er wieder was machen darf. Da läuft garantiert>ein Empfangsbuffer über. Solche delays sind totaler Mist.
Ein _delay_ms(1000) sind bei mir lange keine Sekunde, was wohl an
falschen Einstellungen meinerseits liegt.
Kann auch sein das delays totaler Mist sind.
Ich bin Anfänger, ich habe keine Ahnung.
Ich weiss nur, dass ohne delays oder irgendetwas anderes was Zeit in
Anspruch nimmt garnichts geht.
>Und das wundert dich?
Trotz der Gefahr noch ein "AUA!" zu kassieren und der Tatsache dass mein
AVR keine 5s wartet: Mich wundert es schon ein bisschen.
Ich dachte Peter Fleury's UART Lib arbeitet mit Interrupts.
Und wenn ich das richtig verstanden habe, unterbrechen Interrupts das
Hauptprogramm?
Gruss, Tymm
auch nur mal halbe Zeilen abholen könntest?
Die Funktion holt ab, was gerade im Puffer ist. Da wird nicht bis zum
CR/LF gewartet. Und du machst keinerlei Plausibilitätsprüfungen, ob
überhaupt ein ganzer String für deine Line[] gekommen ist.
Kein Wunder, dass längeres Warten dir da etwas hilft.
In der Tat. Ich war davon ausgegangen, dass uart_getc so lange wartet,
bis auch tatsächlich ein Zeichen empfangen wurde. Ich habe mal einen
Blick in die Dokumentation der Peter-Fleury-Uart-Lib geworfen, und dem
ist nicht so.
@ tymm:
Du musst also deine uart_gets ändern. Z.B. uart_getc immer in einer
Schleife so lange aufrufen, bis kein UART_NO_DATA mehr zurückkommt.
Ja, da scheint mir die Implementierung von uart_gets() die möglichen
Rückgabewerte von uart_getc() noch nicht richtig abzufangen:
Returns:
lower byte: received byte from ringbuffer
higher byte: last receive status
* 0 successfully received data from UART
* UART_NO_DATA
no receive data available
* UART_BUFFER_OVERFLOW
Receive ringbuffer overflow. We are not reading the receive buffer
fast enough, one or more received character have been dropped
* UART_OVERRUN_ERROR
Overrun condition by UART. A character already present in the
UART UDR register was not read by the interrupt handler before
the next character arrived, one or more received characters have
been dropped.
* UART_FRAME_ERROR
Framing Error by UART
Aus:
http://homepage.hispeed.ch/peterfleury/group__pfleury__uart.html