Hallo Community,
Ich habe da mal ne Frage, und zwar habe ich ein IR-Transistor auf ein
Breadboard gesteckt und habe mir das Beispiel aus dem Tutorial IRMP
angeschaut. Wenn ich nun mit meiner Fernseher Fernbedienung(Toshiba) zum
Sensor halte, und dann z.b Die 1 auf der Fernbedienung drücke. Kommt in
USART diese Zeile an:
Protocol: 7 | Address: 1 | Command: 1 | Flags: 0
und ganz kurz danach, nicht mal ne halbe Sekunde kommt dieses Zeile:
Protocol: 7 | Address: 1 | Command: 1 | Flags: 1
Der gleiche Befehl nur mit Flag 1. Soweit ich weis wird mit Flag
signalisiert das jetzt ein Befehl ausgeführt wird zb. Lautstärke leiser
stellen. Ohne das ich jetzt von 100 % auf 50 % Lautstärke 50 die Taste
drücken muss. Sondern das er automatisch runterzählt.
Wisst ihr woran das liegt das dieses beiden Zeilen mir zurück geben
werden?
Mfg Felix.
Felix N. schrieb:> Wisst ihr woran das liegt das dieses beiden Zeilen mir zurück geben> werden?
Das Flag bedeutet, daß die Taste festgehalten und nicht erneut gedrückt
wurde. Und die Fernbedienung sendet halt ein Statusupdate 'Taste 1 wird
immernoch gedrückt'.
Funktioniert wie es soll.
Guest schrieb:> Das Flag bedeutet, daß die Taste festgehalten und nicht erneut gedrückt> wurde. Und die Fernbedienung sendet halt ein Statusupdate 'Taste 1 wird> immernoch gedrückt'.> Funktioniert wie es soll.
Hallo,
Danke.
Hätte da nochmal ne andere Frage, und zwar baue ich mir auch selber eine
Fernbedienung mit dem IRSND.
Ich habe mir diesen Artikel durchgelesen und ausprobiert:
https://www.mikrocontroller.net/articles/IRSND
Meine LED ist genauso angeschlossen wie in der Zeichnung auf dem Artikel
dargestellt. Meine IR-LED ist eine TSAL6200. Und ich nutze denn BC547B
anstatt denn BC337. Sonst sind alles gleich.
Wenn ich nun auf dem NEC Protokoll mit der Adresse 1 und Command 1
sende. Und meine Kamera vom Handy über der LED halte kann ich sehen das
sie blinkt. Jedoch gibt mir der IR-Transistor nix im USART aus.
Die LED ist am OC2B angeschlossen. Ich habe mein Sender Code mal
angehängt.
Mfg Felix.
Felix N. schrieb:> Jedoch gibt mir der IR-Transistor nix im USART aus.
Du meinst der TSOP (das ist kein Transistor, sondern eine komplette
integrierte Schaltung!) empfängt nichts?
Du hast also einmal einen µC mit IRMP laufen und einen zweiten mit
IRSND? Läuft der µC mit IRSND tatsächlich mit einem Takt von 16MHz, so
wie Du es im Quellcode angegeben hast? Wenn nicht, dann klappt das
nämlich nicht.
Um den µC mit 16MHz zu nutzen, brauchst Du nicht nur den entsprechenden
Quarz, sondern musst auch die entsprechenden Fuse-Bits im µC setzen.
Hast Du das gemacht? Wenn ja, mit welchen Fuse-Werten?
Skizziere mal bitte Deinen Aufbau - am besten auch mit Bildern.
P.S.
Zu Deiner Frage mit flag = 1: Das ist so, wie oben erklärt wurde. Steht
auch im Artikel. Bei längeren Tastendrücken sendet die Fernbedienung
Wiederholungen aus. Die sind mit flag = 1 markiert. Wenn Du nur neue
Tastendrücke auswerten willst, dann ignoriere einfach die Frames mit
gesetztem Flag. Das ist auch so im Artikel unter "Entprellen von Tasten"
erklärt.
Frank M. schrieb:> Du meinst der TSOP (das ist kein Transistor, sondern eine komplette> integrierte Schaltung!) empfängt nichts?>> Du hast also einmal einen µC mit IRMP laufen und einen zweiten mit> IRSND? Läuft der µC mit IRSND tatsächlich mit einem Takt von 16MHz, so> wie Du es im Quellcode angegeben hast? Wenn nicht, dann klappt das> nämlich nicht.>> Um den µC mit 16MHz zu nutzen, brauchst Du nicht nur den entsprechenden> Quarz, sondern musst auch die entsprechenden Fuse-Bits im µC setzen.> Hast Du das gemacht? Wenn ja, mit welchen Fuse-Werten?>> Skizziere mal bitte Deinen Aufbau - am besten auch mit Bildern.>> P.S.> Zu Deiner Frage mit flag = 1: Das ist so, wie oben erklärt wurde. Steht> auch im Artikel. Bei längeren Tastendrücken sendet die Fernbedienung> Wiederholungen aus. Die sind mit flag = 1 markiert. Wenn Du nur neue> Tastendrücke auswerten willst, dann ignoriere einfach die Frames mit> gesetztem Flag. Das ist auch so im Artikel unter "Entprellen von Tasten"> erklärt.
Hallo Frank. M
Ich habe denn Fehler bereits gefunden. Nachdem ich die F_CPU Variable in
die Properties des Projektes(Project -> Properties -> ToolChain ->
AVR/GNU C Compiler -> Symbols -> Defined symboles(-D) -> ADD ->
F_CPU....) geschrieben hatte, funktionierte IRSND sofort. Ich denke mal
das in denn ganzen anderen Sourcecode Klassen die F_CPU mit ein anderen
Wert mehrmals überschrieben wurde.
Zu denn FuseBits kann ich dir leider nichts sagen. Da ich denn Arduino
Bootloader auf dem Atmega328p werde. Und dieses haben vom Haushaus 16
Mhz. Es seiden man installiert ein anderen Bootloader. Was bei mir aber
nicht der Fall ist.
Zur Fernbedienung, ich habe diese nur als Test genommen um denn
IR-Empfänger zu testen. Dabei kam mir das mit dem Flag 1 und Flag 0
komisch vor. Mittlerweile habe ich eine provisorische Fernbedienung auf
ein Breadboard. Mit 2 IR LED die auch funktioniert.
Hallo Felix,
Felix N. schrieb:> Ich habe denn Fehler bereits gefunden. Nachdem ich die F_CPU Variable in> die Properties des Projektes(Project -> Properties -> ToolChain ->> AVR/GNU C Compiler -> Symbols -> Defined symboles(-D) -> ADD ->> F_CPU....) geschrieben hatte, funktionierte IRSND sofort. Ich denke mal> das in denn ganzen anderen Sourcecode Klassen die F_CPU mit ein anderen> Wert mehrmals überschrieben wurde.
Ja, das IRSND-Modul wird mit F_CPU in den Projekteigenschaften
übersetzt. Deine Korrektur war also genau der richtige Weg. Du solltest
dann aber in letzter Konsequenz Dein "#define F_CPU" auch noch aus
Deinem main.c rauswerfen. Dann wird alles einheitlich übersetzt und es
kann auch in Zukunft keine Widersprüche auftauchen.
> Zu denn FuseBits kann ich dir leider nichts sagen. Da ich denn Arduino> Bootloader auf dem Atmega328p werde.
Wenn es ein Arduino-Board ist, brauchst Du keine Fuse-Bits mehr
anzupassen. Diese Information fehlte in Deinem Eröffnungsbeitrag. Die
auf den Arduino-Boards bedindlichen ATmegas werden in der Regel bereits
mit den zum Quarz-Betrieb passenden Fuse-Bits ausgeliefert.
> Zur Fernbedienung, ich habe diese nur als Test genommen um denn> IR-Empfänger zu testen.
Ist mir schon klar. Du willst schließlich mit IRSND -> IRMP Daten
übertragen - das habe ich aus dem Parallelthread
Beitrag "Infrarot Übertragung mit ATMega."
zufällig mitbekommen.
> Dabei kam mir das mit dem Flag 1 und Flag 0 komisch vor.
Der Fall ist im Artikel IRMP dokumentiert. Bei Deiner
Datenübertragung ist dieser dann irrelevant.
> Mittlerweile habe ich eine provisorische Fernbedienung auf> ein Breadboard. Mit 2 IR LED die auch funktioniert.
Gratuliere :-)
Es wäre nett, wenn Du uns hier über Dein Projekt auf dem Laufenden
hältst.
Frank M. schrieb:> Gratuliere :-)>> Es wäre nett, wenn Du uns hier über Dein Projekt auf dem Laufenden> hältst.
Hi Frank M.
Ja danke. Ich habe mir dein Artikel mehrmals durchgelesen. Mich hat am
meisten nur verwirrt das der IRSND Daten gesendet womit ich auch meinen
TV ein und ausschalten konnte. Jedoch hat der Empfänger nix empfangen.
Mal ne andere Frage verträgt sich das IRSND nicht mit dem AVR Sleep
Modus? Wenn man mein Gerät auf "aus" stellt mit der Fernbedienung hatte
ich vor denn AVR(der Fernbedienung) in denn PWR Down Modus zu setzten um
Energie zu sparen. Jedoch wenn ich das mache, wird kein Signal mehr
gesendet. Obwohl das Signal zuerst kommt und dann der Sleep Modus. Ist
das normal?
Felix N. schrieb:> Jedoch wenn ich das mache, wird kein Signal mehr> gesendet. Obwohl das Signal zuerst kommt und dann der Sleep Modus. Ist> das normal?
Das Signal wird normalerweise im Hintergrund gesendet, d.h.
irsnd_send_data() kommt sofort zurück und die ISR sendet das Signal "im
Hintergrund" weiter.
Aber Du hast die Funktion mit TRUE aufgerufen:
irsnd_send_data(&irmp_dat, TRUE);
Dann sollte die Funktion warten, bis der IR-Frame komplett versandt
wurde. Vielleicht hat ein vorheriger Sleep den µC in den Tiefschlaf
versetzt, dass er da gar nicht mehr rauskommt?
Also anders gefragt: Woher weisst Du dass
irsnd_send_data(&irmp_dat, TRUE);
überhaupt aufgerufen wird?
Frank M. schrieb:> Das Signal wird normalerweise im Hintergrund gesendet, d.h.> irsnd_send_data() kommt sofort zurück und die ISR sendet das Signal "im> Hintergrund" weiter.
Ah, das heißt wenn ich denn Command absende. Geht er erst an denn 16 Bit
Timer. Und dann in die irsnd_ISR() und wird dort weiter verarbeitet
richtig?
Frank M. schrieb:> Aber Du hast die Funktion mit TRUE aufgerufen:>> irsnd_send_data(&irmp_dat, TRUE);>> Dann sollte die Funktion warten, bis der IR-Frame komplett versandt> wurde. Vielleicht hat ein vorheriger Sleep den µC in den Tiefschlaf> versetzt, dass er da gar nicht mehr rauskommt?
Also "TRUE" bedeutet das die irsnd_send_data() Funktion wartet bis das
IR-Frame versendet ist richtig? Oder falsch. Der Controller wird beim
Starten nach dem Init kram direkt in denn Power Down Modus gesetzt.
Interrupt's bleiben weiter aktiv. Mit der ISR(INT0_vect) wecke ich denn
Controller. Frage ab ob das System an ist. Wenn nein sende ich das IR
Frame. Mein Gerät geht an und die Status LED geht auch an.
Wenn ich das sleep Weg lasse bei der Funktion. Dann passiert wenn ich
nochmal auf denn Button drücke. Das mein Gerät(IR-Empfänger) ausgeht und
die LED geht auch aus.
Wenn ich aber Sleep dabei lasse. Geht mein Gerät nicht aus. Bzw es wird
nicht gesendet das IR-Frame. Aber meine Fernbedienung geht schon aus.
Frank M. schrieb:> Also anders gefragt: Woher weisst Du dass>> irsnd_send_data(&irmp_dat, TRUE);>> überhaupt aufgerufen wird?
Wenn ich sleep weg lasse wird sie aufgerufen. Wenn ich dazwischen
_delay_ms(2500) mache. Und dann Sleep wird sie nicht aufgerufen.
Felix N. schrieb:> Ah, das heißt wenn ich denn Command absende. Geht er erst an denn 16 Bit> Timer. Und dann in die irsnd_ISR() und wird dort weiter verarbeitet> richtig?
Richtig.
> Also "TRUE" bedeutet das die irsnd_send_data() Funktion wartet bis das> IR-Frame versendet ist richtig?
Richtig.
> Der Controller wird beim> Starten nach dem Init kram direkt in denn Power Down Modus gesetzt.> Interrupt's bleiben weiter aktiv. Mit der ISR(INT0_vect) wecke ich denn> Controller. Frage ab ob das System an ist.
Wie fragst Du das ab?
> Wenn nein sende ich das IR Frame. Mein Gerät geht an und die Status LED geht
auch an.
Okay.
> Wenn ich das sleep Weg lasse bei der Funktion. Dann passiert wenn ich> nochmal auf denn Button drücke. Das mein Gerät(IR-Empfänger) ausgeht und> die LED geht auch aus.
Okay.
> Wenn ich aber Sleep dabei lasse. Geht mein Gerät nicht aus. Bzw es wird> nicht gesendet das IR-Frame. Aber meine Fernbedienung geht schon aus.
Das ist merkwürdig. Ich bin mir nämlich sicher, dass das Warten in
irsnd_send_data() korrekt funktioniert, wenn TRUE übergeben wird. Bist
Du denn sicher, dass das Aufwecken per ISR(INT0_vect) überhaupt bei Dir
funktioniert?
Frank M. schrieb:> Felix N. schrieb:>> Wenn ich aber Sleep dabei lasse. Geht mein Gerät nicht aus. Bzw es wird>> nicht gesendet das IR-Frame. Aber meine Fernbedienung geht schon aus.
Ich habe gerade mal in den Source geschaut: Wenn Du TRUE übergibst,
wartet irsnd_send_data() vorher, bis der vorherige Frame komplett
gesendet wurde. Du musst aber nachher warten.
Das geht so:
Frank M. schrieb:>> Der Controller wird beim>> Starten nach dem Init kram direkt in denn Power Down Modus gesetzt.>> Interrupt's bleiben weiter aktiv. Mit der ISR(INT0_vect) wecke ich denn>> Controller. Frage ab ob das System an ist.>> Wie fragst Du das ab?
1
//Hier vor werden noch die Ports belegt.
2
EICRA &= ~((1<<ISC01) | (1<<ISC00));
3
EIMSK |= (1<<INT0);
4
5
initUSART();
6
irsnd_init();
7
timer1_init();
8
9
sei();
10
11
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
12
sleep_mode();
13
sleep_cpu();
14
sleep_disable();
15
//Controller schläft nun.
Hier mal die INT0 ISR
1
ISR(INT0_vect) {
2
IRMP_DATA irmp_dat; //Initialisierung von IRMP_DATA
}else if(systemOn == 1){ //Abfrage auf System ist bereits aktiv
17
irmp_dat.protocol = IRMP_RC5_PROTOCOL;
18
irmp_dat.address = 0x96;
19
irmp_dat.command = 0x01;
20
irmp_dat.flags = 0;
21
22
irsnd_send_data(&irmp_dat, TRUE); //ON Command senden um es auszuschalten
23
_delay_ms(1000); //Warten
24
PORTC &= ~(1<<LED_25); //Alle LEDS auschalten
25
PORTC &= ~(1<<LED_50);
26
PORTC &= ~(1<<LED_75);
27
PORTC &= ~(1<<LED_100);
28
29
systemOn = 0; //System dekativieren
30
31
_delay_ms(20);
32
33
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
34
sleep_mode(); //Power Down Modus.
35
}
36
}
Frank M. schrieb:> Ich habe gerade mal in den Source geschaut: Wenn Du TRUE übergibst,> wartet irsnd_send_data() vorher, bis der vorherige Frame komplett> gesendet wurde. Du musst aber nachher warten.>> Das geht so:
Teste ich mal.
//EDIT
Wenn ich die while(irsnd_is_busy()) {;} hinzufüge. Bleibt der Controller
da hängen. Habe ich getestet in dem ich vorher eine USART nachricht
gesendet habe(Diese kommt an). Und danach(Kommt nicht mehr). Er reagiert
dann auch auf nix mehr.
Felix N. schrieb:> Wenn ich die while(irsnd_is_busy()) {;} hinzufüge. Bleibt der Controller> da hängen. Habe ich getestet in dem ich vorher eine USART nachricht> gesendet habe(Diese kommt an). Und danach(Kommt nicht mehr). Er reagiert> dann auch auf nix mehr.
Wie sendest Du Nachrichten auf dem UART? Über ein FiFo? Wenn ja,
passiert das, weil Du ihn unmittelbar nach dem Senden der
USART-Nachricht in den Sleep-Modus versetzt. Da hat der µC ja überhaupt
keine Möglichkeit mehr, die Nachricht überhaupt noch rauszusenden.
Ich bin mir ziemlich sicher, dass irsnd_is_busy() korrekt arbeitet.
Schließlich bist Du nicht der erste, der IRSND einsetzt :-)
Frank M. schrieb:> Wie sendest Du Nachrichten auf dem UART? Über ein FiFo? Wenn ja,> passiert das, weil Du ihn unmittelbar nach dem Senden der> USART-Nachricht in den Sleep-Modus versetzt. Da hat der µC ja überhaupt> keine Möglichkeit mehr, die Nachricht überhaupt noch rauszusenden.>> Ich bin mir ziemlich sicher, dass irsnd_is_busy() korrekt arbeitet.> Schließlich bist Du nicht der erste, der IRSND einsetzt :-)
Hi Frank nochmal,
Bin grade nicht an meinen Rechner wo mein ganzer Programmier Kram drauf
ist sondern am Laptop.
Ich sende die USART Nachricht über UDR0. Über ein TTL-USB Apdater.
Der µC wird erst später in denn Sleep Modus gesetzt. Und auch erst nach
der Nachricht. Selbst wenn ich denn Sleep Mode weg lasse und nach der
irsnd_is_busy() eine LED einschalten will. Geht dieses nicht an.
Werde morgen nochmal schauen. Und das Codeschnipsel von irsnd_is_busy
mal posten
Mfg Felix.
Hallo Felix,
der ganze Kram gehört nicht in die ISR!
Der Int löst beim 1. mal aus, da die ISR aber nicht beendet wird da
zuvor ja das sleep kommt, kann kein erneuter Interrupt ausgelöst werden.
Setze in der ISR nur ein Flag und mache den Rest in Main.
Saacha
Sascha W. schrieb:> der ganze Kram gehört nicht in die ISR!
Upps, das hatte ich gar nicht gesehen...
Ja, natürlich, das gehört alles in die Hauptschleife, nicht in die ISR.
Der IRSND hat ja überhaupt keine Chance, etwas zu senden, weil die ISR
überhaupt nicht verlassen wird.
@Felix: Mache es so:
Sascha W. schrieb:> der ganze Kram gehört nicht in die ISR!> Der Int löst beim 1. mal aus, da die ISR aber nicht beendet wird da> zuvor ja das sleep kommt, kann kein erneuter Interrupt ausgelöst werden.> Setze in der ISR nur ein Flag und mache den Rest in Main.
Hallo Sascha W.
Dankeschön, das erklärt wohl warum ich denn Button einmal drücken konnte
um ihn zu wecken und einmal um ihn wieder schlafen legen zu könnten.
Aber nicht wieder wecken konnte nach dem zweiten mal schlafen legen.
Frank M. schrieb:> Upps, das hatte ich gar nicht gesehen...>> Ja, natürlich, das gehört alles in die Hauptschleife, nicht in die ISR.> Der IRSND hat ja überhaupt keine Chance, etwas zu senden, weil die ISR> überhaupt nicht verlassen wird.
Werde ich gleich umsetzten. Werde dann mal schreiben ob es funktioniert
hat.
Mfg Felix.
Felix N. schrieb:> Frank M. schrieb:>> Upps, das hatte ich gar nicht gesehen...>>>> Ja, natürlich, das gehört alles in die Hauptschleife, nicht in die ISR.>> Der IRSND hat ja überhaupt keine Chance, etwas zu senden, weil die ISR>> überhaupt nicht verlassen wird.>> Werde ich gleich umsetzten. Werde dann mal schreiben ob es funktioniert> hat.>> Mfg Felix.
Hallo nochmal,
Danke an euch, es funktioniert nun. Dann weis ich jetzt auch wo der
Fehler.
Mal ne andere Frage, ist es eigentlich möglich ein Overflow Interrupt
und ein Phase Correct PWM auf ein 8 Bit Timer gleichzeitig laufen zu
lassen?
Denn würde gerne in mein Gerät noch ein Timer einbauen. Jedoch ist
Timer0 für 2 120mm Lüfter belegt(12V über Mosfet). Und Timer2 ist für
zwei andere Motoren belegt(Auch über Mosfet). Und 16 Bit hat für das IR
Signal.
Kann ich zb. auf Timer2 ein Overflow Interrupt noch zusätzlich
aktivieren?
Mfg Felix.
Felix N. schrieb:> Felix N. schrieb:>> Frank M. schrieb:>>> Upps, das hatte ich gar nicht gesehen...>>>>>> Ja, natürlich, das gehört alles in die Hauptschleife, nicht in die ISR.>>> Der IRSND hat ja überhaupt keine Chance, etwas zu senden, weil die ISR>>> überhaupt nicht verlassen wird.>>>> Werde ich gleich umsetzten. Werde dann mal schreiben ob es funktioniert>> hat.>>>> Mfg Felix.>> Hallo nochmal,>> Danke an euch, es funktioniert nun. Dann weis ich jetzt auch wo der> Fehler.
sehr schön
> Kann ich zb. auf Timer2 ein Overflow Interrupt noch zusätzlich> aktivieren?
Ja das geht solange wie der Timer bis zu 0xFF zählt. Sollte bei dir der
Fall sein.
Sascha