Hace tiempo ayudando a un amigo, me vi en la necesidad de usar timer e interrupciones, les cuento, la idea era simple presionar un botón, que iniciara un audio (se usaba un modulo MP3) y a determinados tiempos según la narración encendieran algunos focos. Bueno pude haber usado cualquier método pero decidí realizar un contador de segundos con el TIMER1 y atender su desbordamiento con una interrupción, bueno en este ejemplo solo mostrare la configuración del TIMER, la interrupción y vamos a encender/apagar algunos LEDs cada determinado tiempo.
Circuito:
El diagrama utilizado es sencillo unicamente LEDs con sus debidas resistencias (330 Ohms) conectados desde D3 hasta D12, en D2 he colocado un el botón de inicio.
Código:
El código que hace posible esto es el siguiente:
Descargas:El código que hace posible esto es el siguiente:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************************************* | |
* | |
* Ejemplo basico usando timers e interrupciones | |
* | |
******************************************************************************* | |
* FileName: NANO_Interrupt_test.ino | |
* Processor: ATmega328 | |
* Complier: Arduino v1.8.3 | |
* Author: Pedro Sánchez (MrChunckuee) | |
* Blog: http://mrchunckuee.blogspot.com/ | |
* Email: mrchunckuee.psr@gmail.com | |
* Description: Encender LEDs cada determinado tiempo, usando el TIMER1 | |
******************************************************************************* | |
* Rev. Date Comment | |
* v0.0.0 23/03/2019 Creación del firmware | |
******************************************************************************/ | |
const int button = 2; | |
const int ctrlLed1 = 3; | |
const int ctrlLed2 = 4; | |
const int ctrlLed3 = 5; | |
const int ctrlLed4 = 6; | |
const int ctrlLed5 = 7; | |
const int ctrlLed6 = 8; | |
const int ctrlLed7 = 9; | |
const int ctrlLed8 = 10; | |
const int ctrlLed9 = 11; | |
const int ctrlLed10 = 12; | |
const int ledStatus = 13; | |
unsigned char pinCount; | |
unsigned int buttonState = 0, buttonTicks = 0; | |
unsigned int currentButtonState = 0, lastButtonState = 0; | |
boolean buttonFlag = false, buttonMode = false; | |
unsigned int contador = 0, segundos = 0; | |
// Valor en segundos del conteo | |
// Si se requiere mas tiempo se puede hacer | |
// Este valor pondra fin al conteno del TIMER1 | |
unsigned int tiempoTotal = 120; | |
void setup() { | |
pinMode(button, INPUT); | |
for(pinCount = 3; pinCount <14; pinCount++) | |
pinMode(pinCount, OUTPUT); | |
//Clear all outputs | |
for(pinCount = 3; pinCount <14; pinCount++) | |
digitalWrite(pinCount, LOW); | |
// Se inicializa el TIMER1 | |
TIMER1_Init(); | |
delay(50); | |
} | |
ISR(TIMER1_OVF_vect){ | |
TCNT1 = 49911; // preload timer | |
contador++; | |
if (contador>4){ | |
contador = 0; | |
segundos++; | |
if (segundos>tiempoTotal){ | |
segundos = 0; | |
//Clear all outputs | |
for(pinCount = 3; pinCount <14; pinCount++){ | |
digitalWrite(pinCount, LOW); | |
} | |
TIMER1_Disable(); | |
buttonFlag = false; | |
buttonMode = false; | |
} | |
digitalWrite(ledStatus, digitalRead(ledStatus) ^ 1); | |
} | |
} | |
void GetInput(void){ | |
// Push Button debounce | |
if (buttonState != digitalRead(button)){ | |
if (buttonTicks > 20){ | |
buttonState = digitalRead(button); | |
buttonTicks = 0; | |
} | |
else buttonTicks++; | |
} | |
else buttonTicks = 0; | |
// Process the push button | |
currentButtonState = buttonState; | |
if (currentButtonState == 0 && lastButtonState == 1){ | |
buttonFlag = true; | |
} | |
lastButtonState = currentButtonState; | |
} | |
void TIMER1_Init(void){ | |
/* Consideraciones para el calculo: | |
* T = periodo del timer, f = frecuencia del clock = 16MHz | |
* T = 1/f --> 1/16MHz = 0.0625us | |
* TiempoOverflowTIMER1 = T * (65536 - PreloadTimer) * Prescaler | |
* = 0.0625us * (65536 - 49911) * 256 | |
* = 0.24 segundos | |
*/ | |
cli(); // Stop interrupts | |
TCCR1A = 0; | |
TCCR1B = 0; | |
TCNT1 = 49911; // preload timer 65536-16MHz/256/4Hz | |
TCCR1B |= (1 << CS12); // 256 prescaler | |
sei(); //Allow interrupts | |
} | |
void TIMER1_Enable(void){ | |
// Enable timer overflow interrupt | |
TIMSK1 |= (1 << TOIE1); | |
} | |
void TIMER1_Disable(void){ | |
// Disable timer overflow interrupt | |
TIMSK1 &= ~(1 << TOIE1); | |
} | |
void loop() { | |
GetInput(); | |
if (buttonFlag == true){ | |
if (buttonMode == false){ | |
buttonMode = true; | |
TIMER1_Enable(); | |
} | |
// Puedes encender el LED en el segundo deseado | |
// Puedes apagar el LED en el segundo deseado | |
switch(segundos){ | |
case 2: | |
digitalWrite(ctrlLed10, HIGH); | |
break; | |
case 5: | |
digitalWrite(ctrlLed1, HIGH); | |
break; | |
case 8: | |
digitalWrite(ctrlLed1, LOW); | |
break; | |
case 10: | |
digitalWrite(ctrlLed2, HIGH); | |
break; | |
case 12: | |
digitalWrite(ctrlLed3, HIGH); | |
digitalWrite(ctrlLed4, HIGH); | |
break; | |
case 30: | |
digitalWrite(ctrlLed2, LOW); | |
break; | |
case 45: | |
digitalWrite(ctrlLed3, LOW); | |
break; | |
case 50: | |
digitalWrite(ctrlLed2, LOW); | |
digitalWrite(ctrlLed4, LOW); | |
break; | |
case 61: | |
digitalWrite(ctrlLed5, HIGH); | |
digitalWrite(ctrlLed6, HIGH); | |
break; | |
case 80: | |
digitalWrite(ctrlLed6, LOW); | |
break; | |
case 89: | |
digitalWrite(ctrlLed5, LOW); | |
break; | |
case 90: | |
digitalWrite(ctrlLed7, HIGH); | |
digitalWrite(ctrlLed8, HIGH); | |
break; | |
case 100: | |
digitalWrite(ctrlLed9, HIGH); | |
break; | |
case 105: | |
digitalWrite(ctrlLed8, LOW); | |
break; | |
case 110: | |
digitalWrite(ctrlLed7, LOW); | |
digitalWrite(ctrlLed9, LOW); | |
break; | |
case 112: | |
for(pinCount = 3; pinCount <14; pinCount++) | |
digitalWrite(pinCount, HIGH); | |
break; | |
case 118: | |
for(pinCount = 3; pinCount <14; pinCount++) | |
digitalWrite(pinCount, LOW); | |
break; | |
default: | |
break; | |
} | |
} | |
} |
Aquí el enlace directo para DESCARGAR los archivos disponibles, también puedes revisar o descargar la información desde mi repositorio en GitHub, si no sabes como descargarlo puedes checar aquí, bueno por el momento es todo si tienes dudas, comentarios, sugerencias, inquietudes, traumas, etc. dejarlas y tratare de responder lo mas pronto posible.
Donaciones:
Si te gusta el contenido o si los recursos te son de utilidad, comparte el enlace en tus redes sociales o sitios donde creas que puede ser de interés y la otra puedes ayudarme con una donación para seguir realizando publicaciones y mejorar el contenido del sitio. También puedes hacer donaciones en especie, ya sea con componentes, tarjetas de desarrollo o herramientas. Ponte en contacto para platicar, o puedes volverte uno de nuestros sponsors.
Pido una retroalimentación avisando cada que un enlace no sirva o tenga errores al momento de abrirlo, así también si una imagen no se ve o no carga, para corregirlo en el menor tiempo posible.
- Microchip, "ATmega328P", https://www.microchip.com/wwwproducts/en/ATmega328p
- Engblaze, "Microcontroller tutorial series: AVR and Arduino timer interrupts", http://www.engblaze.com/microcontroller-tutorial-avr-and-arduino-timer-interrupts/
- Robotfreak en RobotShop Community, "Arduino 101: Timers and Interrupts", https://www.robotshop.com/community/forum/t/arduino-101-timers-and-interrupts/13072
0 Comentarios