[SOLUCIONADO] Codigo no me funciona en Arduino Mega y en UNO si

Buenas amigos

Tengo este código que en arduino UNO funciona perfectamente,pero si lo cargo en arduino Mega, en cuanto se intenta ejecutar los dos ultimos if, el arduino se reinicia.

No entiendo porque, haber si alguno se ustedes me puede dar una razón lógica.

Gracias

#include <SPI.h>
#include "mcp_can.h"

byte EntradaByte[3];    
int contador = 0;       
unsigned long timeout;

const int SPI_CS_PIN = 53;

MCP_CAN CAN(SPI_CS_PIN);

#define NUM_ID 20         // Definimos el numero de ID 

unsigned long oldId[] =   {0x20FEE411, 0x20FEE412, 0x20FEE413, 0x20FEE414, 0x20FEE415,
                           0x20FEE416, 0x20FEE417, 0x20FEE418, 0x20FEE419, 0x20FEE41A,
                           0x20FEE41B, 0x20FEE41C, 0x20FEE41D, 0x20FEE41E, 0x20FEE41F,
                           0x20FEE420, 0x20FEE421, 0x20FEE422, 0x20FEE423, 0x20FEE424};

unsigned long desviosId[NUM_ID];     


void setArrayValues() { // Se rellena el array con 0
  for (byte cont = 0; cont < NUM_ID ; cont ++) {
    desviosId[cont] = 0;
  }
}

int getIdPosition(unsigned long Id) {
  for ( int cont = 0; cont < NUM_ID; cont ++) {
    if (oldId[cont] == Id) {
      return cont;
    }
  }
  return -1;
}


void setup() {
  Serial.begin(115200);
  
  setArrayValues();
  
START_INIT:
  if (CAN_OK == CAN.begin(CAN_500KBPS)) {
    Serial.println("CAN BUS Shield init ok!");
  }
  else {
    Serial.println("CAN BUS Shield init fail");
    Serial.println("Init CAN BUS Shield again");
    delay(100);
    goto START_INIT;
  }
}

void loop() {


  while (Serial.available() > 0) {
    EntradaByte[contador] = Serial.read();  // leemos el puerto serie
    contador++;
    timeout = millis();
  }

  if ((millis() - timeout) > 300) { // Borramos el buffer del contador cada 300ms
    contador = 0;
  }


  if (contador == 3) {
    if (EntradaByte[0] == 0x60 && EntradaByte[2] == 0xFF) { // Si la entrada del puerto serie es 60 XX FF, haremos el desvio de ID correpondiente.
      switch (EntradaByte[1]) {
        case 0x01: desviosId[0] = 0x15FEE101; break;
        case 0x02: desviosId[1] = 0x15FEE101; break;
        case 0x03: desviosId[2] = 0x15FEE101; break;
        case 0x04: desviosId[3] = 0x15FEE101; break;
        case 0x05: desviosId[4] = 0x15FEE101; break;
        case 0x06: desviosId[5] = 0x15FEE101; break;
        case 0x07: desviosId[6] = 0x15FEE101; break;
        case 0x08: desviosId[7] = 0x15FEE101; break;
        case 0x09: desviosId[8] = 0x15FEE101; break;
        case 0x0A: desviosId[9] = 0x15FEE101; break;
        case 0x0B: desviosId[10] = 0x15FEE101; break;
        case 0x0C: desviosId[11] = 0x15FEE101; break;
        case 0x0D: desviosId[12] = 0x15FEE101; break;
        case 0x0E: desviosId[13] = 0x15FEE101; break;
        case 0x0F: desviosId[14] = 0x15FEE101; break;
        case 0x10: desviosId[15] = 0x15FEE101; break;
        case 0x11: desviosId[16] = 0x15FEE101; break;
        case 0x12: desviosId[17] = 0x15FEE101; break;
        case 0x13: desviosId[18] = 0x15FEE101; break;
        case 0x14: desviosId[19] = 0x15FEE101; break;
        default: break;
      }
    }
    if (EntradaByte[0] == 0x61 && EntradaByte[2] == 0xFF) { // Si la entrada del puerto serie es 61 XX FF, haremos el desvio de ID correpondiente.
      switch (EntradaByte[1]) {
        case 0x01: desviosId[0] = 0x15FEE102; break;
        case 0x02: desviosId[1] = 0x15FEE102; break;
        case 0x03: desviosId[2] = 0x15FEE102; break;
        case 0x04: desviosId[3] = 0x15FEE102; break;
        case 0x05: desviosId[4] = 0x15FEE102; break;
        case 0x06: desviosId[5] = 0x15FEE102; break;
        case 0x07: desviosId[6] = 0x15FEE102; break;
        case 0x08: desviosId[7] = 0x15FEE102; break;
        case 0x09: desviosId[8] = 0x15FEE102; break;
        case 0x0A: desviosId[9] = 0x15FEE102; break;
        case 0x0B: desviosId[10] = 0x15FEE102; break;
        case 0x0C: desviosId[11] = 0x15FEE102; break;
        case 0x0D: desviosId[12] = 0x15FEE102; break;
        case 0x0E: desviosId[13] = 0x15FEE102; break;
        case 0x0F: desviosId[14] = 0x15FEE102; break;
        case 0x10: desviosId[15] = 0x15FEE102; break;
        case 0x11: desviosId[16] = 0x15FEE102; break;
        case 0x12: desviosId[17] = 0x15FEE102; break;
        case 0x13: desviosId[18] = 0x15FEE102; break;
        case 0x14: desviosId[19] = 0x15FEE102; break;
        default: break;
      }
    }

// CON ESTOS DOS ULTIMOS if AL RECIVIR LOS DATOS DE LA PANTALLA EL ARDUINO SE REINICIA, SOLO PASA CON ARDUINO MEGA CON UNO NO
    
    if (EntradaByte[0] == 0x62 && EntradaByte[2] == 0xFF) { // Si la entrada del puerto serie es 62 XX FF, haremos el desvio de ID correpondiente.
      switch (EntradaByte[1]) {
        case 0x01: desviosId[0] = 0x15FEE103; break;
        case 0x02: desviosId[1] = 0x15FEE103; break;
        case 0x03: desviosId[2] = 0x15FEE103; break;
        case 0x04: desviosId[3] = 0x15FEE103; break;
        case 0x05: desviosId[4] = 0x15FEE103; break;
        case 0x06: desviosId[5] = 0x15FEE103; break;
        case 0x07: desviosId[6] = 0x15FEE103; break;
        case 0x08: desviosId[7] = 0x15FEE103; break;
        case 0x09: desviosId[8] = 0x15FEE103; break;
        case 0x0A: desviosId[9] = 0x15FEE103; break;
        case 0x0B: desviosId[10] = 0x15FEE103; break;
        case 0x0C: desviosId[11] = 0x15FEE103; break;
        case 0x0D: desviosId[12] = 0x15FEE103; break;
        case 0x0E: desviosId[13] = 0x15FEE103; break;
        case 0x0F: desviosId[14] = 0x15FEE103; break;
        case 0x10: desviosId[15] = 0x15FEE103; break;
        case 0x11: desviosId[16] = 0x15FEE103; break;
        case 0x12: desviosId[17] = 0x15FEE103; break;
        case 0x13: desviosId[18] = 0x15FEE103; break;
        case 0x14: desviosId[19] = 0x15FEE103; break;
        default: break;
      }
    }
    if (EntradaByte[0] == 0x63 && EntradaByte[2] == 0xFF) { // Si la entrada del puerto serie es 63 XX FF, haremos el desvio de ID correpondiente.
      switch (EntradaByte[1]) {
        case 0x01: desviosId[0] = 0x15FEE104; break;
        case 0x02: desviosId[1] = 0x15FEE104; break;
        case 0x03: desviosId[2] = 0x15FEE104; break;
        case 0x04: desviosId[3] = 0x15FEE104; break;
        case 0x05: desviosId[4] = 0x15FEE104; break;
        case 0x06: desviosId[5] = 0x15FEE104; break;
        case 0x07: desviosId[6] = 0x15FEE104; break;
        case 0x08: desviosId[7] = 0x15FEE104; break;
        case 0x09: desviosId[8] = 0x15FEE104; break;
        case 0x0A: desviosId[9] = 0x15FEE104; break;
        case 0x0B: desviosId[10] = 0x15FEE104; break;
        case 0x0C: desviosId[11] = 0x15FEE104; break;
        case 0x0D: desviosId[12] = 0x15FEE104; break;
        case 0x0E: desviosId[13] = 0x15FEE104; break;
        case 0x0F: desviosId[14] = 0x15FEE104; break;
        case 0x10: desviosId[15] = 0x15FEE104; break;
        case 0x11: desviosId[16] = 0x15FEE104; break;
        case 0x12: desviosId[17] = 0x15FEE104; break;
        case 0x13: desviosId[18] = 0x15FEE104; break;
        case 0x14: desviosId[19] = 0x15FEE104; break;
        default: break;
      }
    }
  
  contador = 0; // Vuelve a poner el contador a cero
}

unsigned char len = 0;
unsigned char buf[8];

if (CAN_MSGAVAIL == CAN.checkReceive()) {         // chequeamos la entra CAN
  CAN.readMsgBuf(&len, buf);                     // Leemos la trama
  unsigned long oldId = CAN.getCanId();
  int idToFind = getIdPosition(oldId);

  if (desviosId[idToFind] != 0) { // Si en el array desviosId hay un valor diferente de 0 es que hay una id nueva guardada y se envia la trama tambien.
    CAN.sendMsgBuf(desviosId[idToFind], 1, len, buf);
  }
}
}

Para mi la forma en que lees el puerto no es de mi agrado, pero si dices que funciona el en UNO poco puedo afirmar.

No entiendo porque tienes un contador = 0 al final del código y un timeout donde tmb pone a 0 el mismo contador cada 300 mseg. Evidentemente es posible que lea datos erróneos por ruido.
Si es asi agrega en el código que te sugiero el timeout para sostener el criterio que ya tenías.

Esta es mi sugerencia para el loop modificado. Solo procesará datos si se da el 3er byte 0xFF

void loop() {
    unsigned char len = 0;
    unsigned char buf[8];

    if (Serial.available() > 0) {
        byte c = Serial.read(); // leemos el puerto serie
        EntradaByte[contador++] = c;  
        if (c = 0xFF) {  // solo cuando tenga 3 valores procesa mas abajo.
            flag = true;
            contador = 0;
        }
    }

    if (flag) {
        switch(EntradaByte[0]) {
            case 0x60: // Si la entrada del puerto serie es 60 XX FF, haremos el desvio de ID correpondiente.
                        if (EntradaByte[1] < 0x15)
                            desviosId[EntradaByte[1]-1] = 0x15FEE101;
                        break;
            case 0x61: // Si la entrada del puerto serie es 61 XX FF, haremos el desvio de ID correpondiente.
                        if (EntradaByte[1] < 0x15)
                            desviosId[EntradaByte[1]-1]= 0x15FEE102;
                        break;
            // CON ESTOS DOS ULTIMOS if AL RECIVIR LOS DATOS DE LA PANTALLA EL ARDUINO SE REINICIA, SOLO PASA CON ARDUINO MEGA CON UNO NO                            
            case 0x62: // Si la entrada del puerto serie es 62 XX FF, haremos el desvio de ID correpondiente.
                        if (EntradaByte[1] < 0x15)
                            desviosId[EntradaByte[1]-1]= 0x15FEE103;                
                        break;
            case 0x63: // Si la entrada del puerto serie es 63 XX FF, haremos el desvio de ID correpondiente.
                        if (EntradaByte[1] < 0x15)
                            desviosId[EntradaByte[1]-1]= 0x15FEE104;
                        break;
        }
        flag = false; 
    }
  
    if (CAN_MSGAVAIL == CAN.checkReceive()) {          // chequeamos la entra CAN
        CAN.readMsgBuf(&len, buf);                     // Leemos la trama
        unsigned long oldId = CAN.getCanId();
        int idToFind = getIdPosition(oldId);

        if (desviosId[idToFind] != 0) {                 // Si en el array desviosId hay un valor diferente de 0 es que hay una id nueva guardada y se envia la trama tambien.
            CAN.sendMsgBuf(desviosId[idToFind], 1, len, buf);
        }
    }
}

Buenas surbyte

surbyte:
No entiendo porque tienes un contador = 0 al final del código y un timeout donde tmb pone a 0 el mismo contador cada 300 mseg. Evidentemente es posible que lea datos erróneos por ruido.

Lo hice por eso por el tema de los ruidos.

He estudiado lo que has echo para recibir los datos del serial y la verdad asi en mucho mejor y me ahorro mucho codigo, pero hay una cosa que entiendo por que lo has echo, pero que no me funciona.

if (EntradaByte[1] < 0x15)
desviosId[EntradaByte[1]-1] = 0x15FEE101;

Si lo entiendo bien, aqui lo que haces en decir que desviosId en el byte 1 (supongamos 01) menos 1 seria 0 y debería de lanzar la trama con la ID 0x15FEE101, ya que equivale a desvioId[0] del mi código.

Pues eso no me funciona, recibe el byte, pero no lanza desvioId, si quito EntradaByte[1]-1 y coloco un 0 si funciona y no entiendo por que no funciona lo que me has puesto.

Gracias

Dejame probar algo y te hago alguna modificación, espera unos minutos que lo pongo aquí mismo.

Bueno este es un código algo modificado donde muestro lo que debe presentar. No tengo CAN asi que simulo lecturas

#include <Arduino.h>

byte EntradaByte[3];   
int contador = 0;       
unsigned long timeout;
bool flag;

#define NUM_ID 20         // Definimos el numero de ID
unsigned long oldId[] = {0x20FEE411, 0x20FEE412, 0x20FEE413, 0x20FEE414, 0x20FEE415,
                         0x20FEE416, 0x20FEE417, 0x20FEE418, 0x20FEE419, 0x20FEE41A,
                         0x20FEE41B, 0x20FEE41C, 0x20FEE41D, 0x20FEE41E, 0x20FEE41F,
                         0x20FEE420, 0x20FEE421, 0x20FEE422, 0x20FEE423, 0x20FEE424};

unsigned long desviosId[NUM_ID];     

void setArrayValues() { // Se rellena el array con 0
  for (byte cont = 0; cont < NUM_ID ; cont ++) {
    desviosId[cont] = 0;
  }
}

int getIdPosition(unsigned long Id) {
  for ( int cont = 0; cont < NUM_ID; cont ++) {
    if (oldId[cont] == Id) {
      return cont;
    }
  }
  return -1;
}

byte datos[] = {0x60, 0x02, 0xFF, 0x61, 0x03, 0xff, 0x62, 0x04, 0xff, 0x63, 0x05, 0xFF};

byte generoBytesAlAzar() {
    static byte counter = 0;
    byte tmp;
    
    tmp = datos[counter];
    if (counter++ >= 11) counter = 0;
    return tmp;

}

void setup() {
  Serial.begin(9600);
  Serial.println("Comanzando la recepcion CAN");
}

void loop() {
    char buffer[50];

    byte c = generoBytesAlAzar();
    EntradaByte[contador++] = c; 
    if (c == 0xFF) {  // solo cuando tenga 3 valores procesa mas abajo.
        flag = true;
        contador = 0;
        sprintf(buffer, "%02x %02x %02X", EntradaByte[0],EntradaByte[1],EntradaByte[2]);
        Serial.println(buffer);
    }
    

    if (flag) {
        sprintf(buffer,"Estoy en 0x%x", EntradaByte[0]);
        Serial.println(buffer);
        if (EntradaByte[1] < 0x15) {
            sprintf(buffer,"Resultado de [EntradaByte[1]-1] = %d", EntradaByte[1]-0x01);
            Serial.println(buffer);
            desviosId[EntradaByte[1]-1] = 0x15FEE101+EntradaByte[0]-0x60;
            sprintf(buffer,"Dato en desviosId[EntradaByte[1]-1] = %lx", desviosId[EntradaByte[1]-0x01]);
            Serial.println(buffer);
        }
        flag = false;
        Serial.println();

    }
}

Observa que trabaja correctamente con los resultados esperados.
Prueba a ver si funciona como esperas.
Hasta donde yo lo he probado todo funciona como debería.

Buenas, he tardado en contestar, por que me gusta estudiar lo que me mandas, ya que habia cosas como sprintf, que lo estudie para comprender tu codigo.

Tu código en si funciona, pero cuando lo pasa al CAN no hace los desvíos, no entiendo porque.

Si elimino -1 aqui y envio los bytes en vez del 01 al 14, lo hago del 00 al 15 ( esto lo puedo modificar sin problemas.

desviosId[EntradaByte[1] - 1] = 0x15FEE101

Funciona solo en primer desvió, o sea si lanzo la trama 0x20FEE411 la convierte en la 0x15FEE101, pero con la demas no hace si caso.

La verdad no entiendo por que no funciona.

Hice esto para probar y funciona, no entiendo por que de la otra forma que es mas logico no funciona.

Decirte que lo de enviar 60 XX FF, realmente solo voy a usar 60 XX el FF lo puse para un futuro si me hacia falta, no se si es relevante o no la verdad.

void loop() {


  if (Serial.available() > 0) {
    EntradaByte[contador] = Serial.read();  // leemos el puerto serie
    contador++;
    timeout = millis();
  }

  if ((millis() - timeout) > 300) { // Borramos el buffer del contador cada 300ms
    contador = 0;
  }

  if (contador == 3) {
    if (EntradaByte[0] == 0x60 && EntradaByte[2] == 0xFF) {
      switch (EntradaByte[0]) {
        case 0x60:
          if (EntradaByte[1] < 0x15) {
            desviosId[EntradaByte[1] - 1] = 0x15FEE101;
          }
          break;
      }
    }
    if (EntradaByte[0] == 0x61 && EntradaByte[2] == 0xFF) {
      switch (EntradaByte[0]) {
        case 0x61:
          if (EntradaByte[1] < 0x15) {
            desviosId[EntradaByte[1] - 1] = 0x15FEE102;
          }
          break;
      }
    }
    if (EntradaByte[0] == 0x62 && EntradaByte[2] == 0xFF) {
      switch (EntradaByte[0]) {
        case 0x62:
          if (EntradaByte[1] < 0x15) {
            desviosId[EntradaByte[1] - 1] = 0x15FEE103;
          }
          break;
      }
    }
    if (EntradaByte[0] == 0x63 && EntradaByte[2] == 0xFF) {
      switch (EntradaByte[0]) {
        case 0x63:
          if (EntradaByte[1] < 0x15) {
            desviosId[EntradaByte[1] - 1] = 0x15FEE104;
          }
          break;
      }
    }

    contador = 0; // Vuelve a poner el contador a cero
  }

Buenas surbyte, pues remontando a la primera prueba que me mandaste, decirte que funciona, no me di cuenta de este fallo. Me he pegado unas cuantas horas hoy por que no entendía por que no funcionaba

if (Serial.available() > 0) {
        byte c = Serial.read(); // leemos el puerto serie
        EntradaByte[contador++] = c; 
        if (c = 0xFF) {  // En esta linea cometí el fallo, me falto un signo "="
            flag = true;
            contador = 0;
        }
    }

El código entonces quedaría asín, añadí un case mas para poder parar los desvíos de las ID

void loop() {


  if (Serial.available() > 0) {
    byte c = Serial.read(); // leemos el puerto serie
    EntradaByte[contador++] = c;
    if (c == 0xFF) {  // solo cuando tenga 3 valores procesa mas abajo.
      flag = true;
      contador = 0;
    }
  }

  if (flag) {
    switch (EntradaByte[0]) {
      case 0x60:
        if (EntradaByte[1] < 0x15)
          desviosId[EntradaByte[1] - 1] = 0x15FEE101;
        break;

      case 0x61:
        if (EntradaByte[1] < 0x15)
          desviosId[EntradaByte[1] - 1] = 0x15FEE102;
        break;

      case 0x62:
        if (EntradaByte[1] < 0x15)
          desviosId[EntradaByte[1] - 1] = 0x15FEE103;
        break;

      case 0x63:
        if (EntradaByte[1] < 0x15)
          desviosId[EntradaByte[1] - 1] = 0x15FEE104;
        break;

      case 0x64:
        if (EntradaByte[1] < 0x15)
          desviosId[EntradaByte[1] - 1] = 0;
        break;
        
    }
    flag = false;
  }

Ahora me queda monitorizar los datos del buffer de cada desvio de Id por el puerto serie, subire mañana lo que tenia echo con el otro codigo, haber como lo puedo adaptar a este.

Gracias.

Buenas pues iba a subir el problemas de que tenia de interpretar las tramas, pero esta ya resuelto en el ultimo pos que puse y me ayudaste.

Así que este post lo doy por solucionado por que funciona perfectamente tanto en Arduino Mega como Uno.

Muchas Gracias Surbyte por tu ayuda.

Saludos