Building a CAN API for Arduino DUE

You need 120 Ohms resistors at each end of the bus.

If you have issues with your transceivers, to test your CAN software, make a CAN bus without transceivers (it works up to a few meters long):

https://www.mikrocontroller.net/attachment/28831/siemens_AP2921.pdf

Note that you would have to connect the resistor to 3.3V (and not 5V). Choose the resistor so that the current be lower than 1.6 mA.

Hey Thank you for your answer. Okey I added the 120 Ohm and I also have a lot of traffic on the can RX side already.

If I want to send a frame this won't work. Do you think that's because of the transceiver. Greetings

Untitled.png|1002x540

Do you think that's because of the transceiver ?. The most obvous answer is NO, but there must be something wrong in your wiring.

Check all contacts on your breadboard.

The bus is supposed to be a twisted pair, althought it should not be an issue on such a short distance.

Hey,

I just breaked out CANTX on the Oscilloscope and I have a Square Signal on that. If Break-Out CANH or CANH there's only noise.

Do I have to activate Receive and Send on the transceiver could that be possible?

Greetings.

That particular transceiver has no enable pin so it is essentially always on. If you have signals on CANRX and CANTX but the CANL and CANH lines are garbage then there is likely a wiring fault on the H/L side (the actual CAN bus). What you should get is a square wave on H/L when you use L for ground on your scope and H at the scope input. Or connect to your local board ground with the scope and L will sink then return to center and H will rise and return to center. They ought to rest at essentially the exact same voltage. At rest H = L so you will measure 0 volts. When active they pull away from each other as a squarewave that ought to look like an exact mirror image of each other. The more it differs from that ideal the worse off you are.

Be careful here, if you connect the scope ground to 'L' and the Due is powered from USB, you may be shorting 'L' via mains earth (if your local mains supply has this). You're better off 'scoping both the 'L' and 'H' simultaneously.

Can (no pun intended) we have 'scope traces of the noise?

I assume you've checked that there is in fact 3v3 across the modules supply pins. (I had a board with a 5v part fitted instead of 3v3 and all I got was noise).

If you are using the 230 part instead of the 234, note that pin 5 is not supposed to be connected to 3v3, it's a reference output, forcing this to 3v3 may be why it doesn't work as expected (and could damage it).

weird_dave: Be careful here, if you connect the scope ground to 'L' and the Due is powered from USB, you may be shorting 'L' via mains earth (if your local mains supply has this). You're better off 'scoping both the 'L' and 'H' simultaneously.

Can (no pun intended) we have 'scope traces of the noise?

I assume you've checked that there is in fact 3v3 across the modules supply pins. (I had a board with a 5v part fitted instead of 3v3 and all I got was noise).

If you are using the 230 part instead of the 234, note that pin 5 is not supposed to be connected to 3v3, it's a reference output, forcing this to 3v3 may be why it doesn't work as expected (and could damage it).

Hey thank you for the helpful information.

Currently PIN 5 of the transceiver is connected to 3v3 you think it has to be connected with 5V instead?

I could do some scope traces of the noise but I will try to use the 5V first. Do you mean the modules supply pins the pins of the arduino board or of the transceiver?

AdderD: That particular transceiver has no enable pin so it is essentially always on. If you have signals on CANRX and CANTX but the CANL and CANH lines are garbage then there is likely a wiring fault on the H/L side (the actual CAN bus). What you should get is a square wave on H/L when you use L for ground on your scope and H at the scope input. Or connect to your local board ground with the scope and L will sink then return to center and H will rise and return to center. They ought to rest at essentially the exact same voltage. At rest H = L so you will measure 0 volts. When active they pull away from each other as a squarewave that ought to look like an exact mirror image of each other. The more it differs from that ideal the worse off you are.

Yes so I'm gonna do some measurements on CANTX and CANRX on the Oscillator today again and post the scope here.

I'm going to check if CANL and CANH has 0 Volts when there is nothing send. But I already checked with the multimeter and if I was Sending Frames there was still 0 Volts. If I receive Messages via CANalzyer its about 190 mV. Receiving Messages is working fantastic, do you think this could be still a wiring fault on the H/L side?

Thank you so much for all the answers.

Hey Again,

maybe this is also important to know.

I used this CAN Transceiver Board KNACRO SN65HVD230 Bought them here https://www.amazon.com/KNACRO-SN65HVD230-Communication-transceiver-Arduino/dp/B01ILU2WP6/ref=cm_cr_arp_d_pdt_img_top?ie=UTF8

So the SN65HVD230 is already wired on a breakout board an I only added the capacitors in between.

Greetings

It seems that these transceivers have already 120 Ohms resistors, no need to add them. Remove capacitors and see what happens.

Stupid website logged me out while I was replying, I'm not going through all that again

Suffice to say, don't connect anything to pin 5, it's an output! CANH and CANL should never be both 0v or both 3v3.

disconnect everything on CANL and CANH at the module and attach 2 channels of a scope to them. I would also disconnect Rx and Tx from the module, get this working then attach the Rx and TX and see if it still works, then attach to CANL and CANH, at one of these stages it will fail, indicating where the problem is. I also advise taking a look at the datasheet for the IC.

Hey Guys,

So I just bought the Copperhiltech CAN Due Dual Channel Shield.

This worked perfect for me uploaded the code I already had and it worked instantly.

So I thank you all so much and this due is insane its just firing out the messages.

I was even printing all the frames on the serial and this was still getting all the messages forwarded.

Thank you so much.

Greetings

Hello

I have downloaded the due_can library in the eclipse Arduino Downloads Manager and now I'm trying to get the due_can -> CAN_EchoTest example running. I have connected the CANTX0 to CANRX1 and CANRX0 to CANRX0 to CANTX1 directly without transceiver. The SW gets stuck at the line: while (Can1.available() == 0) { } Is it possible to run this example without external CAN-transceivers?

See the Siemens Application Note AP2921 to operate a CAN bus without transceivers. You only need diodes and connect them to 3.3V, not 5V (works for wires of less than 2 meters long):

https://www.mikrocontroller.net/attachment/28831/siemens_AP2921.pdf

Note that CAN without transceivers is only viable for test with "short" wires. For an operationnal project, transceivers are far better.

I've got collin80's library working well with the MCP2562 transceivers. Currently pushing 116 frames through a gateway at 500kbps baud rate and no errors.

The 5V vs 3.3V difference may only bite you on the bum if trying to interface with some existing modules.

I am having a bit of a problem isolating a single byte in one frame so I can modify it and send it on with the rest. If I run this code, I only get all of the incoming frames passing through the modified frame.

I tried stuffing it into another variable called speed and resending that as well but it wouldn't modify the value at all and only sent what was coming in.

Is there a way with this library that you can filter either side of the required frame so everything else can gateway through except for that one frame?

//Reads all traffic on CAN0 and forwards it to CAN1 but modifies 0x461 byte 6 when detected.
// Required libraries
#include 
#include 

//Leave defined if you use native port, comment if using programming port
#define Serial SerialUSB

void setup()
{
  Serial.begin(115200);
  
  // Initialize CAN0 and CAN1, Set the proper baud rates here
  Can0.begin(CAN_BPS_500K);
  Can1.begin(CAN_BPS_500K);

   // Setup up output pin for gear position and speed zero output
   pinMode(2,OUTPUT);   //gearpos
   pinMode(3,OUTPUT);   //speedzero
  
  //By default there are 7 mailboxes for each device that are RX boxes
  //This sets each mailbox to have an open filter that will accept extended
  //or standard frames
  int filter;
  //extended
  //for (filter = 0; filter < 3; filter++) {
    //Can0.setRXFilter(filter, 0, 0, true);
    //Can1.setRXFilter(filter, 0, 0, true);
  //}  
  //standard
  for (int filter = 3; filter < 7; filter++) {
    Can0.setRXFilter(filter, 0, 0, false);
    Can1.setRXFilter(filter, 0, 0, false);
  }  
  
}

void printFrame(CAN_FRAME &frame) {
   Serial.print("ID: 0x");
   Serial.print(frame.id, HEX);
   Serial.print(" Len: ");
   Serial.print(frame.length);
   Serial.print(" Data: 0x");
   for (int count = 0; count < frame.length; count++) {
       Serial.print(frame.data.bytes[count], HEX);
       Serial.print(" ");
   }
   Serial.print("\r\n");
}

void loop(){
  CAN_FRAME incoming0;
  CAN_FRAME incoming1;
  //CAN_FRAME speed;
  //CAN_FRAME speedzero;
  //CAN_FRAME gearpos;

  if (Can0.available() > 0) {
    Can0.read(incoming0);
    //Can0.read(speed);
    //incoming0.id = 0x461;
    //incoming0.data.bytes[0] *= 2;
    //speed.data.bytes[1] *= 2;
    //speed.data.bytes[2] *= 2;
    //speed.data.bytes[3] *= 2;
    //speed.data.bytes[4] *= 2;
    //speed.data.bytes[5] *= 2;
    //speed.data.bytes[6] *= 2;
    //speed.data.bytes[7] *= 2;
    //Can0.read(gearpos);
    //gearpos.id = 0x4BC;
    //if (gearpos.data.bytes[1] = 8) {
    //    digitalWrite(2, HIGH);
    //Can0.read(speedzero);
    //speedzero.id = 0x4D0;
    //if (speedzero.data.bytes[1] = 0) {
    //    digitalWrite(3, HIGH);
    Can1.sendFrame(incoming0);
    //Can1.sendFrame(speed);
    //}
  }
  if (Can1.available() > 0) {
    Can1.read(incoming1);
    Can0.sendFrame(incoming1);
    printFrame(incoming1);  //uncomment line to print frames that are going out
   }
  //}
}

Here is a how to on doing a CAN gateway with example code.

http://togglebit.net/how-to-gateway-messages/

Yes, the gateway part is no problem at all. Although the collin80 library worked better with the MCP2562's and it also manages the differing DLC's. But none of that is the problem.

I can get all 116 frames through correctly but as soon as I try to manipulate one byte, it will transmit all the information for every frame on that one frame I've tried to change.

I figured thisout in the end, it was a silly syntax error that the compilier wasn't picking up.

Hi! I have created a db file using Qt cpp. Now I want to read and write this file on SD-Card using Arduino. Can you please guide me through.

//

Huge Thanks to Palliser , Massimo and Collin80 and all others for the time and effort put into this!

I am in the very early stages of this learning curve. I do a lot of reading and digging for answers, and I am pretty sure I know the answer to what I am about to ask. But I really wanted an opinion or at least some insight if possible..

Anywhoo, I have a handful of TI CAN Transceiver modules I got a few years back for a different project that never really took off.

These modules are really just a 4-pin breakout board with a TI SN65HVD230 in the middle of it. The 120ohm term resistor is there.

But there is also a 12K resistor pulling the Rs pin to low. This assumes that there will be a config in place to control slope.

I really do not want to get involved in slope or slew rates right now. To far above my head to mess with at the moment.

Do ya'll see any reason that I can't just pluck this little 12K out and just jump the pads instead?

Any and all input is appreciated....

Andy