¿Arduino puede guardar valores de variables que retome luego de un apagado?

Hola, con un teclado matricial le ingreso valores al Arduino y este a un LCD 20x4.

Esos valores serian rangos de funcionamiento, min y max guardados en una variable.

Por ejemplo...si yo le coloco esos rangos, el sistema funciona y luego de un rato lo apago.

Luego de apagarlo...sean minutos, horas, dias etc, lo vuelvo a encender...el Arduino con su

programacion...¿Puede recordar esos ultimos valores dados y seguir funcionando?

De esa forma con cada apagado no se estarian volviendo a colocar ese rango de min y max, que es lo

que quiero.

Gracias.

Claro. Puedes guardar esos parámetros en la memoria EEPROM, y cargar dichos valores en el setup de tu programa.

GRACIAS CHE, PERO SI LUEGO QUIERO MODIFICAR ESOS VALORES DE MAX Y MIN Y GUARDARLOS EN LA EEPROM...MODIFICARLOS SERIA EN EL VOID LOOP, PERO RETORMARLOS LUEGO DE UN APAGADO SERIA EN EL VOID SETUP?

YO NO QUIERO QUE ESOS VALORES SE USEN CONTINUAMENTE LLAMANDO A LA EEPROM, SINO SOLO GUARDAR LOS ULTIMOS INGRESADOS Y USARLOS CONTINUAMENTE PERO EN FORMA DE VARIABLE Y NO LLAMAR A LA EEPROM A CADA RATO PORQUE LEI QUE CONSUME MUCHA MEMORIA DE PROGRAMA.

CORREGIME SINO ES CIERTO POR FAVOR.

No la eeprom solo caduca, creo que solo tiene 100000 ciclos de lectura escritura y luego muere.

Bueno; más concretamente creo que tiene unos cien mil ciclos de borrado/escritura o para entendernos, de escritura. Lecturas puedes hacer las que quieras. El problema con la EEPROM es que no puedes utilizarla como si fuera una memoria RAM. Hay que asegurarse de que tu programa no va a realizar escrituras alegremente. Por lo demás, para guardar parámetros de setup de aplicaciones es óptimo, si van a ser parámetros relativamente estables. Por ejemplo, si vamos a grabar unas 100 veces al día, nuestra eeprom durará unos mil días (3 años aprox).

Gracias noter, muy buena tu respuesta...entonces me sobra tiempo porque solo de vez en cuando se cambiarian esos valores para guardarlos en la EEPROM.

Pero creo yo que no respondieron mi pregunta principal...creo eh, sino disculpen.

Aca se las dejo.

SI QUIERO MODIFICAR ESOS VALORES DE MAX Y MIN Y GUARDARLOS EN LA EEPROM...MODIFICARLOS SERIA EN EL VOID LOOP, PERO RETORMARLOS LUEGO DE UN APAGADO SERIA EN EL VOID SETUP?

Normalmente esos parámetros los vas a cargar en el setup, y normalmente los vas a guardar cuando desde el loop se llame a la función determinada sólo cuando se modifique el valor (al aceptar un determinado menú de modificación de datos, por ejemplo). Esto último es muy importante, porque si por casualidad lo dejas en el loop, de forma que escriba en EEPROM aunque no se haya modificado el valor, llegarás a los 100.000 borrados enseguida. Osea que tienes que asegurarte de que tu programa sólo escribe la EEPROM cuando es necesario.

1 Like

Gracias, y alguna forma de evitar eso, un ejemplo, un codigo, una pagina, etc. Porque no me quiero mandar la macana y luego tener que usar otro arduino. Yo busque y no encuentro exactamente esa info, si vos sabes de algo...

Te pido ese ultimo favor...ya me ayudaste bastante.

IRRA:
Gracias, y alguna forma de evitar eso, un ejemplo, un codigo, una pagina, etc. Porque no me quiero mandar la macana y luego tener que usar otro arduino. Yo busque y no encuentro exactamente esa info, si vos sabes de algo...

Te pido ese ultimo favor...ya me ayudaste bastante.

void actualizaValores(){
  // Codigo que actualiza los valores
}
void setup(){
  // Codigo
}
void loop(){
  if (condicion ) {
    actualizaValores();
  }
}

dentro del loop evaluas la condicion segun la cual quieras que se actualicen los valores,si se cumple esa condicion ,llamas a la funcion que se encarga de actualizar los valores.

Habría que mirar tu código concretamente para decirte cómo ubicarlo; pero te paso un par de funciones que diseñé para alguna aplicación mía y que creo que son adaptables a cualquier configuración que necesite un programa. Tan sólo debes definir tu propia estructura de configuración con todas las variables que necesites guardar y recuperar de eeprom.

#include <EEPROM.h>

// En esta estructura definiremos todos los parámetros de configuración de nuestra aplicación.
// Admite datos de cualquier tipo nativo y arrays, pero no punteros (por ejemplo char *)
struct {
  int max;
  int min;
}
parametros;

// Esta función cargará los parámetros guardados en la eeprom a nuestra variable parametros
void cargaParams(){
  byte *p= (byte*)  &parametros;
  for(int x=0; x<sizeof(parametros); x++) {
    *p++=EEPROM.read(x);
  }
}

// Esta función guardará nuestros parámetros en la eeprom
void salvaParams(){
  byte *p= (byte*) &parametros;
  for(int x=0;x<sizeof(parametros);x++) {
    EEPROM.write(x,*p++);
  }
}

Obviamente, deberás llamar en tu setup a la función cargaParams, y tu estructura se llenará con los datos almacenados en la eeprom (la primera vez estarán a cero y los tendrás que definir, claro). En cuanto a la otra función, lo lógico es que no va a ir en el loop de manera que se la llame cada vez que se pasa por ahí, sino en la función encargada del menú que gestiona dichos valores, cuando pulsemos el OK tras haber modificado algún parámetro, o incluso hacer un menú especifico "guardar configuración" y llamarla desde ahí (en ese caso, si modificas y no salvas configuración, el programa seguirá trabajando con los nuevos parámetros, pero si se resetea volverá a los últimos guardados).

1 Like

Hola, retomando de nuevo este tema que todavia no es muy viejo...aca dejo mi codigo y con la pregunta ahora...DONDE Y COMO COLOCO LA ESCRITURA Y LA LECTURA DE LA MEMORIA EEPROM?

Me pasa que quiero escribir en la memoria 2 valores en dos direcciones distintas de esta al pulsar un boton de un teclado matricial. Esos 2 valores al mismo tiempo se muestran en una pantalla de un LCD. Y luego esos valores se leen despues de un apagado, mostrandome directamente la anterior pantalla del LCD pero con esos 2 valores guardados como maximo y minimo de temperaturas (pantalla "EN FUNCIONAMIENTO...").

No se como ubicar en el programa los pedazos de codigos:

EEPROM.write(direccion, valorA);
EEPROM.write(direccion+1, valorB);

valMax = EEPROM.read(direccion);
valMin = EEPROM.read(direccion + 1);
[code]

Necesito ubicarlos para que luego de un nuevo encendido se muestren directamente en la pantalla LCD y funcionen como valores max y min, sin tener que tener ingresarlos con cada encendido y funcionando como si le hubiera ingresado de nuevo esos valores. Espero haber sido claro, gracias.

Aca dejo el resto de mi codigo:

#include <EEPROM.h>
#include <Keypad.h>          //libreria para controlar el teclado matricial
#include <LiquidCrystal.h>   //libreria para controlar el LCD
/////////////////////////////////////////////////////////////////////////////////
//Configuración del teclado matricial

const byte filas = 4;                            // numero de filas a usar
const byte columnas = 4;                          // numero de columnas a usar
byte pinsFilas[filas] = {22, 23, 24, 25};          // orden de conexion de filas: Fila 1, Fila 2, Fila 3 y Fila 4
byte pinsColumnas[columnas] = {26, 27, 28, 29};    // orden de conexion de columnas: Columna 1, Columna 2, Columna 3 y Columna 4

char teclas[filas][columnas] = {  //matriz teclas para definir orden de caracteres tal cual en el teclado
  {'7', '8', '9', 'A'},
  {'4', '5', '6', 'B'},
  {'1', '2', '3', ' '},
  {'0', ' ', ' ', 'D'},
};
Keypad keypad = Keypad(makeKeymap(teclas), pinsFilas, pinsColumnas, filas, columnas);  //se mapean teclas

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuración para el LCD

// Puertos LCD -> RS  E   D4  D5  D6  D7
LiquidCrystal lcd(32, 33, 34, 35, 36, 37);

//////////////////////////////////////////////////////////////////////////////////////////
const int sensor = 0; // entrada del sensor LM35
const int backlight = 38;   // pin digital LED del LCD
const int ledAzul = 42;     // pin digital LED azul
const int ledVerde = 43;    // pin digital LED verde
const int ledRojo = 44;     // pin digital LED rojo
const int buzzer = 45;      // pin digital buzzer
const int transistor1 = 52; // pin digital transistor 1
const int transistor2 = 53; // pin digital transistor 2

///////////////////////////////////////////////////////////////////////////////////////
char numero;             //variable "char numero" de tipo caracteres
int  valorA;             //variables para mostrar numeros en LCD
int  valorB;

int contador;            //variables "contador" para separar procesos
int contador2 = 0;
int contador3;

int decenaA;     //variables "decena" para definir decenas
int decenaB;
int unidadA;     //variables "unidad" para definir unidades
int unidadB;

int cicloA;      //variables "ciclo" que comienzan procesos
int cicloB;

int tmax;
int tmin;

int direccion = 0;

byte valMax;
byte valMin;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float centigrados()                    //se calcula como variable decimal "coma flotante"
{
  int sensor;                          //de acuerdo a la variable del sensor
  float celsius;                        //se crea una variable resultado decimal
  sensor = analogRead(A0);              //se lee el estado de la entrada analogica A0 donde esta el sensor
  celsius = ((500.0 * sensor) / 1023) - 10;    //se realiza el calculo
  return (celsius);                    //se devuelve el resultado a la variable decimal "celsius"
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ES ESTA PARTE LA QUE NO SE COMO UBICAR EN EL PROGRAMA.
void actualizarValores() {
  EEPROM.write(direccion, valorA);
  EEPROM.write(direccion+1, valorB);
}
  valMax = EEPROM.read(direccion);
  valMin = EEPROM.read(direccion + 1);


///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {                  //se definen como salidas las conexiones a pines digitales
  pinMode(backlight, OUTPUT);
  pinMode(ledAzul, OUTPUT);
  pinMode(ledVerde, OUTPUT);
  pinMode(ledRojo, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(transistor1, OUTPUT);
  pinMode(transistor2, OUTPUT);
  
  delay(500);                        //pausa antes del encendido
  digitalWrite(backlight, HIGH);    //encender backlight
  delay(500);                       //pausa antes de primera pantalla para que se muestre prolijamente
  digitalWrite(ledVerde, HIGH);
  lcd.begin(20, 4);                 //inicio de uso de LCD de 20x4
  lcd.setCursor(3, 1);              //posicionar cursor en columna 3 y fila 1
  lcd.print("BIENVENIDO/A A");      //escribir texto en LCD
  lcd.setCursor(1, 2);
  lcd.print("TECMATEMP LCDMR 35");
  digitalWrite(buzzer, HIGH);       //encender buzzer
  delay(1000);                      //pausa de 1 seg encendido
  digitalWrite(buzzer, LOW);        //apagar buzzer
  delay(4000);                      //esperar 9 seg antes del void loop
  lcd.clear();                      //limpiar pantalla
  delay(100);                        //pausa para pasar a otra pantalla prolijamente
  lcd.setCursor(0, 0);
  lcd.print("SIN VALORES LIMITES!");
  
  
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  
  float temperatura = centigrados();      //se iguala variable temperatura a variable centigrados
  lcd.setCursor(0, 2);                    //posicionar texto en columna 0 y fila 2
  lcd.print("TEMP.ACTUAL       ^C");       //escribir texto en LCD
  lcd.setCursor(13, 2);
  lcd.print(temperatura);                  //mostrar resultado de temperatura mas arriba
  delay(300);

  ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  char teclas = keypad.getKey();  //Guarda en la variable "teclas" el valor pulsado del teclado

  if (teclas != NO_KEY) {             //Si se ha pulsado una tecla
    numero = teclas - 48;            //conversión de caracteres ASCII a valores numericos
    digitalWrite(backlight, HIGH);
    digitalWrite(buzzer, HIGH);
    delay(50);
    digitalWrite(buzzer, LOW);

    //PROCESO AL PULSAR BOTON A (INSERTAR VALOR MAX) (TECLA F6)
    if (numero == 17) {                      //Si se pulsa la tecla A entonces (valor ascii A es en valor numerico 17)
      digitalWrite(ledVerde, LOW);
      lcd.clear();                        //Se limpia la pantalla del LCD
      delay(100);                          //pausa para pasar a otra pantalla
      lcd.setCursor(0, 0);                   //se ajusta el cursor del LCD
      lcd.print("INGRESE VAL.MAX.(F6)");           //se muestra texto en LCD
      lcd.setCursor(5, 1);
      lcd.print("(0.....99)");
      lcd.setCursor(8, 3);
      lcd.print("  ^C");
      cicloA = 1;                         //El "cicloA" será igual a 1
      numero = -1;                    //la variable "numero" comienza en -1
      contador = 0;                       //Se iguala la variable "contador" a 0
    }
    else {//PROCESO AL PULSAR BOTON B (INSERTAR VALOR MIN (TECLA F5)
      if (numero == 18) {             //Si se pulsa la tecla B entonces
        digitalWrite(ledVerde, LOW);
        lcd.clear();                  //Se limpia la pantalla
        delay(100);                    //pausa para pasar a otra pantalla
        lcd.setCursor(0, 0);               //se ajusta el cursor
        lcd.print("INGRESE VAL.MIN.(F5)");
        lcd.setCursor(5, 1);            //Se ajusta el cursor a una determinada posición
        lcd.print("(0.....99)");        //mostrar texto en LCD
        lcd.setCursor(8, 3);                //posicionar cursor del LCD
        lcd.print("  ^C");                   //escribir textos
        cicloB = 1;                       //El cicloB será igual a 1
        numero = -1;                      //variable char numero se iguala a -1
        contador = 0;                   //Se iguala la variable "contador" a cero
      }
    }
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if (cicloA == 1) {                       //Si el "cicloA = 1", indica que se presiono la tecla A o F6

      if (numero >= 0 && contador == 0) {       //Si se presiona un boton del teclado y si el "contador = 0" entonces
        decenaA = numero;                   //Se iguala el valor tecleado a la variable "decenaA"
        lcd.setCursor(8, 3);
        lcd.print(decenaA);
        contador++;                       //Se incrementa el valor del "contador" a 1
        numero = -1;                    //la variable "numero" comienza en -1
        delay(50);
      }
      if (numero >= 0 && contador == 1) {          //Si se presiona una digito y contador=1 entonces
        unidadA = numero;                       //Se iguala el valor tecleado a la variable "unidadA"
        lcd.setCursor(9, 3);
        lcd.print(unidadA);
        contador++;                           //Se incrementa al valor del contador a 2
        numero = -1;                          //la variable numero comienza en -1
        delay(50);

        valorA = (decenaA * 10) + unidadA;
        tmax = valorA;
      }
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if (cicloB == 1) { //Si cicloB = 1, indica que se presiono la tecla B

      if (numero >= 0 && contador == 0) {            //Si se presiona una digito y contador=0 entonces
        decenaB = numero;                           //Se iguala el valor tecleado a la variable "decenaB"
        lcd.setCursor(8, 3);
        lcd.print(decenaB);
        contador++;                                  //Se incrementa al valor del contador a 1
        numero = -1;                                //variable char numero se iguala a -1
        delay(50);
      }

      if (numero >= 0 && contador == 1) {        //Si se presiona una digito y contador=1 entonces
        unidadB = numero;                       //Se iguala el valor tecleado a la variable "unidadB"
        lcd.setCursor(9, 3);
        lcd.print(unidadB);
        contador++;                            //Se incrementa al valor del contador a 2
        numero = -1;                            //variable char numero se iguala a -1
        delay(50);

        valorB = (decenaB * 10) + unidadB;
        tmin = valorB;
      }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////
    //PROCESO AL PULSAR EL BOTON D (ENTER) (F3)
    if (numero == 20) {                           //si se pulsa la tecla D entonces
      digitalWrite(ledVerde, HIGH);                  //encender led verde
      lcd.clear();                                //limpiar pantalla
      delay(100);
      lcd.setCursor(0, 0);                      //posicionar cursor en columna 0 y fila 0
      lcd.print("EN FUNCIONAMIENTO...");        //escribir texto en LCD
      lcd.setCursor(0, 1);                      //posicionar cursor en columna 0 y fila 1
      lcd.print("TEMP.MAX          ^C");       //escribir texto en LCD
      lcd.setCursor(16, 1);
      lcd.print(valorA);                        //mostrar valorA maximo en LCD
      lcd.setCursor(0, 3);                    //posicionar texto en columna 0 y fila 3
      lcd.print("TEMP.MIN          ^C");       //escribir texto en LCD
      lcd.setCursor(16, 3);
      lcd.print(valorB);
      actualizarValores();
    }
  }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if (temperatura >= tmax) {                //si el valor de temperatura es mayor o igual al valorA
    digitalWrite(ledAzul, LOW);                //apagar led azul
    digitalWrite(ledRojo, HIGH);                //encender led rojo
    digitalWrite(transistor2, HIGH);              //encender transistor 2
  }
  else {
    digitalWrite(ledRojo, LOW);              //apagar led azul
    digitalWrite(transistor2, LOW);           //apagar transistor 1
  }

  if (temperatura <= tmin) {            //si el valor de temperatura es mayor o igual al valorB
    digitalWrite(ledRojo, LOW);              //apagar led rojo
    digitalWrite(ledAzul, HIGH);            //encender led azul
    digitalWrite(transistor1, HIGH);        //encender transistor 1
  }
  else {
    digitalWrite(ledAzul, LOW);              //apagar led azul
    digitalWrite(transistor1, LOW);           //apagar transistor 1
  }
}