cyborg5 / IRLib2

Library for receiving, decoding, and sending infrared signals using Arduino
GNU General Public License v3.0
384 stars 138 forks source link

Compatibility issue with sleep and interupt? #52

Open jbike opened 6 years ago

jbike commented 6 years ago

Trying to make an Arduino IR transmitter sleep between button presses, so an on/off switch is not required (like an off the shelf IR remote control). Thus, the batteries are always connected to a Arduino Pro Mini with regulator and led removed to save power during sleep.

The IR code works perfectly for different devices and functions when used without sleep. Sleep and sleep interrupt (on pin 2) seem to work fine by themselves. The problem is, the combined IR code/interrupt/sleep doesn't get the timing right- the gap between mark and space is greatly reduced, so the IR code is no longer received correctly. The sleep functions work correctly, and it does send IR, but with the timing not correct anymore.

include

//#include //#include //#include <avr/power.h>

include <avr/interrupt.h>

include <avr/sleep.h>

//#include <avr/io.h>

//***** This program doesn't work because ** //** sleep interferes with the timing ? *

IRsend mySender; //defined output on pin 3 of UNO const int buttonPin1 = 8; // the number of the pushbutton pin const int buttonPin2 = A0; volatile int buttonState1 = 1; // variable for reading the pushbutton status volatile int buttonState2 = 1; volatile byte state = LOW;

void setup() { pinMode(13, OUTPUT); pinMode(buttonPin1, INPUT_PULLUP); // led pin 3 already declared as output pinMode(buttonPin2, INPUT_PULLUP); pinMode(2,INPUT_PULLUP); //note a diode goes to each button, so pulling either button low triggers the interrupt attachInterrupt(0,blink,FALLING);
}

void loop() {

//digitalWrite(13, state); if (buttonState1 == LOW) { IRsend mySender; //send a code every time a character is received from the serial port //Sony TV KDL-52S4100 (This code assumes the TV is on)- A90 12 bits is toggle power mySender.send(GICABLE,0xF800, 16); // sends "pause the cable TV" delay(400); mySender.send(SONY,0xA50, 12); // sends "bring up input menu" delay(400); mySender.send(SONY,0xAF0, 12); // sends "cursor down" ie., HDMI 2 delay(400); mySender.send(SONY,0xA70, 12); // sends "enter" delay(400); } if (buttonState2 == LOW) { send a code every time a character is received from the serial port Sony TV KDL-52S4100 mySender.send(SONY,0xA50, 12); // sends "bring up input menu" delay(400); mySender.send(SONY,0x2F0, 12); // sends "cursor up" ie., HDMI 1 delay(400); mySender.send(SONY,0xA70, 12); // sends "enter" delay(400); mySender.send(GICABLE,0x3C08, 16); // sends " rewind cable TV (and play)" delay(400); } sleepNow(); // sleep function called here }

void blink() { buttonState1 = digitalRead(buttonPin1); //determine which button was pushed buttonState2 = digitalRead(buttonPin2); //a diode per button connected to pin2 state = !state; } void sleepNow(void) { // Set pin 2 as interrupt and attach handler: attachInterrupt(0,blink,FALLING); delay(100);
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here sleep_enable(); sleep_bod_disable(); // Put the device to sleep: sei(); //enable interrupts sleep_cpu(); // // Upon waking up, sketch continues from this point. sleep_disable(); cli(); //disable interrupts }

cyborg5 commented 6 years ago

I'm sorry I have no experience with any sleep operations so I don't know how it works and how it might interfere with sending. The timing of the send routines is all based on the built-in delayMicroseconds(val) function so unless you're doing something that messes up that built-in function I'm not sure why this would go bad. I did notice that you are declaring your send object inside the loop which I would not recommend. Typically it is global to the entire sketch. In fact I'm surprised some of the code would work at all. It looks to me like where you have declared it, it would be local to that first if statement inside the loop it would not be available elsewhere. I don't think that's the problem but I would definitely move it outside the loop function. Perhaps someone else who is more familiar with how sleep mode works can advise.