Go Down

Topic: almacenar en eeprom funciona pero con detalle ¿ cual es la mejor forma? (Read 315 times) previous topic - next topic

candres

hola.
despues de leer varios posts publico mi duda

necesito guardar un entero en una eeprom cuando recibo la señal desde un pulsador, el codigo que estoy usando es el siguiente, en este caso uso el monitor serial para que lo puedan probar...si quieren.

Code: [Select]

#include <EEPROM.h>
int option;
int led = 13;
int cont = 0;
int B = 0;
byte L;
byte H;
int direccion = 0;
 
void setup(){
 
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  L=EEPROM.read(direccion);
  H=EEPROM.read(direccion + 1);
  B = (L<<8) | H;
  cont = B;
  Serial.println(cont);
}
 
void loop(){
  H = highByte(cont);
  L = lowByte(cont);
  //si existe datos disponibles los leemos
  if (Serial.available()>0){
    //leemos la opcion enviada
    option=Serial.read();
    if(option=='a') {
      cont++;
      EEPROM.write(direccion, H);
      EEPROM.write(direccion + 1, L);
      Serial.println(cont);
    }
  }
}


el problema es que si tengo como cuenta 35 me guarda el 34 en la eeprom no se en que estoy fallando


ademas si alguien me puede decir si es la manera correcto de hacerlo o el codigo esta funcionando de "milagro" lo agradecería

ademas si alguien puede aclarar si es cierto como dice en otro post que la eeprom dura 100.000 ciclos de lectura escritura.

alguien a usado la libreria EEPROMAnything , porque lo intente pero sin exito.

gracias



victorjam

Code: [Select]

B = (L<<8) | H;


Observa lo que hace esa línea de tu código. Cuando lees la eeprom, la parte baja L la desplazas 8 lugares a la izquierda y le hacer un OR con la parte alta: estas poniendo los bytes alrevés.

Lo mismo te ocurre con el orden de escritura/lectura. Si guardas L primero, debes leer L primero. Y en tu código lo tienes remezclado.

Atmel en su datasheet te garantiza que el atmega328 puede hacer 100.000 ciclos de borrado/escritura de la memoria eeprom. A partir de esos 100k, puede que funciona la eeprom o no. No es aconsejable escribir la eeprom siempre (como en tu caso cada vez que recibe "a" por el serial, a no ser que se reciba muy poco o casi nunca). Su uso general es para guardar datos de configuración, o variables que no queremos perder si apagamos el arduino.

En cuanto a la libreria que mencionas, ni idea, ni siquiera uso EEPROM, programo con las funciones básicas que hay en <avr/eeperom.h> que son las que utiliza EEPROM.

msoffredi

Además de lo ya explicado, tal vez te convenga usar EEPROM.put() y EEPROM.get() para simplificar, ya que pueden manejar enteros directamente...

https://www.arduino.cc/en/Reference/EEPROMPut

--------------------
Marcelo
arduinohobby.com

Metaconta

Hola:

Consejos sobre EEPROM.

1) Si vas a usar mucho la EEPROM interna para configuración cada vez que usa el AVR o Arduino, usa todo en la RAM. Hay trucos que si apagas la alimentación, apagas todo el dispositivo menos el microcontrolador para que le de tiempo a guardar los datos en la EEPROM interna, necesitas unos buenos condensadores para dejar más de un segundo el microcontrolador activo. Requiere más electrónica.

2) Cada cierto tiempo, usas dirección de memoria diferente para guardar los datos en la EEPROM interna, así te durará mucho más.

3) Usar una EEPROM externa, sea protocolo I2C o ISP (más rápido). Nunca usar la EEPROM interna. Si te falla la EEPROM, puedes cambiarla físicamente por otra y se acabó. También puedes ponerle una opción al AVR de que cuando pase un tiempo o escrituras indicadas, empiece a grabar en la EEPROM interna del AVR con el aviso en el LCD que debes cambiar la EEPROM externa por seguridad. 24LC256.

4) La EEPROM interna suele ser para configuración. Por ejemplo, en un TV, hay dos formas de guardar información. O usa una misma EEPROM que tiene el firmware del sistema operativo del TV que a mi personalmente el TV será más barato pero en el futuro esto te fallará, la opción más completa y algo más cara, hay dos EEPROM, la del Firmware que solo se actualiza por internet, USB y se queda ahí y tiene una EEPROM más pequeña tipo 24LC256 por nombrar alguno donde guarda la información de los canales buscados, el nivel de volumen donde lo haz dejado, brillo, color, idioma, etc.

Todo esto es para que te hagas una idea.

Saludos.

candres

gracias por la información .

lo del eeprom.put me sirve por ahora.

pero el punto 1) del que habla el usuario METACONTA, si pudiera poner un enlace o alguna pista para buscar mas informacion seria genial ya que la idea de usar la eeprom es para cuando se corta la energia electrica , ya que el arduino estara en un lugar semi-rural (campo).

gracias

nota :
por si alguien entra a este post , en el siguiente post salia la libreria EEPROMAnything.h, un moderador del foro hablaba de ella

http://forum.arduino.cc/index.php?topic=290518.0


ojala METACONTA escriba algo mas de ese punto 1. gracias

Lucario448

pero el punto 1) del que habla el usuario METACONTA, si pudiera poner un enlace o alguna pista para buscar mas informacion seria genial ya que la idea de usar la eeprom es para cuando se corta la energia electrica , ya que el arduino estara en un lugar semi-rural (campo).
Yo sé a qué se refiere, sin embargo requiere del pin 2 o 3.

Hola:

Consejos sobre EEPROM.

1)Hay trucos que si apagas la alimentación, apagas todo el dispositivo menos el microcontrolador para que le de tiempo a guardar los datos en la EEPROM interna, necesitas unos buenos condensadores para dejar más de un segundo el microcontrolador activo. Requiere más electrónica.
Condensador de al menos 1000 uF en los pines 5v y GND. Ojo que no puede ser de un valor muy alto porque el pico de intensidad de corriente que se genera al cargar este condensador (equivalente a un corto circuito que dura unos cuantos milisegundos) podría disparar algún fusible que tenga la placa; esto sólo aplica para la alimentación desde USB.
El condensador debe estar aislado de cualquier otra carga adicional (preferiblemente no conectar nada más que el pin positivo del condensador en 5v); de lo contrario la descarga se torna tan rápida que el microcontrolador no alcanzaría a guardar nada (o a medias). Aumentar la capacitancia incrementa el riesgo de disparar fusibles en el arranque.

Entre la salida (línea de voltaje positivo) y la entrada del Arduino, debe ir un diodo con la franja apuntando hacía el Arduino. La idea es que cuando cortemos la fuente, el condensador no se descargue hacia nuestro "sensor de apagado".
El "sensor de apagado" es un cable que sale desde entre la salida positiva de la fuente (asumiendo que es de 5v) y el diodo, y que llega al pin 2 o 3 del Arduino. El pin 2 o 3 también debe estar conectado a una resistencia de 10k que va a tierra; es el famoso "pull-down".

La idea de usar uno de estos pines del Arduino, es para disparar una interrupción cuando el voltaje cae a menos de 3v (o mejor dicho: apenas desconectemos la fuente de poder). Esta interrupción es la que va a mandar a escribir en la EEPROM:

Code: [Select]
void setup() {
  pinMode(2, INPUT);
  // El resto de configuraciones iniciales
  attachInterrupt(0, FALLING, guardarAhora); // 0 = pin 2; 1 = pin 3
}

void guardarAhora() {
  PORTB = PORTD = PORTC = 0; // Ahorremos la poca energía que entrega un condensador, apagando todos los pines

  // Guardar lo que haga falta, ¡pero rápido! ¡Sin demora!

  while(1); // Bloquear el programa; no tiene sentido seguir ejecutando si de todas formas se va a apagar.
  // Sin embargo, en caso de falsa alarma, esto podría ser perjudicial ya que la única forma de salir es con el botón de Reset
  // Bloquear la ejecución queda a discreción del desarrollador.
}

Metaconta

Buenas campeones:

Si te fijas en los TV, al desenchufarlo, sigue el Led rojo encendido durante mucho tiempo, demasiado para mi gusto, hasta casi el minuto.

Lo que tiene que hacer el microcontrolador, que antes lo hacía con PIC, pero el AVR se puede hacer con la misma técnica.

Usaba dos condensadores en mi época del 2008 con el PIC16F84A. Un condensador electrolítico de 2200 uF / 63 V (es el que nos dieron el profesor) y otro de carga rápida en paralelo que no recuerdo sus valores pero no era electrolítico. Tenía que cargar tensión como máximo de 24 VDC.

A la hora de descargar el condensador se reduce su tensión de 24 V. a 0 V. Su velocidad era casi menos de 1 segundo y no valía en el cual puse una resistencia.

Básicamente usaba circuito RC similar a este para el PIC, que puedes hacer con ARV o ARM de la placas de Arduino.



1) En un pin de entrada digital del uC detecta directamente que ha perdido la alimentación principal.

2) Como le puse una resistencia al condensador para ampliar el tiempo del uC encendido, el pin detecta a nivel 0 V, en el LCD sin luz de fondo indica mensaje:

Power OFF

3) Lo que hace el programa hecho en asm en su día con el PIC16F84A es, simplemente ignorar los piens de entrada y de salida menos el que detecta la fuente de alimentación y solo sale un mensaje de texto en el LCD. Antes usaba un Led rojo en vez del LCD.

4) Aunque venga la fuente de alimentación otra vez, lo ignora.

5)
Todo lo que tenga en la RAM, se pasa a la EEPROM interna, también vale para la EEPROM externa si lo desea pero nunca lo he probado. Lo se por lógica.

Lo hice tal cual indico arriba. Sin embargo, lo haría de otra manera, configurar mediante un PIC que si vuelve la alimentación, funcione el uC otra vez. Solo lo dejaba bloqueado.



Saludos.

Go Up