Go Down

Topic: Ayuda para el primer gran reto de un dummy (Read 2 times) previous topic - next topic

Marcial


noter

#16
May 06, 2014, 10:13 am Last Edit: May 06, 2014, 10:16 am by noter Reason: 1
Sí. Yo también logré cuelgues muy chulos con los poke :smiley-roll-sweat:
Del zx81 recuerdo el comando fast, que aceleraba la ejecución del programa a cambio de desconectar la pantalla hasta que volvías a modo slow.
La gran innovación del spectrum, aparte del modo gráfico y los ocho colores era la desaparición de esos dos comandos pues trabajaba en fast y con pantalla de continuo  :smiley-eek:.
Dios. Parezco el abuelo cebolleta con sus historias. :smiley-roll:

Marcial

Los avances fueron increibles en esos tiempos. Hoy, un telefono tiene mas potencia que cualquiera de esos equipos.
Yo llegue a utilizar (poco tiempo) una calculadora programable, con un BASIC muy básico  :P y  tarjetas perforadas como sistema de almacenamiento. Con 3 K de memoria casi hacias de todo.

Mas adelante con los primeros pc  8086 y 8088 eso si que era programar... Una vez , por una apuesta, llegue a hacer un virus (muy rudimentario) con instrucciones msdos 2.0,  que colgaba el equipo hasta que lo formatearas de nueva. (muchos tubo que formatear el responsable del aula de informática, jajajaja)

rarito_forever

Hola a todos otra vez.
Me alegra ver que no soy el único con la duda del control del tiempo al pasar los 50 días y aún  me alegra mas conocer la solución. Se ha puesto muy interesante el tema. Si alguien quiere aportar algo mas, bienvenido el y su aportación. Yo mientras voy tomando nota de todo.
Vffgaston: te agradezco tu interés pero no te puedo dar más datos ni información simplemente porque no los hay. Como dije al principio no hay proyecto todavía, solo mil ideas inconexas, muchas dudas, ganas de aprender y un pequeño reto que va un poco mas allá de donde llegan los ejemplos del IDE. El tema del control del tiempo sin recurrir a un modulo RTC es una de las cosas que mas me daba que pensar, de las que menos claro veía. Cuando llegue el momento de que haya proyecto no dudare en facilitaros toda la información, seguro que os necesitare.
Gracias.


vffgaston

OK. Seguiré el hilo.

En todo caso: creo que lo mejor para aprender es proponerse un objetivo concreto (por modestísimo que sea; por eso te preguntaba lo del cacharrerío, para imaginarme qué se podría hacer con ello).

Saludos

rarito_forever

Hola otra vez.
Al final en mi caso ha sido antes el huevo que la gallina. En una cena con amigos y amigos de amigos he encontrado una persona que le sacara utilidad a lo que tenía entre manos. Así, al final si que hay proyecto. Él ya tiene una instalación que le da una señal de salida al cumplirse unas determinadas condiciones, y lo que quiere es doblar esa señal a una fija y otra con tiempo variable. Para hacerlo he puesto un 3er pulsador que emula el pulso de la señal para iniciar actividad. Le he puesto un pequeño delay para los rebotes, solo para asegurarme de que si falla algo no sea de aquí el problema, pero lo eliminare antes de darlo por acabado. He aprovechado el código que me ofreció Marcial, lo he entendido y alterado para adaptarlo a mis necesidades. He implementado código para leer y escribir en la eeprom para no perder el valor del tiempo que hay fijado tal y como se me había sugerido. Al final ha quedado un sketch que si bien seguramente no será muy académico si que es funcional al 100% y cumple con lo que esperaba de el. Lo que no he sido capaz es de aplicar la solución para el desbordamiento de Millis(), y eso que me lo habían dado "mascado". De donde no hay no se puede sacar.
Estaría muy agradecido si alguien me dice como (o me lo hace) aplicar la solución por si acaso. Gracias.



Code: [Select]

#include <LiquidCrystal.h>
#include <EEPROM.h>
byte direccion = 0;

LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);
unsigned long T_High=0;            // Milesimas de estado high
unsigned long T_Ciclo=30000;       // Milesimas del ciclo
unsigned long Milis_Ciclo=0;       // Para controlar el temporizador del ciclo
unsigned long Milis_High;        // Para controlar el temporizador de activo

// Los  botones
byte buttonPin = 2;
byte buttonPin_2 = 4;
byte buttonPin_3 = 6;
byte Salida = 5;
byte salida_2 = 13;

// para button state change de cada boton
bool BtnSumar=false;
bool BtnDigito=false;
bool AntSumar=false;
bool AntDigito=false;
bool activo = false;
byte lastButtonState = 0;   
byte buttonState = 0;

long ultimo_reg = 0;
byte seg = 0;

byte pantalla_activa;
byte Digito=0;
byte Valores[4]={};





void setup()
{
  pinMode(buttonPin, INPUT); 
  pinMode(buttonPin_2, INPUT);
  pinMode(buttonPin_3, INPUT);
  pinMode(Salida, OUTPUT);
  pinMode(salida_2, OUTPUT);
  digitalWrite(Salida, LOW);
  digitalWrite(salida_2, LOW);

  Valores[3] = EEPROM.read(direccion);
  if( Valores[0] >= 255 )
  {
    Valores[0] = Valores[1] = Valores[2] = Valores[3] = 0;
  }
  else
  {
    Valores[2] = EEPROM.read(direccion++);
    Valores[1] = EEPROM.read(direccion++);
    Valores[0] = EEPROM.read(direccion++);
    direccion=0;
    T_High=Valores[0]*10 + Valores[1]*100 + Valores[2]*1000 + Valores[3]*10000;
  }


  lcd.begin(16, 2);
  pantalla_monitoreo();
}


void loop()
{
  if (activo == true)
  {
    digitalWrite(salida_2, HIGH);
    if (millis() > Milis_Ciclo)            // Final ciclo, cargamos nuevo tiempo y activamos salida
    {
      Milis_Ciclo = millis() + T_Ciclo;   
      Milis_High = millis() + T_High;
      digitalWrite(Salida, HIGH);                 
    }
    if (millis() > Milis_High)            // Final salida high, desactivar salida
    {
      digitalWrite(Salida, LOW);
      ;
    }
  }
  else
  {
    digitalWrite(salida_2, LOW);
    digitalWrite(Salida, LOW);
  }

  // Boton para activar salidas
  buttonState = digitalRead(buttonPin_3);
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      if (activo == false)
      {
        activo = true;
        if (pantalla_activa == 0)
        {
          lcd.clear();
          pantalla_monitoreo();
        }
      }
      else
      {
        activo = false;
        if (pantalla_activa == 0)
        {
          lcd.clear();
          pantalla_monitoreo();
        }
      }
    }
  }
  delay(250);
  lastButtonState = buttonState;

  //Boton aumentar valores digito
  BtnSumar=digitalRead(buttonPin);
  if (BtnSumar && AntSumar != BtnSumar)    // Boton añadir valor cambia a activo
  {
    switch (pantalla_activa)
    {
    case 0:
      lcd.clear();
      pantalla_pregunta();
      break;

    case 1:
      Digito=0;
      Valores[0] = Valores[1] = Valores[2] = Valores[3] = 0;
      lcd.clear();
      PintaTiempo();
      break;

    case 2:
      Valores[Digito]++;
      if (Valores[Digito]>9) {
        Valores[Digito]=0;
      }
      lcd.clear();
      PintaTiempo();
      break;
    }
  }
  AntSumar=BtnSumar;

  //Boton fijar valor
  BtnDigito=digitalRead(buttonPin_2);
  if (BtnDigito && AntDigito != BtnDigito)    // Boton digito cambia a activo
  {
    switch (pantalla_activa)
    {
    case 0:
      pantalla_monitoreo();
      break;

    case 1:
      lcd.clear();
      pantalla_monitoreo();
      break;

    case 2:
      Digito++;
      if (Digito>3) 
      { 
        T_High=Valores[0]*10 + Valores[1]*100 + Valores[2]*1000 + Valores[3]*10000;// Almacenamos el nuevo tiempo
        EEPROM.write(direccion, Valores[3]);
        EEPROM.write(direccion++, Valores[2]);
        EEPROM.write(direccion++, Valores[1]);
        EEPROM.write(direccion++, Valores[0]);
        direccion = 0;
        if (T_High<T_Ciclo)
        {
          lcd.clear();
          pantalla_monitoreo();
        }    // Del cuarto digito al primero
        else if (T_High>T_Ciclo)          // Si el tiempo high es mayor que el del ciclo pasamos el tiempo a 0
        {
          Digito=0;
          Valores[0] = Valores[1] = Valores[2] = Valores[3] = 0;
          T_High=0;
          PintaTiempo();
        }
        break;
      }

    }
  }
}


// Función pantalla principal
void pantalla_monitoreo()
{
  pantalla_activa = 0;
  lcd.setCursor(0,0);
  lcd.write("SALIDAS ");
  if (activo == true)
  {
    lcd.setCursor(8,0);
    lcd.write("ON");
  }
  else
  {
    lcd.setCursor(8,0);
    lcd.write("OFF");
  }
  lcd.setCursor(0,1);
  lcd.write("T ON S1 = ");
  lcd.setCursor(10,1);
  lcd.print(Valores[3]);
  lcd.setCursor(11,1);
  lcd.print(Valores[2]);
  lcd.setCursor(12,1);
  lcd.print("'");
  lcd.setCursor(13,1);
  lcd.print(Valores[1]);
  lcd.setCursor(14,1);
  lcd.print(Valores[0]);
}

// Función pantalla pregunta
void pantalla_pregunta()
{
  pantalla_activa = 1;
  lcd.setCursor(0,0);
  lcd.write("CAMBIAR TIEMPO?");
  lcd.setCursor(0,1);
  lcd.write("1=VOLVER   2=0K");
}


// Función tiempo seleccionado     
void PintaTiempo()

{
  pantalla_activa = 2;
  lcd.setCursor(0,0);
  lcd.print(Valores[3]);
  lcd.setCursor(1,0);
  lcd.print(Valores[2]);
  lcd.setCursor(2,0);
  lcd.print(":");
  lcd.setCursor(3,0);
  lcd.print(Valores[1]);
  lcd.setCursor(4,0);
  lcd.print(Valores[0]);
}


Marcial

#21
May 16, 2014, 09:41 am Last Edit: May 16, 2014, 09:43 am by Marcial Reason: 1
Échale un ojo a ver que te parece:

Code: [Select]
void loop()
{
  Anteriormilis=millis();   // Almacenamos millis() para controlar el desborde
 
  ...
 
 if (activo == true)
 {
   digitalWrite(salida_2, HIGH);
   if (millis() > Milis_Ciclo)            // Final ciclo, cargamos nuevo tiempo y activamos salida
   {
     Milis_Ciclo = millis() + T_Ciclo;    
     Milis_High = millis() + T_High;
     digitalWrite(Salida, HIGH);                
   }
   if (millis() > Milis_High)            // Final salida high, desactivar salida
   {
     digitalWrite(Salida, LOW);
   }
 
   ...

   if (millis()<Anteriormilis)    // Si es millis es menor que el que hemos almacenado, es qaue ha desbordado y empezado de 0
   {
     Milis_Ciclo = (Anteriormilis - Milis_Ciclo) + millis(); // Nuevo valor para Milis_Ciclo : el timepo que le falta de consumir + millis()
     ...                                                     // Igual con todas las variables que sirvan para lo mismo
   }
 }


PD:  Se me olvidaba comentarte que la epron del arduino tiene una vida limitada,  http://arduino.cc/es/Reference/EEPROMWrite

rarito_forever

Esto si que es rapidez. Ya he integrado en el código la solución que me ofreces, de aquí a 50 días sabré si lo he hecho bien   :smiley-eek: (es broma, no lo dejare 50 días en marcha, si hay problemas ya me vendrán a buscar). No acabo de entender a que otras variables te refieres al decir lo de "Igual con todas las variables que sirvan para lo mismo". Quieres decir con todas las variables que utilizan millis() para su calculo supongo.
Lo de los ciclos de lectura y escritura ya lo sabía pero no creo que lleguen al límite con la utilidad que le darán, parece que sera una cosa bastante constante y repetitiva incluso en el factor tiempo. Lo que no acabo de tener claro es si seria buena practica el uso de un contador para que no sobrescriba siempre los datos en la misma dirección, o considerando (como entiendo que es) que el limite de ciclos es global y no por direcciones, dejarlo hacer siempre en el mismo sitio. ¿Cómo lo ves tú?
Gracias otra vez por tu tiempo.

Marcial

Sobre el tema de los tiempos, si me refería a que si utilizas varias variables para control de tiempo en sitios distintos, que las actualices todas juntas. Sobre la vida útil de la eepron, supongo que sera grabaciones ne la misma dirección, pues la vida útil estara limitada  por problemas físicos.  Sobre contar o no el numero de accesos ... si pero solo si es en números romanos para conseguir una buena precisión  :P, o eso o ser lo suficientemente sensato como para ver si se trata de una acceso diario o un acceso cada 10 décimas de segundo, y tener controlado el tema para que de tiempo al menos a cobrar el trabajo antes de que casque , jajajaj

rarito_forever

Ok. Gracias por las aclaraciones. Espero haber sido un alumno aplicado ,haber seguido bien las indicaciones y al final que todo esto se vea en el funcionamiento del artilugio. Y si no, como dije el otro día, ya me vendrán a buscar.
Gracias por todo a todos y en especial a ti Marcial. Nos vemos

Marcial

Por mi parte no se merecen.

Suerte con el artilugio.

Go Up