Hola, me he encontrado con la problemática acerca de como no se puede utilizar la función de millis() en una interrupción, me gustaría pedir su ayuda para encontrar una solución o alternativa a este conflicto. El código funciona correctamente sin utilizar la función sleep() pero necesito poner a dormir el ATtiny85 para ahorrar energía.
El programa debe de esperar pulsaciones de 2 segundos para activar el Led por 1 segundo en ambos botones BTN1 y BTN2 pero en el botón 2 (BTN2) debe reconocer una pulsación corta y accionar por menos tiempo el mismo Led.
Espero me puedan apoyar con algún consejo o sugerencia, gracias.
#include <avr/sleep.h>
#include <avr/interrupt.h>
int BTN2 =2;
int BTN1 =1;
int Led = 0;
//Variables de estado de los botones
int EST1=0;
int EST2=0;
boolean PLS1_LRG = 0;
boolean PLS2_LRG = 0;
//Cambio de estado del botón 2
boolean EstadoPin = false;
boolean AnteriorEstadoPin = false;
//Vatiables de estado para el tiempo de la pulsación
unsigned long T_Control=0;
unsigned long T_Apagado = 500;
unsigned long T_PLS1=0;
unsigned long T_PLS2=0;
void setup() {
pinMode(BTN2, INPUT);
pinMode(BTN1, INPUT);
pinMode(Led, OUTPUT);
}
void lecturaBTN1(){
if(EST1 == HIGH && T_PLS1 == 0){
T_PLS1 = millis();
}
if(T_PLS1 != 0){
if(millis() - T_PLS1 > 2000){
PLS1_LRG = 1;
if(PLS1_LRG == 1){
activaBTN1();
PLS1_LRG = 0;
T_PLS1 = 0;
}
}
if(millis() - T_PLS1 >= 500 && EST1 == LOW){
T_PLS1 = 0;
}
}
}
void lecturaBTN2(){
if(EST2 == HIGH && T_PLS2 == 0){
T_PLS2 = millis();
}
if(T_PLS2 != 0){
if(millis() - T_PLS2 > 2000){
PLS2_LRG = 1;
if(PLS2_LRG == 1){
activaBTN2();
PLS2_LRG = 0;
T_PLS2 = 0;
}
}
if(millis() - T_PLS2 >= 500 && EST2 == LOW){
T_PLS2 = 0;
}
}
}
void activaBTN1(){
digitalWrite(Led, HIGH);
PLS1_LRG = 0;
delay(3000);
digitalWrite(Led, LOW);
}
void activaBTN2(){
digitalWrite(Led, HIGH);
PLS2_LRG = 0;
delay(3000);
digitalWrite(Led, LOW);
}
void sleep() {
GIMSK |= _BV(PCIE);
PCMSK |= _BV(PCINT1);
PCMSK |= _BV(PCINT2);
ADCSRA &= ~_BV(ADEN); // ADC desactivado
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Reemplaza la declaración anterior
sleep_enable(); // Establece el bit de habilitación de suspención en el registro MCUCR (SE BIT)
sei(); // Habilita las interrupciones
sleep_cpu(); // Dormir
cli(); // Desabilitar las interrupciones
PCMSK &= ~_BV(PCINT1); // Apaga PB2 como pin de interrupción
PCMSK &= ~_BV(PCINT2); // Apaga PB4 como pin de interrupción
sleep_disable(); // Borrar SE bit
ADCSRA |= _BV(ADEN); // ADC activado
sei(); // Habilita interrupciones
} // sleep
ISR(PCINT0_vect) {
}
void loop(){
sleep(); // Si se comenta esta función el código se ejecuta correctamente
EST1 = digitalRead(BTN1);
EST2 = digitalRead(BTN2);
if(AnteriorEstadoPin != EST2){
T_Control = millis() + T_Apagado;
digitalWrite(Led, HIGH);
}
AnteriorEstadoPin = EST2;
if(millis() > T_Control){
digitalWrite(Led, LOW);
T_Control = 0;
}
lecturaBTN1();
lecturaBTN2();
}