Arduino: Bitgehäcksle...
Verfasst: Mi Dez 26, 2012 9:24 pm
Ich hab mir ein ganz einfaches Problem gestellt und gelöst, und der Transfer zur nächsten Stufe will mir nicht gelingen...
Vielleicht ist ja hier der ein oder andere cloidnerux hier der mir weiterhelfen kann...
Folgender Code funktioniert schon.
Es soll aus einem Taster einen Schalter machen:
Da ich später ein paar Taster mehr brauche, und meine Zustandsvariablen reading, previous und state nicht zu arrays machen will, habe ich versucht ein einzelnes Bit zu betrachten.
state kann sich nur ändern wenn reading==HIGH && previous==LOW && (millis()-time > debounce)==TRUE.
(millis()-time > debounce) speicher ich in byte t.
Alle anderen Wertequatrupel bewirken, dass state bleibt wie es ist.
Aus reading, previous, state und t ergibt sich eine 16reihige Wertetabelle die mit dem Zielwert (aktualisierte state-Variable) ausgefüllt werden kann.
Mit einem KV-Diagramm lässt sich das "kürzen" zu:
Die if-Bedingung liefert ja nur 1 oder 0, daher die kürzere Version unten im Quelltext.
Kürzen ist vielleicht das falsche Wort, das sieht gerade viel komplizierter aus als vorher. Ich möchte mit den Bit-Operatoren später ganze Bytes bzw. 4 Bytes verarbeiten, und was mit einem Bit geht sollte ja auch mit mehreren gehen. Zumal eine Implementierung mit Arrays den Nachteil hat, dass ich mit for-Scheifen alle Taster nacheinander auslesen muss. Im Bitmode könnte ich ganze Bytes als Port mit 8 Pins auf einmal einlesen.
Ich habe mal alle Variablen und "Argumente"der Logik-Funktion überwacht und festgestellt, dass alle Werte der Erwartung entsprechen, nur die Neuzuweisung von state klappt nicht, womit state immer LOW bleibt. Aber warum will ich einfach nicht verstehen...
Vielleicht ist ja hier der ein oder andere cloidnerux hier der mir weiterhelfen kann...

Folgender Code funktioniert schon.
Es soll aus einem Taster einen Schalter machen:
Code: Alles auswählen
//SinglePinTastSchalter
byte state = LOW; //derzeitiger LED-Zustand,
byte reading; //derzeitiger Taster-Zustand
byte previous = HIGH; //letzter Taster-Zustand
long time = 0;
long debounce = 200;
void setup()
{
pinMode(14, INPUT_PULLUP); //=A0 mit internem 2k-Pullup (pin14->taster->GND)
pinMode(2, OUTPUT); //=D2 (pin2->LED->GND)
}
void loop()
{
reading = digitalRead(14); //Taster einlesen
if (reading==HIGH && previous==LOW && millis()-time > debounce)
//reading==1 && previous==0 ->Taster gedrückt
//millis()-time > debounce ->und entprellt
{
if (state==HIGH) //ändere LED-Zustand
state=LOW;
else
state=HIGH;
time = millis(); //Wartezeit für nächsten Schleifendurchlauf nullen
}
digitalWrite(2, state); //LED schalten
previous = reading; //letzter Input=aktueller Input
}
state kann sich nur ändern wenn reading==HIGH && previous==LOW && (millis()-time > debounce)==TRUE.
(millis()-time > debounce) speicher ich in byte t.
Alle anderen Wertequatrupel bewirken, dass state bleibt wie es ist.
Aus reading, previous, state und t ergibt sich eine 16reihige Wertetabelle die mit dem Zielwert (aktualisierte state-Variable) ausgefüllt werden kann.
Mit einem KV-Diagramm lässt sich das "kürzen" zu:
Code: Alles auswählen
if ((!reading&&state)||(!previous&&state)||(!t&&state)||(reading&&previous&&!state&t));
aktuellerState==HIGH;
else aktueller==LOW;
Code: Alles auswählen
//SinglePinTastSchalter_bitwise
byte state = LOW;
byte reading;
byte previous = HIGH;
byte t; //für (millis()-time > debounce)
unsigned long time = 0;
unsigned long debounce = 200;
void setup()
{
pinMode(14, INPUT_PULLUP);
pinMode(2, OUTPUT);
}
void loop()
{
reading = digitalRead(14);
if((millis()-time) > debounce)
t=1;
else t=0;
state=((~reading&state)|(~previous&state)|(~t&state)|(reading&previous&~state&t));
time = millis();
digitalWrite(2, state);
previous = reading;
}
Ich habe mal alle Variablen und "Argumente"der Logik-Funktion überwacht und festgestellt, dass alle Werte der Erwartung entsprechen, nur die Neuzuweisung von state klappt nicht, womit state immer LOW bleibt. Aber warum will ich einfach nicht verstehen...