Programa deja de andar al cabo de un tiempo.

Hola, lamento no ser mas claro en el titulo, pero realmente estoy perdido con la causa del fallo.

El programa esta andando, hace lo que quiero. Pero al cabo de un tiempo (no he encontrado un patron, pueden ser un par de minutos hasta quizas media hora) el arduino se cuelga y no hace mas nada.

No parece que se quede en un loop haciendo nada, mas bien como que se detiene completamente.

Otra curiosidad es que no siempre se cuelga en la misma parte del programa, ni se cuelga de la misma manera. A veces basta con pulsar el boton de reset y en otros casos es necesario quitar la alimentacion por completo (cuando sucede esto, el led que viene en la placa (Arduino Nano) queda parpadeando, aun cuando no es utilizado en el programa).

Les dejo el codigo:

#include <SoftwareSerial.h>

// Puerto debug.
SoftwareSerial debug(2, 3);
// Puerto powermeter.
SoftwareSerial port485(5, 6);

String inputString = "";         // a String to hold incoming data
bool stringComplete = false;  // whether the string is complete
String simt_reply = ">0,3,220.1,220.2,214.3,1,999#";

#define PM_CANT 9
#define SENS_X_MOD  3
#define enable485 4
char trama[50];
int z = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long Millisprevio = 0;
int interval = 1000;
unsigned char reply[9];
int index = 0;
char flotante[6];
char valores[PM_CANT][6];
char reply_simt[100];
int n_peticion = 0;
int tpo_reset = 300;

///////////////////TRAMAS DE PETICION POWERMETER///////////////////////

byte peticion[9][8] = {
  //TENSIONES
  {0x01, 0x03, 0x00, 0x09, 0x00, 0x02, 0x14, 0x09},  //0:Ua
  {0x01, 0x03, 0x00, 0x0B, 0x00, 0x02, 0xB5, 0xC9},  //1:Ub
  {0x01, 0x03, 0x00, 0x0D, 0x00, 0x02, 0x55, 0xC8},  //2:Uc
  //CORRIENTES
  {0x01, 0x03, 0x00, 0x0F, 0x00, 0x02, 0xF4, 0x08},  //3.Ia
  {0x01, 0x03, 0x00, 0x11, 0x00, 0x02, 0x94, 0x0E},  //4:Ib
  {0x01, 0x03, 0x00, 0x13, 0x00, 0x02, 0x35, 0xCE},  //5:Ic
  //CosFI,Frecuencia,Energia
  {0x01, 0x03, 0x00, 0x1B, 0x00, 0x02, 0xB4, 0x0C},  //6:fp
  {0x01, 0x03, 0x00, 0x1D, 0x00, 0x02, 0x54, 0x0D},  //7:hz
  {0x01, 0x03, 0x00, 0x21, 0x00, 0x02, 0x94, 0x01}   //8:ea
};
char comandos[9][7] =
{
  ">PT0<",
  ">PT1<",
  ">PT2<",
  ">PT3<",
  ">PT4<",
  ">PT5<",
  ">PT6<",
  ">PT7<",
  ">PT8<"
};

void setup() {
  Serial.begin(9600);
  debug.begin(9600);
  port485.begin(9600);
  debug.println("ARDUINO OK");
  delay(200);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
  pinMode(enable485, OUTPUT);
}


void enviar485(int k) {    
  digitalWrite(enable485, HIGH);   
  for (int i = 0; i < 8; i++) {   
    port485.write(peticion[k][i]);
  }
  port485.flush();
}

void leer485() {

  digitalWrite(enable485, LOW);   //RS485 como Receptor
  delay(20);
  int contador = 0;
  int indice = 0;
  char dato = '\0';
  memset(reply, 0, sizeof(reply));
  while (port485.available() > 0) {

    dato = port485.read();
    reply[indice] = dato;
    indice++;
  }

  for (int i = 0; i < 9; i++)
  {
    debug.print(reply[i], HEX);
  }
  debug.println("");

  port485.flush();
}

void floatAstring(unsigned char respuesta[]) {
  float data;
  union u_tag {
    byte b[4];
    float fval;
  } u;

  u.b[3] = respuesta[3];      //Guardo los bytes de interes
  u.b[2] = respuesta[4];      //para interpretarlos como float.
  u.b[1] = respuesta[5];
  u.b[0] = respuesta[6];

  data = u.fval;
  flotante[6];
  dtostrf(data, 4, 1, flotante);   

  debug.println("FLOTANTE CON ESPACIO: ");
  debug.println(flotante);

}

void armo_respuesta(int response) {

  const char cabecera = '>';
  char id = response + '0';
  const char coma[2] = ",";
  char sensXmodulo[2] = "3";
  const char findetrama[7] = "1,999#";

  memset(reply_simt, 0, sizeof(reply_simt));
  memcpy(reply_simt, &cabecera, 1);
  memcpy(reply_simt + sizeof(cabecera), &id, sizeof(id));
  strcat(reply_simt, coma);
  strcat(reply_simt, sensXmodulo);
  strcat(reply_simt, coma);

  for (int h = 0; h < SENS_X_MOD; h++) {
    strcat(reply_simt, valores[response * SENS_X_MOD + h]);
    strcat(reply_simt, coma);
  }
  strcat(reply_simt, findetrama);

  debug.println("RESPUESTA SIM: ");
  debug.println(reply_simt);

  Serial.println(reply_simt);
  delay(250);
  Serial.println(reply_simt);
  delay(250);
  Serial.println(reply_simt);
  delay(250);

}

void loop() {
  if (stringComplete) {
    debug.println(inputString);
    for (int y = 0; y < SENS_X_MOD; y++) {
      if (inputString.indexOf(comandos[y]) >= 0) {
        n_peticion = y;
        debug.println("RESPUESTA OK !");
        debug.println("REPLY: ");
        // debug.println(simt_reply);

        for (int k = 0 ; k < PM_CANT; k++) {
          delay(30);
          enviar485(k);
          leer485();
          floatAstring(reply);
          char *cosa_sin_espacios = flotante;
          while (*cosa_sin_espacios == ' ') {
            cosa_sin_espacios++;
          }
          for (int i = 0; i < 6; i++) {
            valores[k][i] = cosa_sin_espacios[i];
          }
          debug.println("VALORES K: ");
          debug.println(valores[k]);
        }

        armo_respuesta(n_peticion);

      }
    }
    inputString = "";
    stringComplete = false;
  }
}

void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '<') {
      stringComplete = true;
    }
  }
}

Llevo mas de 2 meses intentando variantes pero el problema persiste, y ya estoy rozando la desesperacion. Asi que cualquier comentario se agradece!

¿Cómo estás alimentado el circuito?. Muchas veces una mala alimentación puede provocar que se cuelgue, de forma totalmente aleatoria. De todas formas no das nada de información sobre qué es lo que estás haciendo, si tienes montado algo más que el arduino, etc etc etc

Hola, nakuadak.
Me di cuenta que no habia explicado lo que intento hacer despues de postear.

El arduino es un intento de “traductor” entre 2 equipos. Mas o menos asi:

EQUIPO SIMT<>ARDUINO<>POWERMETER

  1. Equipo SIMT envia al puerto serie del arduino una peticion Por ej: “>PT0<”
  2. El arduino compara lo que le llegó para saber si se trata de una peticion correcta o no.
  3. Si es correcta, envia por puerto serie por Software varias peticiones de datos a POWERMETER (en hex)
  4. Powermeter contesta (en hex)
  5. Guardo los datos obtenidos y “traducidos” a ascii en un arreglo.
  6. Segun la peticion que haya enviado Equipo SIMT, respondo por puerto serie con los valores pedidos.

El primer problema que veo y no digo que este mal es que tienes dos SoftwareSerial funcionando.

Cuando usas dos SoftwareSerial, recuerda que no pueden funcionar simultáneamente, y que debes usar un flag para accionarlos.Ese flag es el siguiente objeto.listen

Cada vez que esperas reacción de un objeto SoftwareSerial lo llamas usando por ejemplo debug.listen(); y port.listen();

Aca puedes leerlo con mayor detalle link

Enables the selected software serial port to listen. Only one software serial port can listen at a time; data that arrives for other ports will be discarded. Any data already received is discarded during the call to listen() (unless the given instance is already listening).

Habilita el puerto SoftwareSerial seleccionado para ser escuchado. Solo un puerto serie puede ser escuchado por vez, los datos que lleguen al otro puerto serán descartados. Cualquier dato que ya ha llegado es descartado durante el llamado a listen() (a menos que la instancia dada ya este escuchando).