Hallo µC Forums Gemeinde! ich lese schon lange hier mit jedoch ist dies mein erster Beitrag. Ich war auf der suche nach einem Moodlight mit gut aufgelösten Farbübergängen, einer guten Bedienbarkeit und das man eigene Farbmodi editieren kann. Das Moodlight Programm von Axel Schwenke spiegelt alles sehr gut wieder. Beitrag "noch ein AVR Moodlight" Re: noch ein AVR Moodlight AVR-Moodlight-20120308.tar.gz Geiles Programm! mit den feinsten Farbübergängen die ich bis jetzt im inet gefunden hab. (16Bit Soft PWM mit 204 Helligkeitsstufen) Da ich nicht unbedingt der Fan von Fernbedienungen bin und lieber Taster am "Gerät" selbst haben würde, wollte ich die Taster enprellungs Routine in C von Perter Dannegger in das Moodlight Programm implementieren. Zu mir: ich kann einigermaßen gut c programmieren bin aber im µC Programmieren Anfänger. (Hatte C länger in der Hochschule jedoch Computertechnik nur kurz) Das Problem ist ich verstehe das Moodlight Programm nicht richtig. Ich komme mit den einzelnen Programm Teilen durcheinander und weißt nicht wie das Programm insgesamt abläuft. Meine 1.Ansatz ist in der main.c die Taster ISR einzubauen und im moodlight.c abzufragen ob tasten gedrückt wurden. Und ich würde die selben Tasten defines der Fernbedienung nehmen, sodass beides parallel laufen kann. Ist der Ansatz in die richtige Richtung? Hat Jemand schon mal das selbe probiert? Ich finde wenn man dem Moodlight noch eine tasten Steuerung spendiert und dazu noch die vorhandene Fernbedienungs Steuerung hat dann ist es das perfekte Moodlight Programm. Viele Grüße Philipp
Hallo Philipp, Taster und ISR gehören so nicht zusammen. Bitte schaue ins Tutorial und dann in's Forum: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten
Philipp Tholey schrieb: > Ich war auf der suche nach einem Moodlight mit gut aufgelösten > Farbübergängen, einer guten Bedienbarkeit und das man eigene Farbmodi > editieren kann. > Das Moodlight Programm von Axel Schwenke spiegelt alles sehr gut wieder. > Geiles Programm! mit den feinsten Farbübergängen die ich bis jetzt im > inet gefunden hab. Danke für die Blumen! Ich verlinke den Thread mal richtig: Beitrag "noch ein AVR Moodlight" > Da ich nicht unbedingt der Fan von Fernbedienungen bin und lieber Taster > am "Gerät" selbst haben würde, wollte ich die Taster enprellungs Routine > in C von Perter Dannegger in das Moodlight Programm implementieren. Machen! > Das Problem ist ich verstehe das Moodlight Programm nicht richtig. > Ich komme mit den einzelnen Programm Teilen durcheinander und weißt > nicht wie das Programm insgesamt abläuft. Es sind zwei ISR und die Hauptschleife. ISR #2 ist für IRMP. Die könnte man entsprechend umbiegen für die Abfrage lokaler Tasten. Allerdings würde man sie dafür viel langsamer machen. Für IRMP läuft die nämlich mit 10kHz = 100µs. Für Tasten reicht Faktor 100 langsamer. ISR #1 bedient die PWM. Die ISR wird zwischen 1 und 4-mal pro Durchlauf von Timer 1 ausgelöst. Die Anzahl der Auslösungen hängt von den eingestellten Helligkeiten ab. Wenn die 3 LEDs jeweils eine andere Helligkeit haben, dann löst sie 4 Mal aus: 1. alle LED anschalten 2. die dunkelste LED (die am kürzesten an sein soll) abschalten 3. dito die zweitdunkelste LED 4. dito die hellste LED Die Pause vor dem Einschalten aller LED ist in diesem Zyklus immer am längsten. Dementsprechend dekrementiert die ISR #1 bei der letzten Auslösung die Variable tick. Die Hauptschleife wird zweimal mit den ISR synchronisiert. Zum einen wacht sie aus sleep_cpu() bei jedem Interrupt auf. Und immer wenn tick==0 geworden ist, verläßt sie die erste Warteschleife und führt moodlight_step() und setup_pwm() aus:
1 | while (1) { |
2 | while (tick) { |
3 | if (irmp_get_data(&irmp_data)) { |
4 | moodlight_remote(); |
5 | }
|
6 | sleep_cpu(); |
7 | }
|
8 | moodlight_step(); |
9 | setup_pwm(); |
10 | }
|
moodlight_step() ist die Funktion, die die Helligkeiten der drei Farbkanäle entsprechend dem aktuellen Moodlight-Programm verändert. Nebenher setzt sie auch tick wieder auf einen Wert !=0. Je größer tick gesetzt wird, desto langsamer "läuft" das Moodlight. [Tatsächlich wird die Geschwindigkeit der Moodlight-Programme genau darüber gesteuert. Die tick Variable wird auf den Wert der Moodlight- internen Variable ml.delay gesetzt. Die "schneller" und "langsamer" Tasten ändern wiederum den Wert von ml.delay.] setup_pwm() wiederum nimmt die neuen Helligkeitswerte und berechnet die neuen Auslösezeitpunkte für die PWM-ISR. moodlight_remote() schließlich ist die Funktion, die den aktuellen Tastenstatus abfragt und das Moodlight-Programm entsprechend verändert. Zuletzt gibt es noch moodlight_init() und moodlight_wakeup(). Diese 4 moodlight_xxx() Funktionen bilden das ganze Interface zur Moodlight- Funktionalität. Die kann ansonsten als eigenständiger Automat angesehen werden, mit dem Status in der struct ml:
1 | struct { |
2 | uint8_t mode; /* the active moodlight mode */ |
3 | uint8_t delay; /* run moodlight_step() every "delay" PWM cycles */ |
4 | uint16_t cycle; /* counter used by modes */ |
5 | uint8_t flags; /* on/off, stopped, direction */ |
6 | } ml; |
> Meine 1.Ansatz ist in der main.c die Taster ISR einzubauen und im > moodlight.c abzufragen ob tasten gedrückt wurden. Und ich würde die > selben Tasten defines der Fernbedienung nehmen, sodass beides parallel > laufen kann. > > Ist der Ansatz in die richtige Richtung? Im Prinzip schon. Wenn man die Fernbedienung beibehalten will, dann muß man die IRMP-ISR natürlich weiter mit 10kHz auslösen lassen. Man könnte aber bei jedem 100. Durchlauf durch diese ISR die Tasten einmal abfragen und gedrückte Tasten in entsprechenden globalen Variablen markieren. Alternativ zur IRMP-ISR könnte man die Tasten auch in der Hauptschleife abfragen. Die Variable tick ändert sich ja genau einmal pro Durchlauf des PWM-Zyklus (alle 65536 Takte bzw. mit 122Hz). Vermutlich ist das sogar einfacher. Für lokale Tastendrücke würde man wohl am besten die Funktion moodlight_remote() als moodlight_local() duplizieren. Nur daß man hier die als gedrückt erkannte Taste direkt als Funktionsparameter übergibt. XL
danke für die ausführliche Antwort. hab ich das jetzt so verstanden das ich "diesen" Teil aus der ISR in die main kopiere und die funktion(das was in der ISR war) sozusagen jetz alle 122Hz also 8,19ms ausgeführt wird? Der Unterschied würde doch kaumm auffallen? (Beim länger taste drücken) ISR( TIMER0_OVF_vect ) // every 10ms { static uint8_t ct0, ct1, rpt; uint8_t i; TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);// preload for 10ms i = key_state ^ ~KEY_PIN; // key changed ? ct0 = ~( ct0 & i ); // reset or count ct0 ct1 = ct0 ^ (ct1 & i); // reset or count ct1 i &= ct0 & ct1; // count until roll over ? key_state ^= i; // then toggle debounced state key_press |= key_state & i; // 0->1: key press detect if( (key_state & REPEAT_MASK) == 0 ) // check repeat function rpt = REPEAT_START; // start delay if( --rpt == 0 ){ rpt = REPEAT_NEXT; // repeat delay key_rpt |= key_state & REPEAT_MASK; } } int __attribute__((OS_main)) main(void) { ---> static uint8_t ct0, ct1, rpt; uint8_t i; ----> hw_init(); irmp_init(); moodlight_init(); setup_pwm(); sei(); while (1) { while (tick) { if (irmp_get_data(&irmp_data)) { moodlight_remote(); } sleep_cpu(); } moodlight_step(); setup_pwm(); ---->> i = key_state ^ ~KEY_PIN; // key changed ? ct0 = ~( ct0 & i ); // reset or count ct0 ct1 = ct0 ^ (ct1 & i); // reset or count ct1 i &= ct0 & ct1; // count until roll over ? key_state ^= i; // then toggle debounced state key_press |= key_state & i; // 0->1: key press detect if( (key_state & REPEAT_MASK) == 0 ) // check repeat function rpt = REPEAT_START; // start delay if( --rpt == 0 ){ rpt = REPEAT_NEXT; // repeat delay key_rpt |= key_state & REPEAT_MASK; } ---->> } return 0; } danke und viele Grüße Philipp
ok ich denk nochmal drüber nach... Mir ist die Struktur wie ich das schreibe noch nicht klar. Wo und wie frage ich ab, ob die tick variable verändert wurde und wie benutzte ich das Ereignis dann, als Takt für die entprellung die davor in der ISR war. Eigene fkt schreiben in etwa: if(tick geändert) dann tun was in der ISR stand In der main die Tasten Zustände prüfen und der neuen moodlight_local() übergeben. moodlight_local() ordnet der jeweiligen taste die ihr entsprechende Funktion zu. das wärs erstma für heut abend... Viele Grüße Philipp
Hey, Super jetzt funktioniert´s schon mal. Habe 5 Taster an PORTC gesteckt und kann jetzt fröhlich rum drücken. Habe es so wie 2 Posts weiter oben, einfach in die main kopiert und wenn eine Tastendruck erkannt wurde wird die moodlight_remote_local mit der entsprechenden Taste aufgerufen. Was jetzt noch das Problem ist, die Verknüpfung mit der tick variable. Jetzt müsste die Tasten Abfrage bei jedem main Durchlauf aktiv sein. Ich will aber nur das bei if (tick geändert) aktiv ist. Ist eher ein Programmiertechnisches Problem wie war das nochmal... Einfache Tastendrücke erkennts trotzdem gut. Ansonsten werde ich noch eine funktion für Modus+ und Modus- machen statt der 3 Festen Programm. Damit ich beliebig viele Farb Modi editieren kann. Vielen dank nochmal an Falk für die ausführliche Erklärung des Moodlight Programms. Ich wäre sonst nie so schnell gewesen... Viele Grüße Philipp
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.