Hallo zusammen, auf die Gefahr hin gleich geseinigt zu werden wollte ich hier mal was fragen. Möchte eine IR- Fernbedienung, die NEC Signale sendet mit einem Atmel einlesen. Dieser soll dann bei bestimmten Tastendruck Funktionen ausführen. (Nur Ausgang ansteuern z.B. LED einschalten) Es ist nur eine Spielerei was ich ausprobieren möchte. Bin was programmieren angeht eine totale Pfeife. Möchte da aber bissl was ausprobieren und Versuche machen. Was ich aber mittlerweile "geschafft" habe, etwas in C zu programmieren, (besser gesagt zu kopeiren) dass meine Ausgänge angeseuert werden sobald ein Taster gedruckt wird :-) Allerdings möchte ich keinen Taster, sondern das Signal der IR Fernbedienung verwenden. IR Empfänger hab ich, kann ich auch an den Atmel anschließen. Die Signale der Fernbedieung (nach dem ersten Break Signal) hab ich mit dem Oszi ausgelesen und in binär aufgeschreiben. Der Wert war plausiebel, da die Blöcke invertiert zum vorherigen waren. Also richtig aufgeschrieben :-) Hab da ein Bild gefunden, in dem das schön aufgezeichnet war. Nun weiß ich allerdings nicht wie ich dem Controller "beibringe", dass er auf die 11000100 00111011 usw. hören soll. (wollte jetzt nicht alle 4 Blöcke aufschreiben). z.B. Wenn PinD5 ist 11000100 ... (oder diesen Wert in einem anderen Zahlensystem) Wenn PinD5 ist Taster gedrückt hab ich geschafft, aber nicht, dass er auf das IR Signal reagiert :-( Gibt es dazu ein "Grundprojekt", damit die "Hör auf NEC Protokoll" beim Atmel aktiviert wird, bei dem ich dann "einfach" meine ausgelesenen Werte eintragen und dem Pin an dem der IR Empfänger angeschlossen ist zuweißen kann? Suche kein kompliziertes alles könnendes (ich nicht versehendes), sondern nur auf bestimmte NEC Signale hören. p.s. Englischkenntnisse sind so gut wie nicht vorhanden. Hoffe ich hab mich einigermaßen verständlich ausgedrückt? Grüße Michael
Du suchst das: https://www.mikrocontroller.net/articles/IRSND bzw. das https://www.mikrocontroller.net/articles/IRMP
:
Bearbeitet durch User
Michael schrieb: > Suche kein kompliziertes alles könnendes (ich nicht versehendes), > sondern nur auf bestimmte NEC Signale hören. Dann ist IRMP wohl nichts für dich
1. Bau dir einen Empfänger mit der o.a. IRMP Library und compiliere mit NEC und NEC42 Unterstützung. 2. Nutze eine serielle Schnittstelle (oder ein LCD) um die Codes deiner NEC Fernbedienung (Adresse und Tastencode) herauszufinden. 3. Baue eine Software, die die FB-Adresse durchlässt und dann per 'switch-case' oder 'if else', um die Tastencodes auszuwerten und damit Pins zu schalten.
:
Bearbeitet durch User
Hallo, danke für die Antworten. Das IRMP hab ich bereits im Vorfeld angeschaut und nix verstanden. (werd ich auch niemals). Ich such NUR ein paar Zeilen, dass die Startsequenz beginnt, endet und der Tastencode anfängt. Den TastenCode hab ich bereits per Oszi ausgelesen.
Michael schrieb: > Das IRMP hab ich bereits im Vorfeld angeschaut und nix verstanden. > (werd ich auch niemals). Mit deinem Smartphone, falls du Besitzer eines solchen bist, wird es dir nicht viel anders ergehen. Benutzen kann man es trotzdem.
Michael schrieb: > Ich such NUR ein paar Zeilen, dass die Startsequenz beginnt, endet und > der Tastencode anfängt. Ich habe den Eindruck, das du keine Ahnung hast, wie schwierig es ist, z.B. Codes anderer Fernbedienungen, Störungen des IR Empfängers und Situationen wie nur teilweise empfangene Codes auszublenden. Genau das macht IRMP in nahezu perfekter Manier und deswegen ist es wirklich sinnvoll, sich lieber ein paar Stunden mit IRMP zu beschäftigen, anstatt zu probieren, das Rad neu zu erfinden. Immerhin hast du damit auch eine Basis für andere Projekte und lernst nebenbei noch eine Menge.
Fertige Zeilen in C habe ich nicht, aber in PIC Assembler wie folgt gelöst: Eine mögliche Vorgehensweise zum Erkennen der Startsequenz: Bei fallender Flanke des IR Empfängers einen Timer starten, der länger als 9ms Laufzeit hat. z.B einen 8Bit Timer mit 64µs Taktrate ergibt 16,384ms Messzeit. Tritt nun eine folgende steigende Flanke auf, so kann man den Timerwert prüfen. Liegt er z.B. unterhalb von 8,5ms oder oberhalb von 9,5ms oder ist er sogar übergelaufen, so verlässt man die Routine und beginnt sie von Neuem. Also wieder auf eine fallende Flanke warten. Liegt die Messung im gewünschten Toleranzfenster so wurde die 9ms Lowphase erkannt. Die Routine wird nicht verlassen sondern der Timer erneut genullt und auf dieselbe Weise wird überprüft, ob der 9ms Lowphase eine 4,5ms Highphase folgt. Wird etwas anderes als die 4,5ms plus minus Toleranz erkannt, so wird die Routine hier verlassen und wieder ganz von Vorne begonnen. Wurde aber auch die 4,5ms Highpase korrekt erkannt, so ist die Startsequenz detektiert und es kann nun ans Einlesen der Datenbits gehen. Zuerst wird die 8Bit Geräteadresse eingelesen und zwischengespeichert, dann wird die invertierte Geräteadresse eingelesen und auf Übereinstimmung mit der zuvor eingelesenen überprüft. Bei Abweichung... Routine verlassen und wieder von Vorne. Bei Übereinstimmung geht es mit dem Einlesen des 8Bit Kommandos weiter. Dieses wird dann im zweiten Lesevorgang mit dem invertierten Kommando verglichen. Abweichung = Routine verlassen. Übereinstimmung = weitermachen. Zur Sicherheit den kompletten Vorgang mehrfach wiederholen, also nicht nur ein einziges Protokoll einlesen sondern zwei oder drei aufeinanderfolgende und diese dann auf Übereinstimmung prüfen. Wenn mehrere aufeinanderfolgende übereinstimmen kann man davon ausgehen richtig empfangen zu haben. Nun kann das gelesene Kommando mit den bekannten Kommandos verglichen und die dem Kommando entsprechende Aktion ausgeführt werden. Die Leseroutine arbeitet ebenfalls mit dem Timer, aber diesmal auf 2,048ms Overflow eingestellt. Läuft er über wurde nichts Sinvolles erkannt. Zum Lesen der 8Bit wird erneut auf eine fallende Flanke gewartet und dann der Timer gestartet wenn sie auftritt. Danach folgt entweder 560µs Lowpegel weil eine 0 gesendet wurde oder 1,69ms Lowpegel weil eine 1 gesendet wurde. Unterscheiden läasst sich das indem man z.B. nach ca. 830µs den Pegel einliest. Ist er hier noch Low so liegt das an der langen Lowpegel Phase weil eine "1" gesendet wurde. Ist er hier bereits wieder High, so liegt das an der kurzen Lowphase weil eine "0" gesendet wurde. Auf diese Art un Weise werden in einer Loop jeweils 8Bit eingelesen. Läuft der Timer über ist etwas schief gelaufen, also Routine verlassen und alle Daten verwerfen. Läuft er nicht über so hat man etwas mit einer gewissen Sicherheit/Unsicherheit empfangen, nämlich nur einmal. Deshalb macht es Sinn, mehrfach zu lesen und auf Übereinstimung zu prüfen.
Nec Decoder schrieb: > Danach folgt entweder 560µs > Lowpegel weil eine 0 gesendet wurde oder 1,69ms Lowpegel weil eine 1 > gesendet wurde. Unterscheiden läasst sich das indem man z.B. nach ca. > 830µs den Pegel einliest. Ist er hier noch Low so liegt das an der > langen Lowpegel Phase weil eine "1" gesendet wurde. Ist er hier bereits > wieder High, so liegt das an der kurzen Lowphase weil eine "0" gesendet > wurde. Dieser Text bezieht sich auf das IR Signal. Der Emfpänger liefert aber die Pegel genau umgekehrt. Also sind die Einsen und Nullen hier genau umgekehrt wie oben beschrieben. Anbei noch ein Bild wie der Code am Empfängerausgang aussieht.
Michael schrieb: > Das IRMP hab ich bereits im Vorfeld angeschaut und nix verstanden. 1. IRMP-Source herunterladen Klicke auf IRMP: Download 2. IRMP-Quellen ins Projekt einfügen Klicke auf IRMP: Source-Code 3. irmp-main-avr.c als main-Modul hinzufügen oder Inhalt ins vorgefertigte main.c kopieren Klicke auf IRMP: Source-Code unter "Beispiele ..." 4. F_CPU im Projekt setzen Klicke auf IRMP: Source-Code und rolle vor bis zum roten Kasten: "Wichtig" 5. irmpconfig.h: Setze alle IRMP_SUPPORT_xxx_PROTOCOL auf 0 IRMP_SUPPORT_NEC_PROTOCOL auf 1 Klicke auf IRMP: IRMP SUPPORT xxx PROTOCOL Du kannst die Stelle aber auch so lassen wie es ist. Dann "versteht" Dein µC sogar noch ein paar weitere Fernbedienungen, die außerdem noch in Deinem Haushalt rumschwirren. 6. irmpconfig.h: IRMP_PORT_LETTER + IRMP_BIT_NUMBER definieren Klicke erst auf IRMP: IRMP SUPPORT xxx PROTOCOL und rolle bis zum nächsten Unterkapitel vor. 7. Projekt kompilieren und Programm flashen Klicke dazu auf die Dokumentation Deiner eingesetzten IDE. 8. USB-UART-Adapter an µC-UART anschließen und sich über Ausgabe bei jedem Fernbedienungs-Tastendruck freuen Klicke jetzt nicht, sondern schnapp Dir Bleistift und Zettel und notiere Dir nun jeden empfangenen Code samt Tastennamen auf dem Zettel. Geschätzter Aufwand: 15 Minuten für den fortgeschrittenen Anwender, halbe bis ganze Stunde für den Anfänger. Bis dahin hast Du gerade eine Handvoll von Zeilen Deines NEC-Decoders überhaupt geschrieben bzw. aus anderen Quellen zusammengeklaubt. Wenn alle Schritte 1-8 erfolgreich waren: 9. Anpassungen von main(), um IR-Signale auszuwerten und in Aktionen umzusetzen. Dazu obigen Zettel einsetzen. Klicke dazu auf IRMP: Anwendung von IRMP War das jetzt sooo schwierig? Oder ist es Dir zu anstrengend einen Artikel wie IRMP überhaupt sinnentnehmend zu lesen? Merke: IRMP bekommst Du geschenkt. Aber deshalb ist freie Software nicht immer kostenlos. Man muss schon etwas reinstecken: Es nennt sich "Aufwand". Aber dieser ist dank der IRMP-Dokumentation äußerst niedrig. Rausreden kannst Du Dich mit Deinen nicht vorhandenen Englischkenntnissen jedenfalls nicht: Der Artikel ist in deutsch verfasst.
:
Bearbeitet durch Moderator
Hallo, hab jetzt fast 2 Tage damit verbracht das Standard IRMP Projekt inkl. UART Ausgabe in Studio 6 zum Laufen zu bringen. Das funktioniert und ich kann die Tastensignale anschauen. :-) Jetzt versuch ich seit 1 Tag eine LED zum Blinken im Takt zu bringen solange eine Taste gedrückt ist. Aber da scheiterst gewaltig... (Es passiert einfach mal nix, egal was ich schreib) Ja, ich hab den Artikel gelesen, hilft MIR aber nicht weiter. Kann nicht mal einschätzen wo der Fehler liegt. (oder die Fehler) Evtl. schon ganz am Anfang bei der Zuordnung der Ein/ Ausgänge beim Mega8 oder dann doch an den paar Zeilen die ich geschrieben und aus einem anderen funktionierenden Projekt rauskopiert habe. Mein "Werk" beginnt ab main (void) sowie oben die 16MHz, die ich reingeschrieben habe. Hat evtl. jemand einen Tip? Grüße Michael
1 | (irmp_data.protocol == IRMP_NEC_PROTOCOL && // NEC-Protokoll |
2 | irmp_data.address == 0xDC23 // Adresse 0xDC23 |
3 | && irmp_data.command == 0x0014 | // Taste Vol+ |
4 | irmp_data.protocol == IRMP_NEC_PROTOCOL && |
5 | irmp_data.address == 0xDC23 |
6 | && irmp_data.command == 0x0017 ) // Taste Pfeil oben |
7 | {
|
Das sieht zu kompliziert aus. Teste einmal in der Hauptschleife auf NEC Protokoll und die Adresse, dann mache aus irmp_data.command ein switch-case Konstrukt. Dann musst du nicht jedesmal alles abfragen. Das mit dem Repetition Flag klappt nicht bei allen Fernbedienungen. Lass es besser weg und löse die Tastenwiederholung durch das Durchlaufen der Hauptschleife.
Michael schrieb: > hab jetzt fast 2 Tage damit verbracht das Standard IRMP Projekt inkl. > UART Ausgabe in Studio 6 zum Laufen zu bringen. > Das funktioniert und ich kann die Tastensignale anschauen. :-) Gratuliere erst einmal zu Deinem Durchhaltevermögen :-) Ich nehme an, dass Du dabei auch einiges gelernt hast. Matthias S. schrieb: > Das sieht zu kompliziert aus. Das ist nicht nur viel zu kompliziert, sondern auch mit einigen Fehlern gespickt. Zum Beispiel sollte man statt dem bitweisen Operator '|' besser den Logik-Operator '||' verwenden, wenn man Bedingungen miteinander verknüpfen möchte. Außerdem ist das hier falsch:
1 | while (IRMP_FLAG_REPETITION == 0x01) |
IRMP_FLAG_REPETITION ist eine Konstante, nämlich exakt 0x01. Diese ändert sich nie. Damit wird das zu einer Endlosschleife. Das Programm hängt sich hier sprichwörtlich auf. @Michael: Du hast offenbar gewaltige Lücken bei Deinen C-Kenntnissen. So wird das schwierig. Was möchtest Du? Eine LED leuchten lassen, solange eine Taste gedrückt ist? Hier mal eine mögliche Lösung, dabei musst Du die ISR und main() durch den unteren Code ersetzen. Dabei vermeide ich grundsätzlich Delay-Funktionen, die nur das Programm ausbremsen. Dann verhält sich das Programm träge und reagiert nicht so schnell, wie man möchte. Wenn ich sowieso eine Timer-Routine habe, dann sollte ich sie auch nutzen! Zunächst definieren wir eine globale Variable als Countdown, die jede Millisekunde heruntergezählt wird:
1 | static volatile unsigned char msec_counter; // Countdown, wird jede Millisekunde heruntergezaehlt |
Jetzt bauen wir in die ISR den Countdown ein:
1 | ISR(COMPA_VECT) // Timer1 ISR, called every 1/15000 sec |
2 | {
|
3 | static uint8_t cnt; // Zaehlvariable, wird bei jedem Aufruf um 1 inkrementiert |
4 | |
5 | (void) irmp_ISR(); // call irmp ISR |
6 | |
7 | cnt++; |
8 | |
9 | if (cnt == F_INTERRUPTS / 1000) // Wenn cnt == 15, ist eine Millisekunde vergangen |
10 | {
|
11 | cnt = 0; // cnt zuruecksetzen |
12 | |
13 | if (msec_counter > 0) // Countdown herunterzaehlen |
14 | {
|
15 | msec_counter--; |
16 | }
|
17 | }
|
18 | }
|
Jetzt die main-Funktion. Sie prüft das IR-Protokoll und die Adresse nur einmal.
1 | int
|
2 | main (void) |
3 | {
|
4 | IRMP_DATA irmp_data; |
5 | |
6 | DDRB = 0b11111111; // Alle auf B sind als Ausgaenge definiert |
7 | DDRC = 0b11001111; // PC4, PC5 Eingaenge |
8 | DDRD = 0b11110011; // PD2, PD3 Eingaenge (D2= IR IN; IR auch in IRMPConfig.h eingestellt! |
9 | |
10 | irmp_init(); // initialize IRMP |
11 | timer1_init(); // initialize timer1 |
12 | |
13 | sei (); // enable interrupts |
14 | |
15 | for (;;) |
16 | {
|
17 | if (irmp_get_data (&irmp_data)) |
18 | {
|
19 | if (irmp_data.protocol == IRMP_NEC_PROTOCOL && // NEC-Protokoll |
20 | irmp_data.address == 0xDC23) // Adresse 0xDC23 |
21 | {
|
22 | if (irmp_data.command == 0x0014 || // Taste Vol+ oder |
23 | irmp_data.command == 0x0017) // Taste Pfeil oben |
24 | {
|
25 | PORTD |= (1<<PD0); // Ausgang PD0 ansteuern |
26 | msec_counter = 200; // countdown auf 200 (maximal 255 moeglich!) |
27 | }
|
28 | else if (irmp_data.command == 0x0015 || // Taste Vol- oder |
29 | irmp_data.command == 0x0018) // Taste Pfeil unten |
30 | {
|
31 | PORTD |= (1<<PD1); // Ausgang PD1 ansteuern |
32 | msec_counter = 200; // countdown auf 200 (maximal 255 moeglich!) |
33 | }
|
34 | }
|
35 | }
|
36 | else if (msec_counter == 0) // 200 msec vergangen... |
37 | {
|
38 | PORTD &= ~((1<<PD0) | (1<<PD1)); // PD0 und PD1 zuruecksetzen |
39 | }
|
40 | }
|
41 | }
|
Immer, wenn eine Taste erkannt wurde, wird die entsprechende LED eingeschaltet. Wurde 200msec kein IR-Signal erkannt, werden beide LEDs wieder abgeschaltet. Wie funktioniert das? Wenn eine LED eingeschaltet wird, wird der Countdown-Zähler auf 200 gesetzt. In der ISR wird dieser Countdown dann jede Millisekunde heruntergezählt. Sobald der Wert 0 ist, werden die LEDs gelöscht. Wenn Du LED1 und LED2 vom Timing her getrennt behandeln willst, musst Du für jede LED einen eigenen Countdown-Zähler einbauen. Aber normalerweise willst Du offenbar immer nur eine LED leuchten lassen, wenn eine Taste gedrückt wurde. Probiere es also aus und berichte, ob das für Dich so passt oder nicht. Das Programm ist ungetestet. Wenn etwas nicht so läuft wie beschrieben, melde Dich bitte.
:
Bearbeitet durch Moderator
Alternativ könnte man auch je eine EIN-Taste und eine AUS-Taste für jede LED definieren. Dann braucht man den Millisekunden Countdown gar nicht und die ISR- und main-Funktion kann man dann folgendermaßen schreiben:
1 | ISR(COMPA_VECT) // Timer1 ISR, called every 1/15000 sec |
2 | {
|
3 | (void) irmp_ISR(); // call irmp ISR |
4 | }
|
5 | |
6 | int
|
7 | main (void) |
8 | {
|
9 | IRMP_DATA irmp_data; |
10 | |
11 | DDRB = 0b11111111; // Alle auf B sind als Ausgaenge definiert |
12 | DDRC = 0b11001111; // PC4, PC5 Eingaenge |
13 | DDRD = 0b11110011; // PD2, PD3 Eingaenge (D2= IR IN; IR auch in IRMPConfig.h eingestellt! |
14 | |
15 | irmp_init(); // initialize IRMP |
16 | timer1_init(); // initialize timer1 |
17 | |
18 | sei (); // enable interrupts |
19 | |
20 | for (;;) |
21 | {
|
22 | if (irmp_get_data (&irmp_data)) |
23 | {
|
24 | if (irmp_data.protocol == IRMP_NEC_PROTOCOL && // NEC-Protokoll |
25 | irmp_data.address == 0xDC23) // Adresse 0xDC23 |
26 | {
|
27 | switch (irmp_data.command) |
28 | {
|
29 | case 0x0014: PORTD |= 1<<PD0; break; // Taste Vol+: PD0 ein |
30 | case 0x0015: PORTD &= ~(1<<PD0); break; // Taste Vol-: PD0 aus |
31 | case 0x0017: PORTD |= 1<<PD1; break; // Taste Pfeil oben: PD1 ein |
32 | case 0x0018: PORTD &= ~(1<<PD1); break; // Taste Pfeil unten: PD1 aus |
33 | }
|
34 | }
|
35 | }
|
36 | }
|
37 | }
|
Die ISR kannst Du in diesem Fall wieder auf den Aufruf von irmp_ISR() reduzieren, den Kram mit dem msec_counter kannst du komplett aus dem Source wieder löschen. Jetzt ist die main()-Funktion noch einfacher geworden. Aber wie gesagt: Jetzt brauchst Du für jede Ein-/Aus-Funktion immer jeweils 2 Tasten.
:
Bearbeitet durch Moderator
Super, Dankeschön. :-) Meine C Kenntnisse sind gleich Null. Hab das nie gelernt bzw. beigebracht bekommen. Versuche selber etwas damit rum zu probieren. Spiele momentan mit beiden Varianten (die erste und die zweite mit den switch) Wollte nun einen Schritt weiter gehen und noch dazu Eingänge abfragen. den ersten Fall mit einer Taste, den zweiten mit dem switch und zwei tasten zusätzlich das mit dem Eingang abfragen Auf bestimmtes Fernbedienungssignal UND einen high Pegel am Atmel. Erst dann soll der Ausgang geschaltet werden. Was möchte ich nun probieren? Eine Tast soll unterschiedliche Ausgänge ansteuern. Je nach dem welcher Eingang high ist soll der andere Ausgang angesteuert werden. Versucht hab ich das: Mit && wird ein Ausgang angesteuert egal was an dem PIN anliegt. Mit & wird garnix mehr angesteuert. else if ((irmp_data.command == 0x0050) && // Taste MENU (PINC & (1<<PINC5))) // PC5 = high ->einlesen Funktioniert NICHT { PORTC |= (1<<PC1); // Ausgang PC1 ansteuern, da PC5 hight ist msec_counter = 200; // countdown auf 200 (maximal 255 moeglich!) } else if ((irmp_data.command == 0x0050) && // Taste MENU (PINC & (1<<PINC4))) // PC4 = high ->einlesen Funktioniert NICHT { PORTC |= (1<<PC2); // Ausgang PC2 ansteuern, da PC4 high ist msec_counter = 200; // countdown auf 200 (maximal 255 moeglich!) }
Meinen vorherigen Beitrag bitte erstmal ignorieren. Hab den Fehler gefunden... Lag an meiner Versuchs HW (Steckbrett; teils fliegender Aufbau) Werd mich nun an einen weiteren Versuch wagen.
Hallo zusammen, da ich momentan mit einer Funktion nicht weiterkomme wollte ich hier nochmal um Rat fragen. Meine Programmiererei funktioniert soweit recht gut. Hat mich selber überrascht ;-) Nur eines schaff ich leider nicht. Ich möchte: Wenn Taster an Fernbedienung gedrückt ist: PD5 ansteuern Fall 1: - solange PD3 low ist - solange PD3 dann high ist Aufhören wenn PD3 dann wieder low ist (PD5 nicht mehr ansteuern) Also low, high, low -> Aus Fall 2: - solange PD3 high ist Aufhören wenn PD3 dann low ist (PD5 nicht mehr ansteuern) Also high, low -> Aus Des weiteren soll diese Funktion JEDERZEIT mit der OK Taste der Fernbedienung abgebrochen werden können (PD5 wird dann nicht mehr angesteuert und Funktion verlassen) [schön wäre, wenn der Spaß nach 12 Sekunden automatisch stoppen würde, aber das war mir zu viel] Anbei den Ausschnitt des Programms die die nicht so funktionierende Funktion beinhaltet. Probleme: OK Taste wird gar nicht beachtet :-( Fall 1 ist erst zu Ende wenn PD3: low, high, low, high, low -> Aus Fall 2 ist erst zu Ende wenn PD3: high, low, high, low -> Aus Nur warum muss "hinten" immer ein weiteres high, low dazu? Vor dem else if frag ich nur normale Tasten ab und steuer die Ausgänge so lange wie die Taste gedrückt ist. Also ncihts verschachteltes oder kompliziertes, sondern ganz einfaches wie mir paar Beiträge vorher von Frank gezeigt wurde. Den Case hab ich momentan nicht in Verwendung. Grüße Michael
Michael schrieb: > Funktioneirt_nicht_wie_es_soll.txt Was soll das sein. Kein Syntax Highlightning, nichts funktioniert :-( Was spricht dagegen, die für die Programmiersprache üblicherweise verwendete File Extension zu verwenden?
Das hier
1 | && (!(irmp_data.command == 0x0055)) |
tritt immer ein, denn die ganze Entscheidung hängt ja zuerst hiervon ab:
1 | else if (irmp_data.command == 0x0054) |
Um eine etwaige OK Taste abzufragen, musst du ja erstmal ein neues Kommando von der FB empfangen. Ich würde sowas vermutlich mit Flags machen. Also ein Flag setzen für den 'schwebenden Zustand' mit PD3, das später den Pin setzt. Und wenn irmp.data_command() die OK Taste empfängt, löschst du das Flag wieder. Ansonsten wird es nach der Sequenz Low,high,low an PD3 gelöscht (oder was auch immer du definierst). Ganz am Ende der Hauptschleife setzt du dann zentral den gewünschten Port, abhängig vom Flag. Übrigens finde ich es sehr gut, das du dich soweit damit schon beschäftigt hast - Respekt :-) Wenn du nächstes Mal deine Datei einfach als main.c oder so hochlädst, überrascht dich dieses Forum mit syntaxhighlighting.
:
Bearbeitet durch User
puhhh... Flags War schon froh die "einfachen" Abfragen hinzubekommen. Das mit den Flags schau ich grad bissl an... schwierige Sache (zumindest für mich) Hört sich aber für meine Zwecke gut an :-) Aber dass mein low, high, low Teile nicht funktionieren ist mir ein Rätsel. Auch wenn ich Funktion einzeln in lauter verschiednee kleine if mach, kommt immer das Gleiche dabei raus :-( Grüße Michael
Michael schrieb: > puhhh... Flags Flags sind easy. Das ist einfach eine Veriable, die du mit TRUE oder FALSE füllen kannst. Wenn du z.B. PD5 high machen willst, setzt du eine Variable auf TRUE und am Ende der Hauptschleife checkst du, wie die Variable steht. Ist sie TRUE, setzt du PD5, ist sie FALSE, löschst du PD5. Um vVerwirrungen damit zu vermeiden, steht bei meinem Projekten die Definition von TRUE und FALSE (nicht verwechseln mit true und false), in den Settings:
1 | #define TRUE 1
|
2 | #define FALSE !TRUE
|
3 | // und hier mal ein Bitfeld mit Flags
|
4 | typedef struct theFlags { |
5 | uint8_t Send : 1 ; |
6 | uint8_t Mute : 1 ; |
7 | uint8_t TimerActive : 1 ; |
8 | } theFlags_t; |
Dann kann man damit rummachen, z.B.
1 | theFlags_t MyFlags ; |
2 | if (irmp_get_data (&irmp_data)) |
3 | {
|
4 | if ((irmp_data.protocol == 0x1C) && (irmp_data.address == 0x0113)) |
5 | {
|
6 | switch (irmp_data.command) { |
7 | case FB_VIDEOUP : if (DAC[0] < 63) DAC[0]++; |
8 | MyFlags.Send = TRUE; |
9 | break; |
10 | case FB_VIDEODN : if (DAC[0] > 0) DAC[0]--; |
11 | MyFlags.Send = TRUE; |
12 | break; |
13 | case FB_CHANUP : if (DAC[1] < 63) DAC[1]++; |
14 | MyFlags.Send = TRUE; |
15 | break; |
16 | case FB_CHANDN : if (DAC[1] > 0) DAC[1]--; |
17 | MyFlags.Send = TRUE; |
18 | break; |
19 | case FB_STORE : store_EEPROM(); break; |
20 | |
21 | // if power is pressed mute both
|
22 | case FB_POWER : if (MyFlags.Mute) { |
23 | DAC[0] = vol0; |
24 | DAC[1] = vol1; |
25 | MyFlags.Send = TRUE; |
26 | MyFlags.Mute = FALSE; |
27 | PORTB |= (1 << MUTE_PIN); // Audio PA on |
28 | } else { |
29 | vol0 = DAC[0]; DAC[0] = 0; |
30 | vol1 = DAC[1]; DAC[1] = 0; |
31 | MyFlags.Send = TRUE; |
32 | MyFlags.Mute = TRUE; |
33 | PORTB &= ~(1 << MUTE_PIN); // mute Audio PA |
34 | }; break; |
35 | }; // end switch |
36 | } // end irmp_data_prot |
37 | } // end irmp_get_data |
Kleiner Ausschnitt. Das Flag myFlags.Mute sagt mir, ob die Anlage schon gemutet ist, also ob ein Tastendruck wieder laut machen soll. Das Flag myFlags.Send sagt, ob nach der ganzen Abfragerei was an den I²C Bus gesendet werden soll. Entschuldige die merkwürdige Formatierung, aber das Forum ist mit TABs etwas eigenwillig.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.