MKR CAN Shield: Errors

Try to use a MKR zero and the MKR CAN SHIELD to send J1939 CAN Messages. I started with the example file for the CAN send in library MCP_CAN_lib. I changed the CS Pin to 3 as it defaults to 10 but still receiving "error sending message...". Any help is appreciated.

// CAN Send Example
//

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

MCP_CAN CAN0(3);     // Set CS to pin 3 for MKR

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) for (int i = 0; i <= 20; i++){
    Serial.println("MCP2515 Initialized Successfully!");
    delay(500);
  }
  else for (int i = 0; i <= 20; i++) {
    Serial.println("Error Initializing MCP2515...");
    delay(500);
    }
  

  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(500);   // send data per 100ms
}

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

Hi, did you read this post ?

I am finally looking at this again. Thanks! This helped; definitely an issues in the library I was using.

What is the best way to go from float to hex to send out on my CAN message? I am reading an analog input then taking it to a float to scale then want to send it out as a CAN message.

You need to have a look at how can works - how you send it out depends on how you will read it back , you can split your number into several fields to transmit , putting the length in the “ message”, ( as you can see in your sketch) but you need to also read in the same way .
If you are trying to simulate an existing can message ( eg into a car ECU) then look at its format , then how you might translate your number to that format.

Floats are stored in memory as 4 bytes on Arduino , so you can just send these bytes . There are ways to store data in specific locations ( not sure how without googling) , which you could then copy into your message field , but that may give you a solution …I’m unsure ..you may even be able to print a float variable in hex directly ???

Probably you need to say a few more details !

I have the structure of the CAN message determined.
Thanks I was able to look into splitting the float into its bytes and then used that in my CAN message.

Now I just need to determine why my value seems to be off. I am getting the integer I expect on the serial monitor but a much larger value on the CAN monitor I am using. This is what I have so far.

#include <SPI.h>
#include <mcp2515.h>

int AIn1 = A1;        //Joystick 1 to Analog Input 1
int Joystick1AIn = 0; //Joystick 1 Analog Input Integer
float Joystick1PSN = 0;  //Joystick 1 Position
byte PSN1[3]; //Joystick1 Position Bytes
byte CAN_B[7]; //CAN Message Bytes
bool msgbit[7];
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(3);

void setup() {

  canMsg1.can_id  = 0x18EEFF48 | CAN_EFF_FLAG;
  canMsg1.can_dlc = 8;
  canMsg1.data[0] = 0x96;
  canMsg1.data[1] = 0x72;
  canMsg1.data[2] = 0x80;
  canMsg1.data[3] = 0x2D;
  canMsg1.data[4] = 0x00;
  canMsg1.data[5] = 0x8D;
  canMsg1.data[6] = 0x00;
  canMsg1.data[7] = 0x30;

// This message toggle postions.
  canMsg2.can_id  = 0x0CFF0048 | CAN_EFF_FLAG;
  canMsg2.can_dlc = 8;
//canMsg2.data[0] = 0b00010000;
//canMsg2.data[1] = 0x00;
  canMsg2.data[2] = 0x01;
  canMsg2.data[3] = 0x00;
  canMsg2.data[4] = 0x01;
  canMsg2.data[5] = 0x00;
  canMsg2.data[6] = 0xFF;
  canMsg2.data[7] = 0xFF;
  
  while (!Serial);
  Serial.begin(115200);
  
  mcp2515.begin();
  mcp2515.setBitrate(CAN_250KBPS);
  mcp2515.setNormalMode();
  
  Serial.println("Example: Write to CAN");
}

void loop() {
 
  mcp2515.sendMessage(MCP2515::TXB1,&canMsg1);
  mcp2515.sendMessage(&canMsg2);

  Serial.println("Messages sent");

  Joystick1AIn = analogRead(AIn1);
  Serial.println(String(Joystick1AIn) + " AIn1");
  if (Joystick1AIn > 530) {
    Joystick1PSN = ((float)Joystick1AIn - 512) * 19.75; // 19.5503 is correct value
  } else if (Joystick1AIn < 494){
    Joystick1PSN =10100 - ((float)Joystick1AIn * 19.55);
  } else {
    Joystick1PSN =0;
  }
  Serial.println(String((int)Joystick1PSN) + " PSN1");
//PSN1[3] = ((int)Joystick1PSN >> 24) & 0xFF;
//PSN1[2] = ((int)Joystick1PSN >> 16) & 0xFF;
  PSN1[1] = ((int)Joystick1PSN >> 8) & 0xFF;
  CAN_B[1] = ((int)Joystick1PSN & 0xFF);
  msgbit[0] = bitRead(PSN1[1], 0);
  msgbit[1] = bitRead(PSN1[1], 1);
  bitWrite(CAN_B[0], 0, msgbit[0]);
  bitWrite(CAN_B[0], 1, msgbit[1]);
  
  canMsg2.data[0] = CAN_B[0];  
  canMsg2.data[1] = CAN_B[1];

  Serial.println(String(PSN1[0]) + " PSN1");
  Serial.println(String(msgbit[0]) + " BIT0");
  Serial.println(String(msgbit[1]) + " BIT1");
  delay(100);
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.