Problema al leer puerto serial mientras se ejecuta delay()

Hola, buen día, he venido aquí debido a que como se darán cuenta todavía me falta mucho por aprender en esto de programar :slightly_frowning_face: , el caso es que trato de leer una cadena por el puerto Serial3 como esta: 10.0#001001100100 0.5#100100001001 ... para poder después guardarla en la EEPROM, luego leerla y enviarla por los puertos Serial1 y Serial2 del arduino mega.
El numero con punto decimal que viene siempre antes del # es el tiempo que debera pasar antes de enviar la siguiente parte, el problema es que debido a que utilizo la funcion delay() para la parte del tiempo cuando trato de enviar una nueva cadena para sustituir a la anterior en la EEPROM ya no se recibe bien, debido al delay, ya intente con millis() pero no me funciono como queria al igual que probé con interrupciones pero tampoco me funciono probablemente por mi inexperiencia :-[ , ¿si alguien pudiera ayudar a decirme como lograr que cuando reciba algo por Serial3 el programa se pare, escuche y luego se reinicie pero con los nuevos valores ?

#include <EEPROM.h>
String cad;
String scnc[27];
String sscnc;
char stscnc[325];
int storesec[352];
int stime[27];
String tabS[27];
int tmpo[27];
String secuencia[27];

void setup() {
    //Serial.begin(9600);
    Serial3.begin(9600);
    Serial2.begin(9600);
    Serial1.begin(9600);
    Serial3.setTimeout(30);
    pinMode(22,OUTPUT);
    pinMode(23,OUTPUT);
    if(EEPROM.read(350)!=0){
//////////////////////////////////////////////////////////////////////
         int f=0;                                                   //
          for(int rec=324; rec<=350; rec++){                        // Lectura de la EEPROM y almacenamiento en el array "tmpo" para el tiempo
           int a1=EEPROM.read(rec);                                 //
           int tiempo=map(a1,0,100,0,10000);                        //
           tmpo[f]=tiempo;                                          //
           f= f + 1;                                                //
           if(f==28){                                               //
            f=0;                                                    //
           }                                                        //
          }                                                         //
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
         int w=0;                                                   //
         int k=0;                                                   //
         String number2;                                            //
          for(int rec2=0; rec2<=323; rec2++){                       // Lectura de la EEPROM y almacenamiento en el string "secuencia"
           String number= String(EEPROM.read(rec2));                //
           number2= number2 + number;                               //
           w= w + 1;                                                //
           if(w==12){                                               //
            secuencia[k]= number2;                                  //
            w= 0;                                                   //
            k= k + 1;                                               //
            number2="";                                             //
           }                                                        //
          }                                                         //
//////////////////////////////////////////////////////////////////////
}
}
  
void loop() {
  storage();
  char zx[13];
  for(int h=0;h<=26;h++){
    secuencia[h].toCharArray(zx,13);
    Serial2.write(zx);
    Serial1.write(zx);
    delay(tmpo[h]); 
  }
}

void storage(){
    if(Serial3.available()>0){ //Verifica si hay datos en el puerto serial
          cad= Serial3.readString(); //Almacena los datos recibidos en forma de cadena en la variable "cad"
          //Serial.println(cad);  //Datos recibidos
///////////////////////////////////////////////
          int n = cad.indexOf(" ");          //
          for(int i=0;i<=26 ;i++){           //
            int n2= cad.indexOf(" ",n + 1);  //  Bucle para separar en un array la cadena recibida  
            scnc[i]= cad.substring(n,n2);    //
            n= n2;                           //
            //Serial.println(scnc[i]);       //
          }                                  //
///////////////////////////////////////////////
//////////////////////////////////////////////////////          
          for(int j=0; j<=26; j++){                 //
            int n3= scnc[j].indexOf("#");           // Se crea bucle para obtener un array con la secuencia y otro con el tiempo
            String tabT[27];                        // Se multiplican los tiempos por 1000 y se guardan en una variable entera
            tabT[j]= scnc[j].substring(1,n3);       // Se remapean los tiempos
            int tabtime[27];                        // Se crea un string para almacenar todas las secuencias en un solo conjunto
            tabtime[j]= (tabT[j].toFloat())*1000;   // El string anterior se convierte en un array de caracteres
            stime[j]= map(tabtime[j],0,10000,0,100);// Se convierte el array de caracteres en un array de numeros enteros
            tabS[j]= scnc[j].substring(n3+1);       // Se combina el array de tiempos con el de secuencia para almacenarlos en la EEPROM
            sscnc= sscnc + tabS[j];                 //
          }                                         //
          sscnc.toCharArray(stscnc,324);            //
          for(int p=0;p<=323;p++){                  //
            if(stscnc[p]=='1'){                     //
              storesec[p]= 1;                       //
            }                                       //
            else{                                   //
              storesec[p]= 0;                       //
            }                                       //
          }                                         //
          int itr=0;                                //
          for(int e=324;e<=350 ;e++){               //
            storesec[e]= stime[itr];                //
            itr= itr +  1;                          //
          }                                         //
//////////////////////////////////////////////////////
////////////////////////////////////////////////////////
          for(int addrs=0;addrs<=350;addrs++){        // Almacenamiento en la memoria EEPROM
            EEPROM.write(addrs,storesec[addrs]);      //
          }                                           //
////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
         int f=0;                                                   //
          for(int rec=324; rec<=350; rec++){                        // Lectura de la EEPROM y almacenamiento en el array "tmpo" para el tiempo
           int a1=EEPROM.read(rec);                                 //
           int tiempo=map(a1,0,100,0,10000);                        //
           tmpo[f]=tiempo;                                          //
           f= f + 1;                                                //
           if(f==28){                                               //
            f=0;                                                    //
           }                                                        //
          }                                                         //
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
         int w=0;                                                   //
         int k=0;                                                   //
         String number2;                                            //
          for(int rec2=0; rec2<=323; rec2++){                       // Lectura de la EEPROM y almacenamiento en el string "secuencia"
           String number= String(EEPROM.read(rec2));                //
           number2= number2 + number;                               //
           w= w + 1;                                                //
           if(w==12){                                               //
            secuencia[k]= number2;                                  //
            w= 0;                                                   //
            k= k + 1;                                               //
            number2="";                                             //
           }                                                        //
          }                                                         //
//////////////////////////////////////////////////////////////////////
}
}

Bienvenido a foro Arduino.
Veo que sabes programar bastante bien asi que tal vez una orientación te ayude.

El único sitio donde tienes problemas es

void loop() {
  storage();
  char zx[13];
  for(int h=0;h<=26;h++){
      secuencia[h].toCharArray(zx,13);
      Serial2.write(zx);
      Serial1.write(zx);
      delay(tmpo[h]); 
  }
}

Ahora tmpo[] puede ir desde 0 a 10000 o sea 10 segundos.. guauuu no entiendo que quieres hacer con eso?

envias caracteres por los puertos serie, y son todos los caracteres mas un final de carro 13.
Luego tu problema esta en el storage y te pierdes caracteres recibidos por no atenderlos.

A ver si esto sirve

// agrega como global

unsigned long start;

// setup y demas

void loop() {
  byte h = 0;
  char zx[13];
  
  storage();      // Consulto Serial3
  
  //for(int h=0;h<=26;h++){
  switch (estado) {
    case 0: secuencia[h].toCharArray(zx,13);
            Serial2.write(zx);
            Serial1.write(zx);
            estado = 1;
            start = tmpo[h]+millis(); // cargo tiempo
            break;
    case 1: if (millis() > start) {
                if (++h >= 26)
                    h = 0;
                estado = 0;
            }
            break;
  }
}

Lo que no se es si modificar tmpo en alguna de sus valores del array te cambia algo o no.
Aca todo será dinámico.

Antes tenias una secuencia de 26 tiempos, ahora puedes modicar cualquier indice en cualquier momento.

Gracias por contestar :slight_smile:
Es que por ejemplo necesito enviar: 001001100100 y ya después de 10 seg. enviar 100100001001, para que lo reciba otro Arduino, todos esos ceros y unos son los estados de sus pines.

Pues es que en tmpo guardo el valor del tiempo que debe pasar para poder después volver a enviar otra cosa por Serial1 y Serial2, entonces su valor solo debe cambiar si al recibir otra cadena por Serial3 es diferente.

Probé el código y cuando recibo otra cadena en Serial3 si la recibe bien y la almacena en la EEPROM pero no avanza, se queda en la primera parte del array secuencia, aunque al parecer la solución si va por ahí, seguiré checando.

tera199603:
todos esos ceros y unos son los estados de sus pines.

Si son consecutivos y están en grupos de 8 pines, conozco un atajo que ayudaría bastante: se trata de usar el valor del registro PORTx; donde x es la letra de cierto grupo de pines. Puedes ahorrar mucha memoria EEPROM guardando el estado de 8 pines en un solo byte.

Para imprimir la secuencia de bits basada en el estado de un grupo de pines sería de la siguiente manera:

Serial.println(PORTA, BIN);
// PORTA comprende los pines desde el 22 hasta el 29, siendo el 22 el LSB