Go Down

Topic: Building a CAN API for Arduino DUE (Read 325404 times) previous topic - next topic

Palliser

#570
Oct 08, 2016, 10:41 pm Last Edit: Oct 08, 2016, 10:42 pm by Palliser
Hello!

Could you explain, why you decided to connect the VREF pin to +3.3V?
I'm using SN65HVD230 right now, according to datashet, VREF is connected to some sort of internal voltage regulator which maintains VCC/2 (e.g. around 1.65V) on VREF. But when microcontroller is sending data, I've connected my oscilloscope to VREF and it kind of follows the input on the TX pin, with a large amplitude - around 1-2V. Because of this (I suppose) the outputs on CANL and CANH is very distorted, and is not correctly decoded by receiver.

But if I connect VREF to VCC, it starts working, pure magic! But this contradicts the datasheet, which says to leave VREF unconnected (for simple cases). So, I wonder, how you came to this solution - to connect VREF to VCC?

Hello anpaza,

Pin 5 in the SN65HVDx 3.3-V CAN transceiver series has different functions depending on the specific model of transceiver. For example, in the model that I used SN65HVD234, the pin 5 corresponds to the EN or ultra-low current sleep mode Input pin for the device. I powered it with 3.3V to disable this mode (transceiver asleep when pin is LOW). In your model, SN65HVD230 pin 5 is an Output (not an Input), a Vcc/2 voltage reference. As the specs indicate in 10.3.1., this Vref pin can be connected to the common mode point of the split termination resistance in order to help with further stabilization of the common mode voltage of the bus (showed in figure 44 of page 34). If the Vref pin is not used it may be left floating.

Here the link of the Texas Instruments Inc. specification to which I refers.

http://www.ti.com/lit/ds/symlink/sn65hvd231.pdf

-p

anpaza

#571
Oct 10, 2016, 10:40 pm Last Edit: Oct 11, 2016, 12:06 am by anpaza
I did more investigations.

If I disconnect VREF from VCC, the device can receive, but cannot send. In particular, with a two-device network (other device sending and my device receiving) this leads to receiver being unable to set the ACK flag at the end of datagram, to signal that the datagram was correctly received. Thus, sender automatically sends the datagram again and again to infinity.

But in a more-than-two-devices network in a listen-only configuration that could work. Bus contents are deciphered correctly, only can't send correctly.

For full functionality, however, you have to connect VREF to VCC. I don't understand why it is this way, but that's a fact. My ICs are marked "VP230 61M", I think 61M is batch number (maybe it's a failed batch, I don't know).

Here's the oscillogram from SN65HVD230 sending some data at 1MBit speed with pin VREF connected to VCC.
https://s12.postimg.org/vpvwwhjt9/image.png
Red and yellow graphs are CANL/CANH, and green graph is math (CANH-CANL).
Looks ok to me but, however, I can't compare with other transceivers as I have only VP230s here.

duramaxhd

Hello Ben,

Have you made progress in solving your problem?
If not, can you show us the code or a snippet of your filtering (receive)? Thanks.

-p
Hi- Yes, I figured it out!

Here is what I did:

Code: [Select]
// Required libraries
#include "variant.h"
#include <due_can.h>

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


char MSG[8];

void setup()
{

  Serial.begin(115200);
 
  // Initialize CAN0, Set the proper baud rates here
  Can0.begin(CAN_BPS_500K);

 
Can0.setRXFilter(0x4A1, 0x7ff, false);// can0 to only receive $4A1 CAN ID
  } 

//============================================================================================
//============================================================================================


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 g = 0; g < frame.length; g++) {
       Serial.print(frame.data.bytes[g], HEX);
       Serial.print(" ");
   }
   Serial.print("\r\n");


  frame.id = 677;                  // assign new CAN ID $2A5 to original message received on $4A1
  frame.extended = false;
  frame.length = 8;
   frame.data.byte[8] = int (MSG);
   Can0.sendFrame(frame);
}
//============================================================================================
//============================================================================================


void loop(){
  CAN_FRAME incoming;
  if (Can0.available() > 0) {
Can0.read(incoming); //read in can information
  printFrame(incoming);
}
}

duramaxhd

Hello Ben,

Have you made progress in solving your problem?
If not, can you show us the code or a snippet of your filtering (receive)? Thanks.

-p
One other quick question...

Have you had any success using the 100-pin SAM3X8C? Or do you have ideas of what needs to be changed in the libraries to reconfigure things?

It would be awesome to be able to get this CAN stuff working on the smaller Cortex M3 chip....

Barre

Hi Gentleman's !
Please need help !!!

trying to send some can bus frames from SD to can bus, but "SD read" and "can send" make some collision
SD works ,can works -but not together
the failure is empty data information reading can bus id and ext works
any suggestions ? more description in code


code;
void setup()
{
    //***********************  SD  **********************
  Serial1.begin(9600);
  Can0.begin(CAN_BPS_125K);
  Can0.watchFor(); 
  mydisp.clearScreen();
}

void sendData()
{
  SysCall::yield();
  if (!sd.begin(chipSelect, SPI_SIXTEENTH_SPEED)) {
    sd.initErrorHalt();
  }
 openfile:
   mydisp.clearScreen();
  if (! printFile.open("Run.txt", O_READ))
  { sd.errorHalt("opening test.txt for read failed");
  mydisp.println("card failure ");
  }
   while (printFile.available()) {
 
   
   // buffer = printFile.readStringUntil('\n');                      //  this row failure funktion wile reading file
   buffer = "03C3F7FC;F9;00;00;19;40;27;78;15;0000064C;;";           // this string from file work, if before read is blocked "//"

     
     
     CAN_FRAME outgoing;

 outgoing.id = strtol(buffer.substring(0,8).c_str(), NULL, 16);
  outgoing.extended = true;
  outgoing.priority = 4; //0-15 lower is higher priority
 
 outgoing.data.byte[0] =  strtol(buffer.substring(9,11).c_str(), NULL, 16);
  outgoing.data.byte[1] =  strtol(buffer.substring(12,14).c_str(), NULL, 16);
   outgoing.data.byte[2] =  strtol(buffer.substring(15,17).c_str(), NULL, 16);
    outgoing.data.byte[3] =  strtol(buffer.substring(18,20).c_str(), NULL, 16);
     outgoing.data.byte[4] =  strtol(buffer.substring(21,23).c_str(), NULL, 16);
      outgoing.data.byte[5] =  strtol(buffer.substring(24,26).c_str(), NULL, 16);
       outgoing.data.byte[6] =  strtol(buffer.substring(27,29).c_str(), NULL, 16);
        outgoing.data.byte[7] =  strtol(buffer.substring(30,32).c_str(), NULL, 16);

      delay (1000);
      mydisp.print(outgoing.id,HEX);mydisp.print(" "); mydisp.print(outgoing.data.low,HEX);mydisp.println(outgoing.data.high,HEX);// print works
Can0.sendFrame(outgoing);

     delay (1000);

  printFile.close();


}
void loop()
{

  sendData();
    delay (1000);
  }
 

kindred7

#575
Apr 17, 2017, 04:04 am Last Edit: Apr 17, 2017, 04:11 am by kindred7
Code: [Select]
// Required libraries
  #include "variant.h"
  #include "due_can.h"
  #include <HardwareSerial.h>
  //#include "Time.h"
  int checker = 1;
  unsigned long currentMillis = 0;
  unsigned long previousMillis = 0;
  static const int interval = 5000;
  //Leave defined if you use native port, comment if using programming port
 // #define Serial SerialUSB

  CAN_FRAME incoming0, incoming1; // might not need, canframe defined in function
  
  //Define DCDC messages
  #define dcdc_1  0x12231930
  #define dcdc_hi 0x00000000

void setup() {
  Serial.begin(115200);
  Can0.begin(CAN_BPS_500K); // Initialize CAN0 and CAN1, Set the proper baud rates here
  Can1.begin(CAN_BPS_500K);  
  //Can0.set_baudrate(33333);
  //Can0.set_baudrate(1000000);
  //Can0.enable();
  Can0.watchFor(0x102);
  Can1.watchFor(0x103);
}

void sendData()
{
  CAN_FRAME outgoing;
  outgoing.id = 0x400;
  outgoing.extended = false;
  outgoing.priority = 4; //0-15 lower is higher priority
  outgoing.data.s0 = 0xFEED;
  outgoing.data.byte[2] = 0xDD;
  outgoing.data.byte[3] = 0x55;
  outgoing.data.high = 0xDEADBEEF;
  Can0.sendFrame(outgoing);
}

void sendDCDC(){
  CAN_FRAME dcdc;
  dcdc.id = 0x112;
  dcdc.extended = true; //what is exteneded frames?
  dcdc.priority = 4;
  dcdc.length = 8;
  dcdc.data.low = dcdc_1;
  dcdc.data.high = dcdc_hi;
  Can0.sendFrame(dcdc);
  //Serial.println(Can0.sendFrame(dcdc),HEX);
  //Serial.println(dcdc.data.low,HEX);
}

void loop() {
  //CAN_FRAME incoming;
  
//  if (Can0.available() > 0)  {//This meanss there is data existing on CAN0 RX.
//  //Serial.println("CAN0 data recieved and read");
//  Can0.read(incoming);
//  Can1.sendFrame(incoming);
//   }
//  if (Can1.available() > 0) {//This means there is data existing on CAN1 RX.
//  Serial.println("CAN1 data recieved and read");
//  Can1.read(incoming);
//  Can0.sendFrame(incoming);
//  }
  currentMillis = millis();
  if (currentMillis - previousMillis >= interval){
    Serial.print("CurrentMillis:");
    Serial.println(currentMillis);
    Serial.print("PreviousMillis:");
    Serial.println(previousMillis);
    Serial.println("");
    Serial.print(interval);
    Serial.println("");
    Can0.read(incoming0);
    previousMillis = currentMillis;
      if (checker == 1){
         Serial.println("Checker is on");
         sendDCDC();
         delayMicroseconds(100);
         checker = 0;
      }
   }
}


Hi everyone,

I am fairly new to arduino but not programming in general. Above you can see the code I am using for testing transmission of a CAN frame I need to test.

The problem I am having right now is an odd one I think. Currently I cannot stop the transmission of my CAN frame. I have placed an interval to delay the sending of the CAN frame. It is supposed to send one frame every 5 seconds. This portion works and is confirmed by my print statements. I even placed a checker variable near the end to block the "sendDCDC()" function call just to make sure I am not somehow looping the send command for the frame.

I feel like I am losing my mind, can anyone lend a hand? Thank for your time!

AdderD

The problem I am having right now is an odd one I think. Currently I cannot stop the transmission of my CAN frame. I have placed an interval to delay the sending of the CAN frame. It is supposed to send one frame every 5 seconds. This portion works and is confirmed by my print statements. I even placed a checker variable near the end to block the "sendDCDC()" function call just to make sure I am not somehow looping the send command for the frame.

I feel like I am losing my mind, can anyone lend a hand? Thank for your time!
You're not losing your mind. It is very likely that the problem is that nothing else on the bus is acknowledging the frame. If nobody claims it then the sending node will attempt to resend on the assumption that transmission had failed. It will do this rapid fire forever until someone says they're listening. So, you need something on the other end that isn't in listen-only mode.

kindred7

You're not losing your mind. It is very likely that the problem is that nothing else on the bus is acknowledging the frame. If nobody claims it then the sending node will attempt to resend on the assumption that transmission had failed. It will do this rapid fire forever until someone says they're listening. So, you need something on the other end that isn't in listen-only mode.
Thanks Collin80 for clearing the murky waters a bit! Also thanks for all the work you put into this CAN back end, it's awesome. Cheers!

SergeyPP

Thanks for the library. It helps me to understand how to use CAN.


I had a problem with sending messages in CAN.  All examples I tried sent nothing.
I found the default tx mailboxes is 0.

Can0.setNumTXBoxes(1); helped me.


Like this:

Code: [Select]
void setup()
{
 pinMode(13,OUTPUT);
 Serial.begin(115200);
 
 Serial.print("\n Go ...");

 Can0.begin(CAN_BPS_1000K);
 Can0.setNumTXBoxes(1);

 Can0.watchFor();
}



Hardware is Arduino Due + SN65HVD230

AdderD

Woah, thanks for reporting that! I can't believe I missed that. You're right, a recent batch of changes accidentally caused the number of TX boxes to be set to zero by default. That is corrected now.

methods

Nice thread!  First time seeing it.

5 years in development eh....  Thanks for posting.  That's a big contribution.


I will share anything I learn along the way.  I need to implement on a 5V chip that is low cost so we will see how it goes.  I have done many Arduino based designs but usually don't release them out of embarrassment for lack of polish - or rather they are over-specific to whatever I am doing.

This one is prototype of Master in a distributed LTC based BMS with lots of competing requirements other than CAN functionality.  Low BOM cost and 5V peripheral compatibility a must - so I will get to reading and see if this is an easy chore or complicated one.

Arduino FTW...  I convert people all the time.

thanks,
-methods

SergeyPP

One more think I met in sendFrame.
If it is set CANPort->setNumTXBoxes(3) then one call Can0.sendFrame(FrameToSend) is sending the three frames to bus.

It is possible I use not the last version of the sources.

There is no brake at !!!! in code below.

Code: [Select]

bool CANRaw::sendFrame(CAN_FRAME& txFrame)
{
...
    for (uint8_t mbox = 0; mbox < 8; mbox++) {
...
          result=true; //we've sent it. mission accomplished.
          !!!!
        }
...
}

AdderD

Spasibo!

Yes, you're right. There is a missing break and it seems it has caused your problem. Thank you for reporting this. I've updated the code. Recently I merged in a lot of changes from other people and apparently it didn't all get tested thoroughly enough.

ofir060

Hi, I've tried testing this library by uploading CAN_ExtendedPingPong to my due, and shorting CANRX with pin 53 and CANTX with DAC0.
The pingpong doesn't seem to work, Could anyone know why?

ard_newbie

#584
Sep 28, 2017, 02:20 pm Last Edit: Sep 28, 2017, 02:33 pm by ard_newbie
Are you using transceivers  or diodes ?  Are you using the programming port or the native USB port ?
What is exactly your wiring ?


Go Up