Llamadas a subrutinas

Buenas tardes.
La idea consiste que dentro del proceso void loop() haga una serie de llamadas a diferentes subrutinas cada x,y,z tiempos para cada una de ellas, en este caso un esp8266.

Ejemplo:

void loop()
{
cada 2 segundos ejecutar subruitna1 (x tiempo)
cada 10 segundos ejecutar subrutina2 (y tiempo)
cada 5 minutos ejecutar subrrutina3 (z tiempo)
}

subrutina1(){
.....
}
subrutina2{
.....
}
subrutina3{
.....
}

¿Como seria el código?

Muchas gracias por la ayuda.
Javier

Ya lo has escrito tu. Cambia las explicaciones por variables comparadas con millis y.....

Saludos

Gracias.
El problema es que no tengo claro como pasarlo a codigo.
Podéisdeis ayudarme?.

Gracias y un saludo,
Javier.

Javier, te podemos ayudar a corregir tu código pero no hacemos el código por ti.

Saludos

Muchas gracias de todas formas.

Hola una aproximacion podria ser la siguiente:

unsigned long reloj,relog1;
int intervalo,intervalo1;

void setup(void){ 
  
}

void loop()
{
 cada 2 segundos ejecutar subruitna1  (x tiempo)
 intervalo = (millis()-reloj);
 if (intervalo >= 2segundos;){reloj = millis(); reloj1=millis(); subrutina1();}
 
 cada 10 segundos ejecutar subrutina2 (y tiempo)
 cada 5 minutos  ejecutar subrrutina3 (z tiempo)
}

subrutina1(){
inicio1:
intervalo1 = (millis()-reloj1);
 if (intervalo1 >= x tiempo;){
    reloj1 = millis();
....................
goto inicio1;    
 }
}
.....

}
subrutina2{
.....
}
subrutina3{
.....
}

Estudialo, tendras que crear nuevas variables para las otras dos etc ya comentaremos
Saludos

Gracias por tu ayuda.

He implementado este código pero no me funciona como esperaba ya que veo que no se llama a ninguna de las subrutinas.

//
#define DEBUG(a) Serial.println(a);
#ifdef ESP32
  #include <WiFi.h>
  #include <HTTPClient.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESP8266HTTPClient.h>
  #include <WiFiClient.h>
#endif

// OLED
#include <SPI.h>
#include <Wire.h>
#include <SFE_BMP180.h>
#include "SSD1306Wire.h"        // legacy: #include "SSD1306.h"
//
// RED
#define FIREBASE_HOST "host_firebase"
#define FIREBASE_AUTH "clave"
#define WIFI_SSID "ssid"
#define WIFI_PASSWORD "password"
//
unsigned long tiempo1,tiempo2, tiempo3;
unsigned long final1, final2, final3;
unsigned long inicio, actual;

void subrutina1();
void subrutina2();
void subrutina3();


void setup(){
  tiempo1 = 2000;
  tiempo2 = 10000;
  tiempo3 = 3000000;
  inicio = millis();
// conexion red
Serial.begin(115200);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Conectando a la Wi-Fi");
  while (WiFi.status() != WL_CONNECTED)
  {
   // Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connectado con la IP: ");
  Serial.println(WiFi.localIP());
 //   
 actual = millis();
} // FIN SETUP

void loop()
{
   
   Serial.print("El tiempo actual es:");
   Serial.println( actual);
   if ((actual - inicio) >= tiempo1)
   {
      subrutina1();
      inicio = millis();
   }
   if ((unsigned long)(actual - inicio) >= tiempo2)
   {
      subrutina2();
      inicio = millis();
   }
   if ((unsigned long)(actual - inicio) >= tiempo3)
   {
      subrutina3();
      inicio = millis();
   }
   actual = millis();
 }  // FIN LOOP
 
 void subrutina1(){
  Serial.print('Paso 1');
  delay(6000);
  actual = millis();
  // cada 2 segundos ejecutar subruitna1  (x tiempo)
}

void subrutina2(){
  Serial.print('Paso 2');
  delay(6000);
  actual = millis();
  // cada 10 segundos ejecutar subrutina2 (y tiempo)
 }
 
 void subrutina3(){
  Serial.print('Paso 3');
  delay(6000);
  actual = millis();
  // cada 5 minutos  ejecutar subrrutina3 (z tiempo)
}

Podéis orientarme donde esta el fallo?.

Gracias..

Vamos por partes, dijo Jack el destripador.

Estás intentando ejecutar una rutina cada 2 seg pero la propia rutina tiene un delay de 6 seg.
Algo no esta bien...

Lo mismo ocurre con las otras dos, esos delays de 6 seg impiden que la 1ra se ejecute cada 2 seg.

Usas la variable inicio para calcular los retardos en todos los tiempos pero resulta que inicio se actualiza cada 2 segundos (en realidad cada 6 por lo del delay)
Usa final1, final2 y final3, según corresponda, en lugar de inicio.

A tiempo3 debes asignarle 300000 ms porque 3000000 ms son 50 min en lugar de 5 min.

Para las pruebas, comenta lo relacionado con el wifi, cuando lo demás funciona lo descomentas, así ves los resultados más rápido sin esperar que se conecte.
Lo mismo, has más corto tiempo3, así no esperas 5 min para saber que se ejecuta bien o no, luego lo cambias.

Saludos

Estupendo.
Muchas gracias. Tienes razón en el delay() y en los 50 minutos, ambas cosas arregladas.
El delay estaba puesto para ver,si es que pasaba por la subrutina el mensaje en el monitor de arduino.
Ahora veo que pasa por cada subrutina aunque hay que depurarlo un poco mas y meter el código que falta.
Iré comentando.

Un saludo,
Javier.

De nada!

Saludos

Por favor, si usas millis() no uses un solo delay() en tu código, ya nos lo agradecerás primero a nosotros y luego será para tu beneficio.
delay() es la perdición de Arduino, solo sirve para hacer que las cosas en general dejen de funciona y mas si quieres acciones diversas como en tu caso.
Delay detiene la ejecucion del programa asi que no tiene razón de ser.
Imagina un partido de futbol donde tienes un jugador que si le pasas la pelota el la esconde por el tiempo (delay) que le ordenes, que pasa con el partido?

Si estás usando un esp8266 puedes usar los timers que lleva el firmware.
Te pongo un ejemplo que llama a rutina1() cada 2 segundos, a rutina2 cada 10 segundos y rutina3 cada 5 minutos. Si lo haces así no hace falta llamar a ninguna rutina para actualizar tiempos. Estos temporizadores no son muy precisos pero para tiempos de 2 segundos no tiene importancia el error. Tambien puede usar la librería Ticker.h, creo que está incluida en el core de esp8666.
Aquí tienes el ejemplo

#include <Arduino.h>

os_timer_t timer1;
os_timer_t timer2;
os_timer_t timer3;

void rutina1(void *pArg){

}


void rutina2(void *pArg){

}

void rutina3(void *pArg){

}

void setup(){
  Serial.begin(115200);

  /* El tercer parametro de os_timer_setfn es el puntero que recibe la funcion
null si no quieres pasar nada
*/ 
  os_timer_setfn(&timer1, rutina1, NULL);
  os_timer_arm(&timer1, 2*1000, true);

  os_timer_setfn(&timer2, rutina2, NULL);
  os_timer_arm(&timer2, 10*1000, true);

  os_timer_setfn(&timer3, rutina3, NULL);
  os_timer_arm(&timer3, 5*60*1000, true);
}

void loop(){
}

Estupendo, muchas gracias por vuetro apoyo.
Voy a intentar aplicarlo y os respondo.
Supongo que tambien servira para un ESP32?.

Un saludo,
Javier.

No, para el esp32 no sirve. Pero no hace falta, el esp32 implementa RTOS.

Saludos.

Cual es el problema en usar millis() como todos te hemos dicho?

Ve a Documentación y lee los tutoriales de millis() es la respuesta a tu problema.
No vueles alto, con soluciones mas elaboradas, cuando una solucion simple resuelve tu problema.

un simple

if (millis() - varTiempo1 > INTERVALO1) {
    rutina1();
    varTiempo1 = millis();
}

se ejecuta cada INTERVALO1 milisegundos
repites eso n Veces y tienes todas tus rutinas a X, Y, Z milisegundos

Si, muchas gracias. Implementé los procedimientos con millis() y funciona.
Pero se agradecen otras aportaciones que pueden venir bien en otros casos.

Repito, muchas gracias a todos por vuestra ayuda.

Javier.