Forum: Mikrocontroller und Digitale Elektronik In Moodlight Programm Taster Entprellen


von Philipp T. (phitho)


Lesenswert?

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

von Uwe (de0508)


Lesenswert?

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

von Axel S. (a-za-z0-9)


Lesenswert?

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

von Philipp T. (phitho)


Lesenswert?

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

von Philipp T. (phitho)


Lesenswert?

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

von Philipp T. (phitho)


Lesenswert?

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
Noch kein Account? Hier anmelden.