CAN message using 2 Arduino Nano

Dear members!
I want to send a message through CAN using 2 Arduino Nano cards. The first one will be used for keypad and Adafruit ILI9340 display communicating via SPI. The second one (slave I2C) vill takes some data and send it to MCP2515 CAN chip. The problem is that I wat to convert a char array to an integer. I am using atoi to covert the array and it works if I have declared the array as “char date = {‘2’,‘0’,‘1’,‘9’};”. The output instead “a = 20l9 my_int = 2019” is “a = 20l9 my_int = 20a = 20l9 my_int = 20”.
So if there is someone who can help me to fix that I will be very grateful.
Here is my code so far for the Master:

#include <Wire.h>
char date[] = { '2', '0', 'l', '9', '\0' };
void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
  sendData();
}
void loop() {
}

void sendData () {
  Wire.beginTransmission(8); // transmit to device #8
  Wire.write(date, 4);       // sends four bytes
  Wire.endTransmission();    // stop transmitting
  delay(2000);
}

Slave:

#include <SPI.h>
#include <mcp2515.h>
#include <Wire.h>
char b[10]="";
char c[10]="";
char a[4] = "";
//  char date[] = { '2', '0', 'l', '9'};
//  int my_int = atoi(date);
  int menupage=5;

MCP2515 mcp2515(10);

void int2Bytes(int val,byte* bytes_array){
  // Create union of shared memory space
  union {
    int int_variable;
    byte temp_array[4];
  } u;
  // Overite bytes of union with in variable
  u.int_variable = val;
  // Assign bytes to input array
  memcpy(bytes_array, u.temp_array, 4);
}

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output

  SPI.begin();//----------Start CAN------------------------
  mcp2515.reset();
  mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
  mcp2515.setNormalMode();
  //-----------------------End CAN----------------------------
}

void loop() {
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
  
  while (Wire.available()) { // loop through all but the last
    for (int j=0; j<4;j++){
      c[j] = Wire.read(); // receive byte as a character
    }
    delay(100);
   }

  memcpy(a, c, 4);
  Serial.print("a = ");
  for(int i = 0; i<4; i++){
  Serial.print(a[i]);
}
  struct can_frame frame;
  frame.can_id = 0x100;
  frame.can_dlc = 2;
  frame.data[0] = 0x00;
  //int my_int = 2019;
  //char date[] = {'2','0','1','9'};
  int my_int = atoi(a);
  int2Bytes(my_int, &frame.data[0]);
  
  Serial.print(" my_int = ");
  Serial.print(my_int);
  
  /* send out the message to the bus and
  tell other devices this is a standard frame from 0x00. */
  mcp2515.sendMessage(&frame);
  delay(100);
}

The function

int atoi( const char *str )

interprets an integer value in a byte string pointed to by

str

,

 str

being pointer to the null-terminated byte string.

Can you now see what you are doing not quite right on the slave side...? :wink:

Hello!
Thank you for your answer! Should I use the function int "atoi( const char *str )" instead "atoi(a)"?

Tonyboy:
Hello!
Thank you for your answer! Should I use the function int “atoi( const char *str )” instead “atoi(a)”?

I think you missed the point…

in your slave code:

  while (Wire.available()) { // loop through all but the last
    for (int j=0; j<4;j++){
      c[j] = Wire.read(); // receive byte as a character
    }
    delay(100);
   }

only picks up ‘2’ ‘0’ ‘1’ ‘9’ (that’s all you sent across btw)

and when you then use

  memcpy(a, c, 4);
  Serial.print("a = ");
  for(int i = 0; i<4; i++){
  Serial.print(a[i]);
  }

all is still good since you are simply printing the characters.

but then you do

int my_int = atoi(a);

WITHOUT adding ‘\0’ at the end! hence the source of your error I believe…

so to me this is how it should be on the slave side:

char a[5] = "";//array length is FIVE not FOUR


memcpy(a, c, 4);

a[4] = '\0'; //add the null terminator to the last array element

int my_int = atoi(a); //shuold now give you the correct value

hope that helps…

Worked perfectly, thank you! I am wondering why Serial prints char a and my_int twice?
Output: a = 2019 my_int = 2019a = 2019 my_int = 2019