Cuenta atras con lcd

Hola, primero presentarme al foro, soy nuevo y estoy empezando con arduino.

Os cuento mi proyecto y haber si me podéis echar una mano.

Quiero hacer un contador que cuente hacia atrás. Ejemplo tipo maquinitas, que cuando recibe un pulso por una entrada agregue x tiempo y empiece a contar hacia atrás, y cuando llegue a 0 en la salida xx pase a tener otro valor.

Esto parece sencillo, pero necesito ciertas características que me trae un poco loco por qué no sé por dónde meter mano.
1 el tiempo se debe de guardar si se corta la luz, cada minuto que se guarde: ejemplo, el contado marca 10minutos, cuando pasa a 9 se guarda si se va la luz el contador empieza a contar desde 9 hacia atrás..

2 tener un menú donde configurar el tiempo: cada pulsación 10minutos, o 15minutos, o el valor que queramos.

3 ver todas las pulsaciones que se han producido. Ejemplo: ver pulsaciones 100 veces

4 poder borrar esas pulsaciones: poner a 0 esas pulsaciones, para cuando quiera volver a solicitar el punto 3 me aparezca.

Todo esto se mostrara por un display.

Bueno espero que pronto pueda poner algo de código para que me ayudéis, y si tenéis alguna sugerencia este es el momento..
Un salu2. :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile:

Aqui os dejo el esquema de bloque del circuito.

Estoy recopilando enlaces de contadores, los ire agregando aqui.

Enlace de una cuenta atras y se controla con pulsadores el tiempo. (no es lo que quiero pero algunas parte si)

Otro

chambri:
Hola, primero presentarme al foro, soy nuevo y estoy empezando con arduino.

Os cuento mi proyecto y haber si me podéis echar una mano.

Quiero hacer un contador que cuente hacia atrás. Ejemplo tipo maquinitas, que cuando recibe un pulso por una entrada agregue x tiempo y empiece a contar hacia atrás, y cuando llegue a 0 en la salida xx pase a tener otro valor.

Esto parece sencillo, pero necesito ciertas características que me trae un poco loco por qué no sé por dónde meter mano.
1 el tiempo se debe de guardar si se corta la luz, cada minuto que se guarde: ejemplo, el contado marca 10minutos, cuando pasa a 9 se guarda si se va la luz el contador empieza a contar desde 9 hacia atrás..
para esto utiliza la libreria EEPROM, es sencillo.

2 tener un menú donde configurar el tiempo: cada pulsación 10minutos, o 15minutos, o el valor que queramos.
Tienes que currarte un menu, por ejemplo usando SWITCH CASE hacer que cada pulsación de boton modifique una variable numerica. y con otro boton actue de OK

3 ver todas las pulsaciones que se han producido. Ejemplo: ver pulsaciones 100 veces
Que problema hay? simplemente guarda las pulsaciones en una variable y muestralo por pantalla

4 poder borrar esas pulsaciones: poner a 0 esas pulsaciones, para cuando quiera volver a solicitar el punto 3 me aparezca.
lo mismo un boton que haga un reset y te mande al menu.

Todo esto se mostrara por un display.

Bueno espero que pronto pueda poner algo de código para que me ayudéis, y si tenéis alguna sugerencia este es el momento..
Un salu2. :slight_smile: :slight_smile: :slight_smile: :slight_smile: :slight_smile:

Gracias por responder darme algunas pistas para realizar el proyecto.
De momento el proyecto lo llamare EUREKA v5.0, ya que he realizado varios con el mismo fin pero utilizando ordenador con circuiteria comunicados por puerto serie y sin procesadores. y esta sera la version 5 y autonoma.

Bueno espero que este proyecto le sirva a alguien mas o por lo menos que se puedan beneficiar del codigo quien pueda.

Un salu2 :grin: :grin: :grin: :grin: :grin:

Para los botones puedes usar el siguiente circuito

Es un keypad estilo joystick que tiene 5 pulsadores, seleccionar, arriba, abajo,derecha izquierda. Solo neceistas usar un pin A0. el valor se obtiene del divisor the voltaje .

Cuando se presiona un pulsador, el pin A0 lee el voltaje y es comparado con valores en el sketch para identificar que pulsador se ha precionado y asi realizar una acccion.

Para encontrar instrucciones detalladas de como hacer esto click en el link de abajo:

Gracias yOPERO, no se me habia ocurrido, es muy bueno, lo implementare, aunque me sobran varios pulsadores lo adaptare al circuito, y pensar que tenia un codigo tela de largo para entrar en cada situacion... jejejej que bueno y que facil es cuando se tiene tanta ayuda..

Mil gracias..

Aqui os dejo el menu de configuración del contador. es un imagen y empezare a realizar el menu en codigo lo antes posible.

ya tengo hecho el esquema del display y de los pulsadores.
he puesto en marcha el display y funciona perfectamente.

voy a empezar a programar el codigo para los pulsadores y que muestre en el display los datos de entradas de los pulsadores

Pimeras pruebas con lcd y pulsadores para crear el menu.
os dejo un vido del youtube y una foto.

el codigo solo me sirve para sacar los valores de entrada analogico y poder saber que pulsador esta funcionando.

/*
  LiquidCrystal Library - Hello World
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD
 and shows the time.
 
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 8 Feb 2010
 by Tom Igoe
 
 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>

int Pulsador = 0;
int tecladopin = 1;
int TecladoValor = 0;
int TecladoValorTotal = 0;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("PandoraSoft");

}

void loop() {
  
  TecladoValor = analogRead(tecladopin);   
  
  TecladoValorTotal = (TecladoValor/4);
  

  if (TecladoValorTotal == 0){
    lcd.clear();
    lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print("Entro en menu");
   
  }
  if (TecladoValorTotal == 127){
    lcd.clear();

    lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print("Menu +");
  }
   if (TecladoValorTotal == 170){
    lcd.clear();

    lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print("Menu -"); 
   }
    if (TecladoValorTotal == 191){
    lcd.clear();

    lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print("Menu Arriba");
    }
     if (TecladoValorTotal == 204){
    lcd.clear();

    lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print("Menu Abajo");
  
  }
}

Hola, estoy realizando el codigo para grabar los datos en la eeprom, pero he leido por algun lado que las lecturas y reescritura estan limitadas en este chip. alguien puede confirmar esto??
y si es cierto existe alguna memoria que no este limitada y que podamos conectar a arduino????

la informacion la he sacado de aqui. http://arduino.cc/es/Reference/EEPROMWrite

Un salu2.

Toda memoria EEPROM tiene un límite de ciclos de escritura, lo que te dicen es que lo tengas en cuenta, porque quizás prefieras usar una EEPROM externa con más 'aguante', que además puedes substituir más fácilmente (una 24C0X por ejemplo). Es más que recomendable que en la medida de lo posible minimices el uso de la EEPROM, copiando su valor a una variable mapeada en la RAM, y no reescribiendo hasta que se salga del programa. En tu caso es algo más dificil de conseguir, ya que tienes que guardar cada minuto. El único método para optimizar la EEPROM como te digo requiere modificar un poco la placa del Arduino, seguramente es más comodo añadir el 24C0X, en formato PDIP, ya que así puedes cambiarlo cuando acabe.

Ya tengo el contador casi terminado, pero me encuentro con dos problemas que de momento no se resolver.

1º. cuando esta la cuenta atrás, no funciona ningún botón, ni administrador ni el click para aumentar el tiempo.
2º. Cuando el tiempo esta a 0, puedo entrar al administrador. pero parpadea entre insertar moneda y el menú que se elija.

Aqui os dejo el codigo:

/*
  Contador para maquinas recreativas, tipo maquinas para internet
  maquinas pago para tv, y todo lo que se pueda cobrar por utilizar
  por un tiempo determinado.
 
  El circuito lo vamos a dividir en dos partes:
  Primero El administrador:
  donde configuraremos los datos para que el contador funcione.
  Segundo el Contador:
  Contara a tras el tiempo que hemos configurado por click en su
  entrada

  El circuito mostrara por un LCD de 16x2 toda la informacion
  ***************************************************************
  PULSADORES
  ***************************************************************
  Tenemos 3 pulsadores que controlan la administración
  1- Menu: Entra y sale del Menu de administración
  2- + : Sube el valor de la variable que tengamos en el menu
  3- - : Baja el valor de la variable que tengamos en el menu
 
  Valores que toma la entrada de los botones:
  Entrada analogica y dividida por 4.
  si pulsamos MENU  = 0
              MAS   = 127
              MENOS = 170
             
             *** estos no se utilizan al final ***
              ARRIBA = 191
              ABAJO  = 204
             *** **** **** **** **** **** **** ***
 
  Realizado el 06/10/2011:
 
   http://www.pandorasoft.com
 
 */

// incluimos la libreria del LCD  16x2
#include <LiquidCrystal.h>
// ***********************************
#include <EEPROM.h>
// ***********************************
int BotonMenu = 0;
int BotonMas = 0;
int PinBoton = 0;
int MenuAdmin = 0;
int MemoriaClick = 0;
int TotalClick = EEPROM.read(0);
float MostrarClick;
int BorraRecauda = 0;
int ActivarCircuito = 0;
int DesactivarCircuito = 0;
int PinClick = 8;
int BotonClick;
int ConfiTiempo = EEPROM.read(1);
int BotonMasTiempo = 0;
int BotonMenosTiempo = 0;
int ConfiPrecio = EEPROM.read(2);
int BotonMasPrecio = 0;
int BotonMenosPrecio = 0;
int Salir = 0;
//// cuenta atras
int Tiempo = EEPROM.read(3);
int Minutos;
int Horas;
// las patillas del lcd qeu tienen entradas y salidas
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // salida a controlar por el pin 7
  pinMode(7, OUTPUT); 
  // configura lcd con columnas y caracteres
  lcd.begin(16, 2);
  lcd.clear(); /// limpio pantalla

}
// funcion para hacer reset
void(* resetFunc) (void) = 0; // esta es la funcion
  ///////////////////////////////////////////////////////////
//////////// funcion de para la cuenta atras.
void timer(){
     // activamos la salida en alto
     digitalWrite(7, HIGH);  
    
     //////////// contamos 60 segundos atras ///
     for(int timerCount = 59; timerCount >= 0; --timerCount){
 
         if(timerCount == 0 && Tiempo > 0){ // cuando los segundos llega a 0 guardamos entiempo menos 1
	    //// y volvemos a poner el timer en 60 para restar otro minuto
            //// tambien guaramos el tiempo en la eeprom
            timerCount = 59;
            Tiempo --;
            EEPROM.write(3,Tiempo);
            MostrarTiempo();
         }else{
	    EEPROM.write(3,Tiempo);      
            MostrarTiempo();
        }
       // Mostramos cuenta atras de los segundos
       MostrarTiempo();
       lcd.print(":");
         if (timerCount >10){ /// esto es por estetica para poner formato 01,02,03 etc..
           lcd.print(timerCount);
         }else{
           lcd.print("0");
           lcd.print(timerCount);
         }
       delay(1000);
       }
    
     
 }
int MostrarTiempo(){ //// funcion para mostrar el tiempo restante
   ////////////////////// con formato 00:00
    Horas = Tiempo/60; /// Obtenemos las horas
    Minutos = Tiempo -(Horas * 60); //Obtenemos los minutos
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Tiempo Restante");
    lcd.setCursor(4,1);
      if( Horas < 10 ){ // si es menor de 10 agregamos delante un 0 (por estetica)
        lcd.print("0");
        lcd.print(Horas);
      }else{
        lcd.print(Horas);
      }
    lcd.print(":");
      if(Minutos < 10){ // si es menor de 10 agregamos delante un 0 (por estetica)
        lcd.print("0");
        lcd.print(Minutos);
      }else{
        lcd.print(Minutos);
      } 
 }
void loop() {
  //// comenzamos el contador ///////
 if (Tiempo == 0){ // si el tiempo es 00:00
    digitalWrite(7, LOW); // DESCTIVAMOS LA ENTRADA
    lcd.setCursor(0,0);
    lcd.clear();// mostramos por pantalla que inserten moneda
    lcd.print("Insertar Moneda");
    lcd.clear();
    delay(600); // hacerlo parpadear
    lcd.print("Insertar Moneda");
    delay(600);
 }else{
    timer(); // si no es 0 el contador debe empezar o continuar.
 }

la siguiente parte del codigo lo inserto en otro post, aqui no me deja dice que he excedido el máximo de caracteres..

En el primer video vemos como funciona el contador.

En el segundo vemos como no funcionan los pulsadores.

Aquí os dejo la segunda parte del código para completar el código completo.

/////////////////////////////////////////////////////////
// meto en botonclick las pulsaciones recibidas ////////
  BotonClick = digitalRead(PinClick);
  // guardar los click en la memoria;
  if (BotonClick == 1){
      delay(200);
      TotalClick ++; 
      Tiempo = Tiempo + ConfiTiempo;
      EEPROM.write(3,Tiempo); /// guardamos el valor del tiempo
      EEPROM.write(0,TotalClick); /// guardamos el total de los click
      resetFunc();  // funcion para hacer un reset
  }
  /// meto dentor de botonmenu el valor del pulso del menu
  BotonMenu = analogRead(PinBoton);   
  // aumento el valor de la variable para entrar en el menu
  if ((BotonMenu/4) == 0){
    MenuAdmin ++;
    delay(500);  
  }
  if (MenuAdmin == 7){ /// para salir del menu
    MenuAdmin = 0;  
  }
  switch (MenuAdmin){ // casos de menu
    case 1:
      lcd.clear(); /// limpio pantalla
      lcd.print("Total Recauda");
      lcd.setCursor(0, 1); // le digo posicion del cursor
      TotalClick = EEPROM.read(MemoriaClick);// obtengo el valor guardado en memoria
      MostrarClick = (TotalClick * ConfiPrecio);
      lcd.print(MostrarClick/100); //imprimo el valor por pantalla
      lcd.print(" Euros");
      delay(500);
      break;
    case 2:
      if ((BotonMenu/4) == 127){
      BorraRecauda = 1;
       }
      if ( BorraRecauda == 1){ /// si pulsamos + borramos el valor guardado
      lcd.clear();
      lcd.print("Borrar Recauda");
      lcd.setCursor(0, 1);
      lcd.print("borrado");
        EEPROM.write(0,0);
        BorraRecauda = 0;
        delay (5000);
      }else{
         lcd.clear(); /// limpio pantalla
         lcd.print("Borrar Recauda");
         lcd.setCursor(0, 1); // le digo posicion del cursor
         lcd.print("Pulsa + y Borra"); // muestro mensaje
      }
      delay(500);
      break;
    case 3:
    if ((BotonMenu/4) == 127){
        BotonMasTiempo = 1;
        }
        if ((BotonMenu/4) == 170){
      BotonMenosTiempo = 2;
    }
      lcd.clear(); /// limpio pantalla
      lcd.print("Config. Tiempo");
      lcd.setCursor(0, 1); // le digo posicion del cursor
      if (BotonMasTiempo == 1){
        ConfiTiempo ++;
        EEPROM.write(1,ConfiTiempo);
        BotonMasTiempo = 0;
      delay(100);
      }
      if (BotonMenosTiempo == 2){
        ConfiTiempo --;
        EEPROM.write(1,ConfiTiempo);
        BotonMenosTiempo = 0;
        delay(100);
      }
    
      lcd.print(ConfiTiempo);
      lcd.print(" Minutos"); // muestro mensaje
      
      delay(500);
      break;
    case 4:
     if ((BotonMenu/4) == 127){
        BotonMasPrecio = 1;
        }
        if ((BotonMenu/4) == 170){
      BotonMenosPrecio = 2;
    }
      lcd.clear(); /// limpio pantalla
      lcd.clear(); /// limpio pantalla
      lcd.print("Conf.Valor Click");
      lcd.setCursor(0, 1); // le digo posicion del cursor
      if (BotonMasPrecio == 1){
        ConfiPrecio ++;
        EEPROM.write(2,ConfiPrecio);
        BotonMasPrecio = 0;
      delay(100);
      }
      if (BotonMenosPrecio == 2){
          ConfiPrecio --;
        EEPROM.write(2,ConfiPrecio);
        BotonMenosPrecio = 0;
        delay(100);
      }
      lcd.print(ConfiPrecio);
      lcd.print(" Cent."); // muestro mensaje
      delay(500);
      break;
    case 5:
     lcd.clear();
        lcd.print("Activar Circuito");
        lcd.setCursor(0, 1);
        lcd.print("Activ + Desac -");
      if ((BotonMenu/4) == 127){
      ActivarCircuito = 1;
    }
    if ((BotonMenu/4) == 170){
      DesactivarCircuito = 1;
  }
      if (ActivarCircuito == 1){
        digitalWrite(7, HIGH);  
        ActivarCircuito = 0;
        lcd.clear();
        lcd.print("Activar Circuito");
        lcd.setCursor(0, 1);
        lcd.print("Desac. pulsa -");
        ActivarCircuito = 0;
        delay (1000);
      }
      if (DesactivarCircuito == 1){
        digitalWrite(7, LOW); 
        DesactivarCircuito = 0;
        lcd.clear();
        lcd.print("Activar Circuito");
        lcd.setCursor(0, 1);
        lcd.print("Activar pulsa +");
        DesactivarCircuito = 0;
        delay (1000);
      }
      delay(500);
      break;
    case 6:
      lcd.clear(); /// limpio pantalla
      lcd.print("Salir de Menu");
      lcd.setCursor(0, 1); // le digo posicion del cursor
      lcd.print("Pulsa + p Salir"); // muestro mensaje
       if ((BotonMenu/4) == 127){
      Salir = 1;
    }
       if (Salir == 1){
         MenuAdmin = 0;
         BotonMenu = 0;
         BotonMas = 0;
         BorraRecauda = 0;
         ActivarCircuito = 0;
         DesactivarCircuito = 0;
         BotonMasTiempo = 0;
         BotonMenosTiempo = 0;
         BotonMasPrecio = 0;
         BotonMenosPrecio = 0;
         resetFunc();  // funcion para hacer un reset
     }
       
      delay(500);
      break;
  }

}

Solucionado el problema de no contar cuando estaba dentro del bucle, he quitado el for y he puesto un while; dentro de la funcion timer.

aqui os dejo el codigo, sigo investigando para el tema del parpadeo del administrador.

Otra cosa es que mientras esta contando no puedo habrir el administrador tengo que esperar que llegue a 0. lo voy a mirar haber si lo puedo corregir.

//////////// funcion de para la cuenta atras.
void timer(){
     // activamos la salida en alto
     digitalWrite(7, HIGH);  
     int Segundos = 59;
     while (Tiempo > 0){     
       while (Segundos > 0){
          //// obtenemos el tiempo mientras se esta contando, por si hecha alguna moneda en ese momento.   
         if (digitalRead(PinClick) == 1){ 
                delay(200);
                TotalClick ++; 
                Tiempo = Tiempo + (ConfiTiempo - 1); // restamos -1 para que cuente desde 2:59 si marcamos 3 minutos
                EEPROM.write(3,Tiempo); /// guardamos el valor del tiempo
                EEPROM.write(0,TotalClick); /// guardamos el total de los click
                resetFunc();  // funcion para hacer un reset
          }  
            Segundos--;
            MostrarTiempo();
            lcd.print(":");
               if (Segundos < 10){ /// esto es por estetica para poner formato 01,02,03 etc..
                   lcd.print("0");
                   lcd.print(Segundos);
               }else{
                   lcd.print(Segundos);
               }
             delay(1000); 
      }
       Tiempo --;
       EEPROM.write(3,Tiempo);
       Segundos = 59;
     }
}

tambien les pongo un video con los segundos acelerados para que vean como funciona.

Hola chambri, se que el tema es viejito, pero quiero saber si si le implementaste las funciones que tenias pendiente.

de hecho es muy buen proyecto...

saludos...

es un post del 2011. Y chambi no sabemmos si sigue participando de este foro. Te sugiero le envies un PM o Menaje Privado.

Gracias surbyte, david ya me respondio en los comentarios del video y parece que abandono el proyecto hace mucho por falta de tiempo....

de todos modos gracias por su codigo que es un buen punto de partida....

Saludos y suerte...

Primero Perdonar por no responder, ya que hace tanto tiempo que no entro en el foro, que ya no me manda las notificaciones.
Segundo, por motivos de tiempo, 3 niñas y el trabajo ya no puedo dedicarle lo suficiente a arduino que en mi opinion es una gozada para todo electronico.
Tercero, ya me he vuelto a incorpora al foro y a recibir la notificaciones, en los huecos que pueda seguire ayudando a los que necesiten de mi ayuda y aportando ideas.
y por ultimo decir que me esta entrando el gusanillo y puede que haga un hueco y retomar el tema del contador.

Un saludo a todos y a programar....... :grin: :grin: :grin: :grin: :grin:

chambri:
Primero Perdonar por no responder, ya que hace tanto tiempo que no entro en el foro, que ya no me manda las notificaciones.
Segundo, por motivos de tiempo, 3 niñas y el trabajo ya no puedo dedicarle lo suficiente a arduino que en mi opinion es una gozada para todo electronico.
Tercero, ya me he vuelto a incorpora al foro y a recibir la notificaciones, en los huecos que pueda seguire ayudando a los que necesiten de mi ayuda y aportando ideas.
y por ultimo decir que me esta entrando el gusanillo y puede que haga un hueco y retomar el tema del contador.

Un saludo a todos y a programar....... :grin: :grin: :grin: :grin: :grin:

Que bueno chambri, hace como 8 años diseñe uno parecido para el pic 16f84a con todas las funciones que mencionas solo me falto el menu de programacion y era con dysplay de 7 segmentos, anoche desempolve mi arduino y buscando piezas y tambien encontre el display lcd que creo es lo mas costoso...

por otra parte te pregunto si seria posible simularlo en isis proteus, anoche estube mirando y depronto quisas...
lo que pasa es que en este momento tambien estoy algo frio en esto de la programacion, debere desempolvarme tambien...

espero te animes, y asi seriamos 2 para compartir ideas y dejarlo a punto....

Saludos....