¿Como temporizar una hora?

Hola a todos. Estoy con un proyecto para controlar la temperatura de un tanque de agua.
Lo tengo mas o menos claro, pero me surge un problema al que con mis conocimientos no se darle solución.
Necesito subir la temperatura del agua de forma automática hasta 31 grados, con un incremento de un grado a la hora.
Es decir, al activar una entrada en Arduino, si estoy a 26 grados, subir a 27 y esperar una hora, despues subir a 28 y esperar otra hora, y así hasta llegar a 31.
El problema que tengo es que no se como hacer un contador de una hora, sin bloquear con un "delay" al procesador.
¿Me podéis ayudar en esto con algún ejemplo, por favor?

Gracias

debes usar la funcion millis() si no dispones de un rtc (DS3231 por ejemplo)y esta tratado hasta la saciedad en este foro(usa el buscador ) ,en documentacion hay un tutorial de millis() ,en google hay miles de posts y entre los ejemplos basicos que vienen con el ide de arduino ,busca blynkWithoutDelay.

si durante una hora no vas a hacer nada, te puedes apañar con delay(), pero si durante esa hora piensas hacer algo más necesitarás de un módulo rtc.

Buenas, si como dijeron te aconsejo el uso del RTC.
Si tienes un corte en el suministro de la alimentaion del arduino ( y no usas un RTC) o cualquier otro motivo que resetee el programa podrias comenzar de nuevo el conteo del tiempo y alterar el correcto incremento de 1grado/hora

Ve a Documentación => Indice de temas tutoriales => millis()

Eso te permitirá crear un programa que funcione fluido y que no se detenga x 1 hora.
Mientras podras vigilar las curva de crecimiento de temperatura.
Supongo que tampoco debería ser que suba 1 grado x hora sino que sea una pendiente de crecimiento.

Ej. de lo que digo. si arrancas con 26 a la media hora debe estar en 26.5 grados y a la hora 27 grados.
Un pendiente de 1grado /hora y no escalonado como sería, 26 ahora, y en una hora subir de golpe a 27.

Son cosas diferentes y programaciones diferentes.

como ejemplo mira en tu Ide BlinkWithoutDelay.ino y entenderás con leds lo que tu quieres hacer.

surbyte:
Eso te permitirá crear un programa que funcione fluido y que no se detenga x 1 hora.
Mientras podras vigilar las curva de crecimiento de temperatura.
Supongo que tampoco debería ser que suba 1 grado x hora sino que sea una pendiente de crecimiento.

En realidad el tema de los delay con millis aquí no me parece que resuelva el problema (resuleve solo el de no detener el procesador), quiero decir que no es el meollo del problema, es que hay muchas variables, la cantidad de agua, la velocidad en que el calentador aumenta la temperatura, si se mantiene constante el volumen de agua.
Como dices, el centro del tema está en cómo implementar una curva de crecimiento, de manera de ir progresivamente aumentando la temperatura, de manera independiente al volumen total de agua, la temperatura ambiente, las posibles variaciones de ese volumen (durante esa hora se mantiene constante?).
No es lo mismo aumentar la temperatura del agua en p.ej 10 minutos y luego mantenerla a esa temperatura durante el resto de la hora que subirla en fracciones iguales a lo largo de esa hora.

Me he liado yo mismo, JAJA
Creo que el compañero debería ampliar un poco las condiciones de la instalación.

Gracias a todos por vuestras respuestas, antes que nada decir a jose que ya he buscado por el foro y por la web, solo que cuando se sabe lo que se hace, se entiende todo. En mi caso no soy experto en programación y aunque vea proyectos parecidos, no los se interpretar.
Surbyte y compañía, como bien indicáis depende de como sea el preceso de calentamiento, intento de explicarme porque creo que antes, no lo hice bien.
Se trata de controlar la temperatura de un acuario, determinadas especies desarrollan una enfermedad que es un hongo. Para curarlos se eleva la temperatura hasta 31º y se mantiene unos días.
La temperatura estándar debe ser unos 26 o 27 grados, si aplicamos termoterapia, durante la siguiente hora la subimos un grado, es decir, si estamos a 28º Arduino deberá de mantener activado el relé de salida 220V del calentador hasta alcanzar 29º, y una vez lo alcance, esperamos una hora para subir a 30º. Una vez que se ha alcanzado los 30º, mantenemos una hora y subimos a 31º. Al llegar a 31, lo mantenemos de forma indefinida, hasta que manualmente modifiquemos la temperatura.
El control de temperatura ya lo tengo hecho, mañana desde el PC os lo envío para que lo veáis.
Lo que me queda que implementar es la función que llamo termoterapia.
Podría hacerlo manualmente subiendo la temperatura un grado, pero a veces no puedes estar en casa durante todo el tiempo que dura el proceso.
Nuevamente gracias a todos.
Saludos

O sea que le aplicaras un salto de temperatura de 1º sin problemas y el pez/peces no experimentarán problemas?
Bueno si es asi, lo que estoy pensando es que estas suponiendo que la cosa es mas simple que lo que en realidad es.
Vas a necesitar un control de temperatura PID para lograr tu objetivo porque no es tan facil con un control SI/NO o sea proporcional lograr un ajuste como el que buscas.
Mas alla que la inercia termica del acuario no permitirá grandes fluctuaciones, un control si/no no permite ajustes finos.

UN PID con un control x fase para el ajuste de la temperatura sería lo ideal.

Gracias de nuevo Surbyte.
El calentador del acuario tiene calculada su potencia para los litros de agua que calienta.
La variación de temperatura es lenta porque aproximadamente es 1W por litro, por lo que el incremento es lento y no hace daño a los peces.
Ahora mismo lo controlo con un LM35 y un Arduino Uno, y con las pruebas del prototipo funciona. Como decía anteriormente, mañana pasaré el codigo que tengo el PC a mano.
Saludos

Bueno evidentemente no lo tienes a mano.
Este es un ejemplo de lo que podrias hacer con un PID un Arduino y un LM35 USING PID ON AN ARDUINO TO CONTROL AN ELECTRIC HEATER

El sistema controla la temperatura con mucha precisión. Usa un SSR (sin cruce por cero) que obviamente no es un rele sino uno de estado solido.

El código puede modificarse para que haga tu secuencia de tiempo y temperaturas.

Aunque creas que está muy claro lo que deseas hacer, ten en cuenta que el punto de partida de los que leemos tu post es la nada. No existe ningún contexto por muy obvio que te parezca. ¿Podrías explicarlo para dummies?
Particularmente yo veo dos posibles interpretaciones:

  • Subir un grado de forma rápida (pongamos que toma quince minutos) , esperar una hora a esa temperatura, subir otro grado de forma rápida, esperar otra hora...
  • Subir de forma progresiva un grado por hora hasta alcanzar la temperatura objetivo.
    Es decir, hacer la subida de temperatura de forma escalonada o de forma lineal.
    Estaría bien que pongas un ejemplo práctico de hora/temperatura.

Gracias Noter y Surbyte por vuestra respuesta, la velocidad del incremento de temperatura viene marcado por la potencia del calentador.
Eso para el proyecto debe ser transparente, si tarda 5min o una hora, no es significativo para el proyecto.
La intención es que una vez alcanzado el grado de temperatura que debe subir, tarde lo que tarde, se mantenga una hora a esa temperatura, y luego suba otro grado.
Os pongo el código para que veáis lo que tengo hecho hasta ahora, que es solo, control de temperatura.
Seguro que el código es mejorable, pero es lo que he podido hacer con mis conocimientos.

//TERMOSTATO ACUARIO CON LM35
//CONTROLA LA TEMPERATURA DEL AGUA Y ACTIVA O DESACTIVA UN RELE PARA SALIDA DE CALENTADOR
//MEMORIZA EN EEPROM LA TEMPERATURA OBJETIVO A MANTENER
// 30/3/2018 SI LA TEMPERATURA BAJA DE 24 O SUBE DE 31 SALTA UN BUZZER. SE PUEDE SILENCIAR EL BUZZER Y APARECE UN * INDICANDO QUE LA ALARMA ESTA DESABILITADA  

// Incluir el código de la biblioteca:
#include <LiquidCrystal.h>

// Inicializa la biblioteca con las conexiones a los pins del interface Arduino:
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#include<EEPROM.h>

// Patillas y variables globales

  int sensor=A0; // Sensor en entrada analógica pin A0
  int modo=6; // Pulsador Memo pin 6
  int adj=7; //Pulsador de ajuste pin 7
  int led=1; // LED de salida pin 1
  int buzzer=8; //Buzzer alarma
  float valorSensor=0; // Variable con el contenido de la entrada analógica A0
  float termo=0; // Variable con el valor real de temperatura
  int pulsa1=0;  // Variable con estado de pin 6
  int pulsa2=0;  // Variable con estado de pin 7
  int temp_memo; // Variable para guardar el valor de temperatura objetivo 
  float temp; // Variable de conmutación del relé (LED Rojo)
  int flag=0; //Bandera para desactivar buzzer  buzzer=LOW


// Subprograma de alarma
void alarma()// Suena alarma
  { 
    digitalWrite(buzzer,HIGH);
    delay(50);
    digitalWrite(buzzer,LOW);
    delay(50);
    digitalWrite(buzzer,HIGH);
    delay(50);
    digitalWrite(buzzer,LOW);
  }// Fin Subprograma de alarma

// Subprograma de temperatura
void temperatura()// Control de temperatura. Ajuste de umbral 
  { 
     
  pulsa1=0;
  digitalWrite(buzzer,HIGH);
  delay(100);
  digitalWrite(buzzer,LOW);       
  while(pulsa1 == LOW) // Umbral de conmutación del relé (LED Rojo)
  
  { 
    delay(1000);
    pulsa1 = digitalRead(modo);
    pulsa2 = digitalRead(adj);
    if (pulsa2 == HIGH)
        
      {         
        temp = temp + 1; // Incrementos de  grados
      }
       
    if ((temp < 24) or (temp > 31))
      {
        temp = 24;
      }
        
    lcd.setCursor(5,0);            
    lcd.print("AJUSTE");
    lcd.setCursor(3,1);            
    lcd.print("TEMP:");
    lcd.print(temp);
    lcd.blink();
  }
  lcd.clear();
  lcd.setCursor(2,1);
  lcd.noBlink();
  lcd.print(temp);
  lcd.print(" Grados");
  delay(1000);
  lcd.setCursor(1,1);
  lcd.print("TEMP MEMORIZADA");
  temp_memo=temp*100;
  EEPROM.put(0,temp_memo);
  delay(1000); 
  
} // Fin Subprograma de temperatura

// Inicialización del programa
void setup() 
{ 
  lcd.begin(16, 2);
  lcd.setCursor(2, 0); 
  lcd.print("TERMOSTATO");
  lcd.setCursor(2, 1);
  lcd.print("ACUARIO Ver1");
  delay(1000);

  EEPROM.get(0,temp_memo);//Leo el valor de la temperatura objetivo ajustada
  temp=temp_memo/100;

  pinMode(modo,INPUT);
  pinMode(adj,INPUT);
  pinMode(led,OUTPUT);
  pinMode(buzzer,OUTPUT); 
  digitalWrite(buzzer,LOW);
}

void loop() {
  pulsa1 = digitalRead(modo);
  if (pulsa1 == HIGH)//Pulsador memo
    
    {
      temperatura(); //VOY A SUBRUTINA DE TEMPERATURA
    }
     
  lcd.setCursor(3,0);
  lcd.print("TEMP:");
  valorSensor=analogRead(sensor);
  termo=(valorSensor / 2);
  lcd.print(termo);
   if (flag==1)
   
   {
    lcd.setCursor(0,0); 
    lcd.print("*");
   }
  
  delay(500);

  if (termo < temp)
  
   {
    digitalWrite(led,HIGH);
    lcd.setCursor(2, 1);
    lcd.print("CALENTADOR ON");
    delay(500);
   }
   
 if (termo >= temp)
 
   {
     digitalWrite(led,LOW);
      lcd.clear();
   }

if (termo < 24)

  {
  lcd.clear();  
  lcd.setCursor(3,0); 
  lcd.print("TEMP:");
  lcd.print(termo);
  lcd.setCursor(2, 1);
  lcd.print("**TEMP LOW**");
  
   if (flag==1)
    {
     lcd.setCursor(0,0); 
     lcd.print("*");
    }
   delay(500);
   lcd.clear();
  }
  
pulsa2 = digitalRead(adj);
if (pulsa2 == HIGH)

 {  
  flag=flag+1;
  delay(10);
  if (flag > 1) 
   {
    flag=0;
   }
 }
  
 if ((termo <24) && (flag==0)) {alarma();}
 if ((termo <24) && (flag==1)) {digitalWrite(buzzer,LOW);}
 if ((termo >31) && (flag==0)) {alarma();}
 if ((termo >31) && (flag==1)) {digitalWrite(buzzer,LOW);}
 if ((termo >=24) && (termo<=31)) {digitalWrite(buzzer,LOW);}

 if (termo > 31)
 
  {
   lcd.clear();  
   lcd.setCursor(3,0);  
   lcd.print("TEMP:");
   lcd.print(termo);
   lcd.setCursor(2, 1);
   lcd.print("*TEMP. HIGH*");
    if (flag==1)
     {
      lcd.setCursor(0,0); 
      lcd.print("*");
     }
   delay(500);
   lcd.clear();
  }
    
} //Fin