Transferring data over CAN bridge

I am trying to set up a CAN bridge between 2 different pieces of equipment. The data only needs to flow one way and is only related to one measurement.

I have set up the CAN bridge sketch but am stuck on how to transfer the data over.

The received data typically is;

Standard ID: 0x351 DLC: 8 Data: 0x10 0x02 0x72 0x01 0x72 0x01 0xC2 0x01

And that would need to be sent as;

CAN0.sendMsgBuf(0x05044000, 1, 8, "value");

Where “value” is 0x29, 0x15, 0x00, 0x10, 0x02

Any help would be gratefully received.

// CAN Bridge
//

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

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];


unsigned char login[][8] = {
 {0x16, 0x36, 0x71, 0x07, 0x03, 0x76, 0x00, 0x00},  
 {0x18, 0x10, 0x50, 0x01, 0x76, 0x09, 0x00, 0x00},
 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},  
 {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};         //The serial numbers are unique for each PS and must be set for your units

byte txBuf0[] = {66,55,66,55,66,55,66,55};
byte txBuf1[] = {55,66,55,66,55,66,55,66};

char msgString[128];                         // Array to store serial string

char msgStringV1[128];                       // Array to store serial string Volts
char msgStringV2[128];
char msgStringI1[128];                       // Array to store serial string Amps
char msgStringI2[128];

#define CAN0_INT 3                           // Set INT to pin 3 ELTEK
#define CAN1_INT 2                           // Set INT to pin 2 PYLONTECH

MCP_CAN CAN0(9);                             // CAN0 interface usins CS on digital pin 9   ELTEK
MCP_CAN CAN1(10);                            // CAN1 interface using CS on digital pin 10  PYLONTECH


void setup()

{
  Serial.begin(115200);
  
  // init CAN0 bus, baudrate: 125k@8MHz ELTEK
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK)
    {
    Serial.print("CAN 0 ELTEK: Init OK!\r\n");
    CAN0.setMode(MCP_NORMAL);
    }
  else
    Serial.println("Error Initializing MCP2515..CAN 0 Eltek");  
  
  
  // init CAN1 bus, baudrate: 500k@16MHz PYLONTECH
  if(CAN1.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK)
    {
    Serial.print("CAN 1 PYLON: Init OK!\r\n");
    CAN1.setMode(MCP_LISTENONLY);
    }
  else
    Serial.println("Error Initializing MCP2515..CAN 1 Pylon");

  CAN0.enOneShotTX();
    
  
  SPI.setClockDivider(SPI_CLOCK_DIV2);         // Set SPI to run at 8MHz (16MHz / 2 = 8 MHz)
  
  CAN0.sendMsgBuf(0x1000000, 1, 8, txBuf0);  
  //CAN1.sendMsgBuf(0x1000001, 1, 8, txBuf1);
}


void loop()
{
  
  if(!digitalRead(2))                         // If pin 2 is low, read CAN1 receive buffer PYLONTECH
  {
    CAN1.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)
//  /*
    if(rxId == 0x351 || rxId == 0x359 || rxId == 0x355 || rxId == 0x356 || rxId == 0x35A || rxId == 0x35B || rxId == 0x35C || rxId == 0x35E || rxId == 0x35F || rxId == 0x00F || rxId == 0x305 || rxId == 0x306)  // rxId == 0x305 || rxId == 0x306 ||
    if(rxId == 0x351)
    {
    if((rxId & 0x80000000) == 0x80000000)     // Determine if ID is standard (11 bits) or extended (29 bits)
      sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
    else
      sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);
  
    Serial.print(msgString);
  
    if((rxId & 0x40000000) == 0x40000000)    // Determine if message is a remote request frame.
    {
      sprintf(msgString, " REMOTE REQUEST FRAME");
      Serial.print(msgString);      
    }
    
    else
    {
      for(byte i = 0; i<len; i++)
      {
        sprintf(msgString, " 0x%.2X", rxBuf[i]);
        Serial.print(msgString);        
      }
    }
       
    Serial.println();
    }

//    */
    
//    /*
    if(rxId == 0x351)
    
    {
    Serial.println();
    
    if((rxId & 0x80000000) == 0x80000000)     // Determine if ID is standard (11 bits) or extended (29 bits)
      sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
    else
      sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);
  
    Serial.print(msgString);
  
    if((rxId & 0x40000000) == 0x40000000)    // Determine if message is a remote request frame.
      {
      sprintf(msgString, " REMOTE REQUEST FRAME");
      Serial.print(msgString);      
      }    
      
     Serial.println();
      
        sprintf(msgStringV1, " 0x%.2X", rxBuf[0]);
        sprintf(msgStringV2, " 0x%.2X", rxBuf[1]);
        Serial.print ("Voltage setting, volts    ");
        Serial.print(msgStringV1);
        Serial.println(msgStringV2);

     CAN0.sendMsgBuf(0x05004804, 1, 8, login[1]);      // Immediately send message out CAN0 interface ELTEK Login
     delay (50);
     CAN0.sendMsgBuf(0x05004808, 1, 8, login[2]);      // Immediately send message out CAN0 interface ELTEK Login
     delay (50);
     CAN0.sendMsgBuf(0x0500480C, 1, 8, login[3]);      // Immediately send message out CAN0 interface ELTEK Login
     delay (50);
     
     CAN0.sendMsgBuf(0x05044000, 1, 8, "value");      // Immediately send message out CAN0 interface ELTEK Volts
     delay (50);
     CAN0.sendMsgBuf(0x05084000, 1, 8, "value");      // Immediately send message out CAN0 interface ELTEK Volts
     delay (50);
     CAN0.sendMsgBuf(0x050C4000, 1, 8, "value");      // Immediately send message out CAN0 interface ELTEK Volts
     delay (50);

/*
        sprintf(msgStringI1, " 0x%.2X", rxBuf[2]);
        sprintf(msgStringI2, " 0x%.2X", rxBuf[3]);
        Serial.print ("Current setting, amps     ");
        Serial.print(msgStringI1);
        Serial.println(msgStringI2);

     //CAN0.sendMsgBuf(0x1000000, 1, 8, txBuf0);
     
     //CAN0.sendMsgBuf(rxId, 1, len, rxBuf);      // Immediately send message out CAN0 interface ELTEK Current
     
*/      
     
       
    Serial.println();

    
  
    }
    //CAN0.sendMsgBuf(0x1000000, 1, 8, txBuf0);
    //CAN1.sendMsgBuf(0x1000001, 1, 8, txBuf1);
//  */   
  }
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

Your values of interest seem to be in the rxBuf array at index 0 and 1 so you will need to copy them over to your output array and then send tem

... code to determine the correct msg
txBuf0[0] = 0x29;
txBuf0[1] = 0x15;
txBuf0[2] = 0x00;
txBuf0[3] = rxBuf[0];
txBuf0[4] = rxBuf[1];
....
CAN0.sendMsgBuf(0x05044000, 1, 8, txBuf);

It looks like that command is sending 8 bytes, so you should pad it out with 0x00 as well

Thank you. I'm certain that will work but I've struck a problem, the data isn't complete.

I'm not where I have something wrong with my set up but I've gone back to the very basics of an example send and receive sketch and the output I'm getting is as below and this is what I'm getting with my sketch.

22:26:57.854 -> Standard ID: 0x100 DLC: 8 Data: 0x02 0x03


// CAN Send Example
//

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

MCP_CAN CAN0(10);     // Set CS to pin 10

void setup()
{
  Serial.begin(115200);

  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 Initialized Successfully!");
  else Serial.println("Error Initializing MCP2515...");

  CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
}

byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};

void loop()
{
  // send data:  ID = 0x100, Standard CAN Frame, Data length = 8 bytes, 'data' = array of data bytes to send
  byte sndStat = CAN0.sendMsgBuf(0x100, 0, 8, data);
  if(sndStat == CAN_OK){
    Serial.println("Message Sent Successfully!");
  } else {
    Serial.println("Error Sending Message...");
  }
  delay(100);   // send data per 100ms
}

and

// CAN Receive Example
//

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

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[12];
char msgString[128];                        // Array to store serial string

#define CAN0_INT 2                              // Set INT to pin 2
MCP_CAN CAN0(10);                               // Set CS to pin 10


void setup()
{
  Serial.begin(115200);
  
  // Initialize MCP2515 running at 16MHz with a baudrate of 125kb/s and the masks and filters disabled.
  if(CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK)
    Serial.println("MCP2515 Initialized Successfully!");
  else
    Serial.println("Error Initializing MCP2515...");
  
  CAN0.setMode(MCP_NORMAL);                     // Set operation mode to normal so the MCP2515 sends acks to received data or Listenonly mode for no acks.

  pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input
  
  Serial.println("MCP2515 Library Receive Example...");
}

void loop()
{
  if(!digitalRead(CAN0_INT))                         // If CAN0_INT pin is low, read receive buffer
  {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)

    //if(rxId == 0x351 || rxId == 0x359 || rxId == 0x355 || rxId == 0x356 || rxId == 0x35A || rxId == 0x35B || rxId == 0x35C || rxId == 0x35E || rxId == 0x35F || rxId == 0x00F)  // rxId == 0x305 || rxId == 0x306 ||

    //if(rxId == 0x351)
    
    {
    if((rxId & 0x80000000) == 0x80000000)     // Determine if ID is standard (11 bits) or extended (29 bits)
      sprintf(msgString, "Extended ID: 0x%.8lX  DLC: %1d  Data:", (rxId & 0x1FFFFFFF), len);
    else
      sprintf(msgString, "Standard ID: 0x%.3lX       DLC: %1d  Data:", rxId, len);
  
    Serial.print(msgString);
  
    if((rxId & 0x40000000) == 0x40000000){    // Determine if message is a remote request frame.
      sprintf(msgString, " REMOTE REQUEST FRAME");
      Serial.print(msgString);
    } else {
      for(byte i = 2; i<=3; i++){
        sprintf(msgString, " 0x%.2X", rxBuf[i]);
        Serial.print(msgString);
      }
    }
       
    Serial.println();
    }
  }
}

And what is the problem? You send a message and the receiver got it an displayed byte #2 and #3 which match what was sent.

I thought it'd sent 8 bytes. AH!! spotted it.

for(byte i = 2; i<=3; i++){