Da will man bei einem alten Projekt mal eben den Code ein wenig aufpeppen, drückt nach einiger Weile den Uploadknopf und zack... nix geht mehr kennt ihr das?
Im Detail geht es um eines meiner ersten Projekte, eine Fernbedienung, die verschiedene Geräte ansteuern kann. Da die Tasten nicht sehr zuverlässig funktionierten und nicht all zu schnell nacheinander gedrückt werden konnten, wollte ich mal das pollen und debouncen überarbeiten und die Möglichkeit hinzufügen, eine Taste gedrückt zu halten, um einen Befehl schnell wiederholt zu senden.
Problem:
Nach jedem Tastendruck geht die Fernbedienung in den pwr down modus, um die Batterien zu schonen. Dies hat im alten Sketch tip top funktioniert, im neuen funktionierts nun nicht mehr, obwohl die Schlaffunktion und die ISR praktisch identisch sind. Drücke ich eine Taste, wacht er manchmal gar nicht und manchmal stark verspätet auf. Deaktiviere ich die Funktion, die den uC in den Schlaf schickt, funktioniert alles wunderbar. Komme nicht drauf, was der Fehler ist.
Hier der neue Code:
Tab 1
#include <IRremote.h>
#include <avr/sleep.h>
#include <PinChangeInt.h>
int Tasten[9] = {6, 7, A4, 5, 8, A3, A5, A2};
int unused[7] = {A0, A1, A6, A7, 2, 4};
byte reading = B11111111;
byte laststate = B11111111;
byte buttonvalues = B11111111;
byte lastbuttonvalues = B11111111;
int buttonevent;
unsigned long lastDebounce = 0;
unsigned long repeattimer = 0;
unsigned long sleeptimer = 0;
unsigned long deviceArray1[8] = {0x80C, 0x83C, 0x810, 0x811, 0x838, 0x80D, 0x82B};
unsigned long deviceArray1_2[8] = {0xC, 0x3C, 0x10, 0x11, 0x38, 0xD, 0x2B};
unsigned long deviceArray2[8] = {0x800FF, 0x838C7, 0x88877, 0x8A857, 0x848B7, 0x828D7, 0x8B847};
unsigned long deviceArray3[8] = {0x77E17A1E, 0x77E1401E, 0x77E1D01E, 0x77E1B01E, 0x77E1101E, 0x77E1E01E, 0x77E1BA1E};
unsigned long deviceArray4[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
int rc5state = 0;
// IR Led hängt an Pin 3
int Leds[5] = {9, 10, 11, 12};
int device = 0;
unsigned long loopCount = 0;
IRsend irsend;
void setup() {
for (int i = 0; i < 8; i++) {
pinMode(Tasten[i], INPUT);
digitalWrite(Tasten[i], HIGH);
}
for (int i = 0; i < 4; i++) {
pinMode(unused[i], INPUT);
digitalWrite(unused[i], HIGH);
}
for (int i=0; i<4; i++) {
pinMode(Leds[i], OUTPUT);
}
pinMode(3, OUTPUT);
}
void loop() {
poll(20);
if(klickCheck(7) == 0) {
switchDevice();
}
for (int i=0; i<7; i++) {
if (klickCheck(i) == 0) {
sendIR(i);
repeattimer = millis();
}
else if (klickCheck(i) == 1 && millis() - repeattimer > 150) {
sendIR(i);
repeattimer = millis();
}
}
goToSleep();
} // Loop Ende
Tab 2
//----------------------------------------------------------
// goToSleep: attached pci's und legt den uC schlafen
//----------------------------------------------------------
void goToSleep () {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
delay(30);
for (int i = 0; i < 8; i++) {
PCintPort::attachInterrupt(Tasten[i], awake, FALLING);
}
sleep_mode();
// hier startet er beim Erwachen wieder
sleep_disable();
}
//----------------------------------------------------------
// awake: ISR zum Wecken des uC und Detachen der Interrupts
//----------------------------------------------------------
void awake () {
sleep_disable();
for (int i = 0; i < 8; i++) {
PCintPort::detachInterrupt(Tasten[i]);
}
}
//----------------------------------------------------------
// Poll: liest alle Sensoren aus und speichert die Werte in Variablen
//----------------------------------------------------------
void poll(unsigned long debouncedelay) {
for (int i = 0; i<8; i++) {
bitWrite(reading, i, digitalRead(Tasten[i]));
}
if (reading != laststate) {
lastDebounce = millis();
}
if (reading != buttonvalues && millis() - lastDebounce > debouncedelay) {
buttonvalues = reading;
}
laststate = reading;
}
//----------------------------------------------------------
// klickCheck: 0 = frisch geklickt, 1 = gehalten, 2 = losgelassen, 3 = nicht gedrückt
//----------------------------------------------------------
int klickCheck (int button) { //7=switch
if (bitRead(buttonvalues, button) == 0 && bitRead(lastbuttonvalues, button) == 1) {
bitWrite(lastbuttonvalues, button, 0);
buttonevent = 0;
}
else if (bitRead(buttonvalues, button) == 0 && bitRead(lastbuttonvalues, button) == 0) {
buttonevent = 1;
}
else if (bitRead(buttonvalues, button) == 1 && bitRead(lastbuttonvalues, button) == 0) {
bitWrite(lastbuttonvalues, button, 1);
buttonevent = 2;
}
else if (bitRead(buttonvalues, button) == 1 && bitRead(lastbuttonvalues, button) == 1) {
buttonevent = 3;
}
return buttonevent;
}
//----------------------------------------------------------
// sendIR: sendet code
//----------------------------------------------------------
void sendIR (int taste) {
switch(device) {
case 0:
if(rc5state == 0) {
irsend.sendRC5(deviceArray1[taste], 12);
rc5state = 1;
}
else {
irsend.sendRC5(deviceArray1_2[taste], 12);
rc5state = 0;
}
break;
case 1:
irsend.sendNEC(deviceArray2[taste], 32);
break;
case 2:
irsend.sendNEC(deviceArray3[taste], 32);
break;
case 3:
irsend.sendRC5(deviceArray4[taste], 12);
break;
}
}
//----------------------------------------------------------
// switch: Gerätumschaltfunktion
//----------------------------------------------------------
void switchDevice() {
for(int i = 0; i<4; i++) {
digitalWrite(Leds[i], LOW);
}
digitalWrite(Leds[device], HIGH);
loopCount = millis();
while(millis() - loopCount < 1000) {
poll(20);
if(klickCheck(7) == 0) {
device++;
if(device > 3) {
device = 0;
}
for(int i = 0; i<4; i++) {
digitalWrite(Leds[i], LOW);
}
digitalWrite(Leds[device], HIGH);
loopCount = millis();
}
}
for(int i = 0; i<4; i++) {
digitalWrite(Leds[i], LOW);
}
}