Código en Arduino. Varios modos con memoria.
Ahora el siguiente paso es que el driver tenga varios modos. Como sabemos, en algunas de nuestras linternas el cambio de modo ocurre de la siguiente forma. Si apagamos y encendemos rápido, la linterna pasa al siguiente modo. Si dejamos la linterna encendida en un modo más de un determinado tiempo, ese modo queda memorizado para la próxima vez.
Por tanto, debemos guardar el modo en el que se debe encender la linterna en una memoria no volátil, que no se borre al perder la alimentación el chip (apagar la linterna). Esa memoria se llama EEPROM. Y, por tanto, la palabra EEPROM aparecerá en el código de Arduino cuando escribamos o leamos la memoria EEPROM.
En Arduino escribir y leer en la memoria EEPROM es muy fácil:
EEPROM.write(posición_memoria, nombre_variable) guarda en la posición de memoria “posición_memoria” la variable ”nombre_variable”.
El Attiny13 tiene 64 posiciones de memoria. En cada una de ellas puede grabar un byte. Es decir, un valor entre 0 y 255.
EEPROM.read(posición_memoria) lee el valor que hay (de 0 a 255) en la posición “posición_memoria”
Con estas dos instrucciones puedes entender el código que sigue, más complejo que los anteriores, pero ya tenemos un programa REAL para un driver. Un poco de esfuerzo que vale la pena... insisto que lo que sigue es ya un programa como los que llevan los drivers que compramos.
Vamos a mostrar el código para un driver con tres modos: alto, medio y flash. Con memoria del último modo, si lleva más de time_memory milisegundos en ese modo.
El código sigue a continuación:
//PROGRAMA CON TRES MODOS Y MEMORIA ÚLTIMO MODO
#include //incluye una librería para poder escribir leer en EEPROM
#define ledpin 1
#define time_memory 3000 //esto es el tiempo en milisegundos que está encendida
//la linterna para que se guarde el modo actual. Si la apagas antes de ese tiempo,
//se encenderá en el modo siguiente
//la siguiente variable, mode, es el modo en el que está la linterna: alto = 1, medio = 2, ...
byte mode;
//el valor mínimo de mode es 1, el máximo es maxmodereal
#define maxmodereal 3 //indicamos aquí que hay 3 modos. Cambiar si hya más o menos
//la siguiente variable, guardamode, indica que modo de los que hay se guarda en EEPROM
//puede ser el modo siguiente (si han pasado menos de time_memory milisegundos)
//o el actual en caso contrario
byte guardamode; //modo a guardar en la memoria EEPEOM
boolean primer1 = false; //variable false/true para grabar en EEPROM. Empieza siendo false.
boolean primer2 = false; //variable false/true para grabar en EEPROM. Empieza siendo false.
unsigned long int time_on; //time_on es el tiempo em milisengundos cuando se enciende linterna
unsigned long int time_now; //time_now tiempo en milisendos actual, para grabar o no el modo actual
void setup() { //solo se hace al principio de encender la linterna
pinMode(ledpin, OUTPUT); //indicamos que el control del led esta en salida digital número 1
time_on = millis(); //guarda el tiempo en milisegundos cuando se enciende la linterna
mode = EEPROM.read(1); // antes de encender la linterna lee modo a utilizar desde memoria
// y lo guarda en variable mode.
if (mode == 0) {mode = 1;} //la primera vez que utilicemos la linterna después
//de haber programado el driver, el contenido de la toda la EEPROM está a cero.
//Esta línea solo hace falta esa pimera vez.
//En ese caso, como es cero lo convertimos a uno, para que empiece en el primer modo
//si no se enciende, no hay mode 0.
//Otra solución es que el primer modo sea el 0.
}//fin setup()
//a continuación lo que se repite una y otra vez
void loop() {
if (primer1 == false) {//lo siguiente sólo se hace una vez, cuando primer1 == false.
guardamode = mode +1; //en principio se guardará en memoria el
//sigiente modo, modo+1, salvo que pasen time_memory milisegundos, entonces se
//guardaría el modo actual. Eso se hace al final de este código
if (guardamode > maxmodereal) {guardamode = 1;}
//Como cada vez que apagumeos y encendeamos rápido aumenta el valor de guardamode,
//al final nos pasaremos del límite. En ese caso, empezamos otra vez desde el modo 1
EEPROM.write(1, guardamode); //guarda el mode siguiente al actual.
//Por tanto, la próxima vez que encendamos la linterna estará en el siguiente modo
primer1 = true;} //una vez hecho, ya no hay que hacerlo más. Hacemos primer1 = true
//siguen la descripción de los modos
if (mode == 1) {digitalWrite(ledpin, 255);} //modo 1 es alto, high.
if (mode == 2) {analogWrite(ledpin, 127);} //modo medio, 50% amperaje
if (mode == 3) //flash a un tercio de la potencia, amperaje
{ analogWrite(ledpin, 85); delay(500); analogWrite(ledpin, 0); delay(500); }
//a continuación se guarda el modo actual, NO EL SIGUIENTE, si han pasado más de
//time_memory milisegundos
if (primer2 == false) {//sólo se va a ejecutar una vez pasados los time_memory milisegundos
time_now = millis(); //hora actual en milisegundos
if ((time_now - time_on) > time_memory) //si han pasado más de time_memory milisegundos
{EEPROM.write(1, mode); //escribe en la posicion 1 el modo actual (no el siguiente)
//sobre escribimos lo que antes habíamos escrito, que era mode+1
primer2 = true;} // ya no se hace más esta parte del código, para que no repita
}
}
El programa está bastante comentado y es fácil seguir lo que hace y está pensado para que cualquiera pueda ajustarlo a sus necesidades.
Lo que se puede cambiar muy fácilmente es:
* Valor de maxmodereal. Está puesto a 3 porque hay tres modos. Si pones más o menos modos hay que cambiarlo.
* Valor de time_memory. Tiempo sin cambiar de modo para que se guarde en memoria. Está en el código fijado a 3 segundos.
* La definición de los tres modos.
Si eres capaz de entender ese programa, enhorabuena, ya podrás diseñar tus programas. Si no entiendes algo, ¡pregunta!
El código sin comentarios:
//PROGRAMA CON TRES MODOS Y MEMORIA ÚLTIMO MODO
#include
#define ledpin 1
#define time_memory 3000
byte mode;
#define maxmodereal 3
byte guardamode;
boolean primer1 = false;
boolean primer2 = false;
unsigned long int time_on;
unsigned long int time_now;
void setup() {
pinMode(ledpin, OUTPUT);
time_on = millis();
mode = EEPROM.read(1);
if (mode == 0) {mode = 1;}
}
void loop() {
if (primer1 == false) {
guardamode = mode +1;
if (guardamode > maxmodereal) {guardamode = 1;}
EEPROM.write(1, guardamode);
primer1 = true;}
if (mode == 1) {digitalWrite(ledpin, 255);}
if (mode == 2) {analogWrite(ledpin, 127);}
if (mode == 3)
{ analogWrite(ledpin, 85); delay(500); analogWrite(ledpin, 0); delay(500); }
if (primer2 == false) {
time_now = millis();
if ((time_now - time_on) > time_memory)
{EEPROM.write(1, mode);
primer2 = true;}
}
}
Este código se compila en 818 bytes, de los 1024 disponibles.