Interrupt routine Question

hello everyone,

i have question about interrupt routine.

Im using Arduino Uno + Seeeduino CAN-Bus Shield. The hardware should listen to all the messages on CAN-Bus and print them to serial port. At the same time every 20ms send a message with a counter. To send a message i've used interrupt routine and it works, but the main loop function prints few times to Serial and then stops.

Can someone tell where is the problem? I would realy appreciate your help.
Thank you in advance

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



MCP_CAN CAN(9);                                    // Set CS pin
unsigned char stmp[6] = {01, 00, 00, 00, 00, 00};
unsigned char len = 0;
unsigned char buf[8];


void setup()
{
Timer1.initialize(20000);
 Timer1.attachInterrupt(senden);
  Serial.begin(115200);
  
  

START_INIT:

  if(CAN_OK == CAN.begin(CAN_500KBPS))                   // init can bus : baudrate = 500k
  {
      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 senden() {
 CAN.sendMsgBuf(0xF0, 0, 6, stmp);
 stmp[5] = stmp[5] + 1;
}


void loop()
{
  
  if (CAN_MSGAVAIL == CAN.checkReceive())           // check if data coming
  {
    CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf
    unsigned char canId = CAN.getCanId();
    Serial.println();
    Serial.print("get data from ID: ");
    Serial.print(canId, HEX);
    Serial.print("------->  ");
    if (canId == 253) {                                               //FD
      unsigned   a = buf[0] * 256 + buf[1];
      float voltage = a * 0.1;
      Serial.print(voltage, 2);
      Serial.print("V");
      Serial.print('\t');

      unsigned long  b = buf[2] * 256 + buf[3];
      float current = b * 0.1;
       current = 500 - current;
      Serial.print(current, 3);
      Serial.print("A");
      Serial.print('\t');

      unsigned long  c = buf[4] * 256 + buf[5];
      float voltage2 = c * 0.1;
      Serial.print(voltage2, 2);
      Serial.print("V");
      Serial.println('\t');
    }
 else if (canId == 240) {    //F0
for(int i = 0; i<len; i++)    // print the data
        {
            Serial.print(buf[i]);
            Serial.println("\t");
        }
 }
    else if (canId == 250) {      //FA

      float soc = buf[6] * 0.5;
      Serial.print("SOC - ");
      Serial.print(soc, 1);
      Serial.print("%");
      Serial.print('\t');

      long hvilstatus = buf[2] >> 6;
      Serial.print("HViLStatus - ");
      switch (hvilstatus) {
        case 00:
          Serial.print("FAIL");
          Serial.print('\t');
          break;
        case 01:
          Serial.print("Pass");
          Serial.print('\t');
          break;
        case 10:
          Serial.print("Error");
          Serial.print('\t');
          break;
        case 11:
          Serial.print("Unavailable");
          Serial.print('\t');
          break;
      }
      long cellBalancing = buf[3] >> 6;
      Serial.print("CellBalncingStatus - ");
      switch (cellBalancing) {
        case 00:
          Serial.print("Not Active");
          break;
        case 01:
          Serial.print("Active");
          break;
        case 10:
          Serial.print("Error");
          break;
        case 11:
          Serial.print("Unavailable");
          break;
      }
      Serial.println();
    }

    else if (canId == 251) {                                        //FB
      unsigned long  a = buf[0] * 256 + buf[1];
      float maxDisPower = a * 0.01;
      Serial.print(maxDisPower, 2);
      Serial.print("kW");
      Serial.print('\t');

      unsigned long  b = buf[2] * 256 + buf[3];
      float maxRegPower = b * 0.01;
      Serial.print(maxRegPower, 2);
      Serial.print("kW");
      Serial.print('\t');

      unsigned long  c = buf[4];
      long resistance = c * 4;
      Serial.print(resistance, DEC);
      Serial.print("Ohm");
      Serial.print('\t');

      unsigned long  d = buf[5] * 256 + buf[6];
      long activeFault = d;
      Serial.print(activeFault, DEC);
      Serial.println('\t');

    }

    else if (canId == 252) {                                      //FC
      unsigned long  a = buf[0] * 256 + buf[1];
      float maxDisPower = a * 0.01;
      Serial.print(maxDisPower, 2);
      Serial.print("kW");
      Serial.print('\t');

      unsigned long  b = buf[2] * 256 + buf[3];
      float maxRegPower = b * 0.01;
      Serial.print(maxRegPower, 2);
      Serial.print("kW");
      Serial.println('\t');
    }
   else if (canId == 254) {                                               //FE
      unsigned   a = buf[0] * 256 + buf[1];
      unsigned   b = buf[2] * 256 + buf[3];
      float maxCellVoltage = a * 0.001;
      float minCellVoltage = b * 0.001;
      float dUdt = maxCellVoltage - minCellVoltage;
      Serial.print("dV/dt:");
      Serial.print( dUdt, 4);
      Serial.print('\t');
      
      unsigned long  e = buf[6];
      float temperature = 0.5 * e - 40;
      Serial.print("Temperature:");
      Serial.print(temperature, 1);
      Serial.println(" C");
   }
    else {
    };

  }
  
}

Can someone tell where is the problem?

How does CAN.sendMsgBuf() work? Does it rely on interrupts? Interrupts are disabled during an interrupt service routine, so if this function is buffering data and returning, relying on interrupts sending the data, and the buffer gets full, and this routine then blocks, that would explain the issue you are having. The HardwareSerial class, that Serial is an instance of, does just that.

The goto and label are completely unnecessary. A while loop would make it look like you knew what you were doing.

      Serial.print("V");
      Serial.println('\t');
    }
 else if (canId == 240) {    //F0
for(int i = 0; i<len; i++)    // print the data
        {
            Serial.print(buf[i]);

Tools + Auto Format would cure this drunken sailor hangover issue.

I have added here C++ file with all the functions

mcp_can.cpp (30.9 KB)

So, that calls two more undefined functions... Not much help.

i have modified my previous post

Just a note, this does probably not what you intend

      switch (hvilstatus) {
        case 00:
          Serial.print("FAIL");
          Serial.print('\t');
          break;
        case 01:
          Serial.print("Pass");
          Serial.print('\t');
          break;
        case 10:
          Serial.print("Error");
          Serial.print('\t');
          break;
        case 11:
          Serial.print("Unavailable");
          Serial.print('\t');
          break;
      }

Didn't you want something like the following?

      switch (hvilstatus) {
        case 0b00:
          Serial.print(F("FAIL"));
           break;
        case 0b01:
          Serial.print(F("Pass"));
          break;
        case 0b10:
          Serial.print(F("Error"));
          break;
        case 0b11:
          Serial.print(F("Unavailable"));
          break;
      }
      Serial.write('\t');