Coder Social home page Coder Social logo

arduino-can's Introduction

Arduino CAN

Build Status

An Arduino library for sending and receiving data using CAN bus.

Compatible Hardware

Microchip MCP2515 wiring

Microchip MCP2515 Arduino
VCC 5V
GND GND
SCK SCK
SO MISO
SI MOSI
CS 10
INT 2

CS and INT pins can be changed by using CAN.setPins(cs, irq). INT pin is optional, it is only needed for receive callback mode. If INT pin is used, it must be interrupt capable via attachInterrupt(...).

NOTE: Logic level converters must be used for boards which operate at 3.3V.

Espressif ESP32 wiring

Requires an external 3.3V CAN transceiver, such as a TI SN65HVD230.

CAN transceiver ESP32
3V3 3V3
GND GND
CTX GPIO_5
CRX GPIO_4

CTX and CRX pins can be changed by using CAN.setPins(rx, tx).

Installation

Using the Arduino IDE Library Manager

  1. Choose Sketch -> Include Library -> Manage Libraries...
  2. Type CAN into the search box.
  3. Click the row to select the library.
  4. Click the Install button to install the library.

Using Git

cd ~/Documents/Arduino/libraries/
git clone https://github.com/sandeepmistry/arduino-CAN CAN

API

See API.md.

Examples

See examples folder.

For OBD-II examples, checkout the arduino-OBD2 library's examples.

License

This library is licensed under the MIT Licence.

arduino-can's People

Contributors

agdl avatar ddejean avatar emekbaris avatar jonmon6691 avatar kouuta avatar sandeepmistry avatar simsso avatar ziss avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arduino-can's Issues

Is this library compatible with c++

I'm writing my arduino code in C++ for a project and i want to put everthing i do with this CAN library in a class, but when i do that i get issues, like the error "CAN was not declared in this scope"

Processing suddenly stops after 1 second at 500kbps and 1000kbps

Hi!

I have wired an sn65hvd230 to the ESP32s standard CAN RX and TX pins and I'm using the standard library with standard receive example where I change only the baudrate for testing.

As a CAN sending device, I have a notebook with Busmaster and a logfile which I'm replaying and sending through a Vector CanCaseXL.

When setting up the standard example as well as the sender to 100kbps, everything works fine, no glitches, no isses.
The story changes when changing the baudrate to 500 or 1000 respectively.
It takes approx 1s (+10-100ms) until the communication stops.
I monitor the communication through the serial monitor in ArduinoIDE.

Since my level is beginner, I first started looking if someone had similar issues but found nothing, hence why I'm writing this and asking for help on how to proceed further and how to troubleshoot what might be the issue? I have a small oscilloscope to monitor stuff if this is needed.

Thanks!

EDIT: I forgot to mention that I use this product: https://www.amazon.de/gp/product/B072C29H3K?pf_rd_p=8997cce2-05c4-4359-bdb7-10e52332d836&pf_rd_r=WVQRVN463A8BPR2MKDXM
I tried it with and without resistor and tried to pull down the pin nr. 8 directly to GND with same outcome.

Best regards,
RoB

Even example code doesn't always work

I have made the setup you show us.
I can use the examples, like read the rpm and read the vin code etc. Although the examples doesn't always work. For example the rpm doesn't always show in the console. My connections am pretty sure they are good. Do you have any suggestion?
Also when i try to read different PID i cant make it work either. I try simple PID to keep the code same as the RPM example and if it works to move forward to something more complicated. I try to read MAF sensor PID since it is very similar to RPM PID.
So i changed the code from the RPM example CAN.read() != 0x0c // correct PID
RPM PID to this CAN.read() != 0x10 since 0c is the rpm hex and 10 is the maf value and also change the calculation algorithm to match . But it doesn't work i get no data at all.

CAN receiver receives same packet continuosly

i am using esp32 with arduino and my device gets can msg repeatedly after some several hours of run.
parallely my another task is also running but it is getting blocked when can bus receives same message repeatedly. is there any interrupt enabled in this library?

Not able to get Ecu data from Jeep compass

Hello sir,
Im trying to receive the data from jeep compass ecu. Using the Can_receiver sample program we are getting different data.

Im trying the engine rpm example code.

// Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
//
// This examples queries the engine RPM (OBD-II PID 0x0c) once a seconds and
// prints the value to the serial monitor
//
#include <CAN.h>

// Most cars support 11-bit adddress, others (like Honda),
// require 29-bit (extended) addressing, set the next line
// to true to use extended addressing
const bool useStandardAddressing = true;

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

  Serial.println("CAN OBD-II engine RPM");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }

  // add a filter to only receive the CAN bus ID's we care about
  if (useStandardAddressing) {
    CAN.filter(0x7E8);
  } else {
    CAN.filterExtended(0x18daf110);
  }


  
}

void loop() {
  if (useStandardAddressing) {
    
    CAN.beginPacket(0x7DF, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }
  CAN.write(0x02); // number of additional bytes
  CAN.write(0x01); // show current data
  CAN.write(0x0c); // engine RPM
  CAN.endPacket();

  while (CAN.parsePacket() == 0 ||
         CAN.read() < 3 ||          // correct length
         CAN.read() != 0x41 ||      // correct mode
         CAN.read() != 0x0c);       // correct PID
  float rpm = ((CAN.read() * 256.0) + CAN.read()) / 4.0;

  Serial.print("Engine RPM = ");
  Serial.println(rpm);
   delay(1000);
   
}

what could be the issue? Please help me.

Best regards.

NO LOOPBACK IN LIBRARY WITH CALLBACK EXAMPLE WITH ESP32

- always shows Guru Meditation Error: Core 1 panic'ed when trying to send CAN MESSAGE inside the onReceive function### ``(InstrFetchProhibited).

here is the onReceive method:

void onReceive(int packetSize)
{
  long CAN_ID;
  int cmd_time_gateway[8];
  uint8_t count = 0;

  // received a packet
  Serial.print("Received ");
  Serial.print("packet with id : 0x");
  //// (11 Bits Messsage ID) 2 bits MSG CMD  + 9 bits CAN ID.

  CAN_ID = CAN.packetId();
  CAN_ID &= 0x1FF;
  Serial.print(CAN_ID, HEX);
  Serial.print(" = ");
  Serial.print(CAN_ID);
  Serial.print(" and length ");
  Serial.println(packetSize);

  // only print packet data for non-RTR packets
  while (CAN.available())
  {
    // (8 Bytes data) 1 byte CMD 4 bytes timestamp 3 bytes Gateway.
    cmd_time_gateway[count] = CAN.read();
    Serial.print(cmd_time_gateway[count], HEX);
    count++;
  }
 
  switch (cmd_time_gateway[0])
  {
  case 0xFF:
    /* code for send own id  (response of request all id) */
    Serial.println(" - SEND REQUEST ALL ID RESPONSE(SEND OWN ID)");
    confirmSpecificNewID(CAN_ID);
    Serial.println(" - CAN ID CONFIRMED)");
    break;

  case 0xF0:
    /* code for confirmation of ID from rfid node */
    Serial.println(" - send confirmation request");
    break;

  case 0x0F:
    /* code for heartbeat */
    Serial.println(" - HEART BEAT");
    break;

  default:
    /* code for detection of RFID  module */
    Serial.println(" - CARD DETECTION");
    break;
  }
  Serial.println(" - ENDED");
}

after finishing the onReceive function and execute this

 void confirmSpecificNewID(long confirmedID)
{
  int id = confirmedID | 0x200;
  CAN.beginPacket(id, 8);
  CAN.write(confirmSpecificIDBuffer, 8);
  CAN.endPacket();
}

Take in note that nothing happens it just works brilliantly if i removed confirmSpecificNewID() which for me that onReceive unable to operate functions inside ??

ESP Hangs itself - Guru Meditation Error: Core 1 panic'ed

Hi!
first, Great Lib!
Im having a little bit of trouble getting the ESP Stable with the CAN Library here.

Im useing the "void onReceive(int packetSize) " Callback and after a while Im getting this error:

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:10088
load:0x40080400,len:6380
entry 0x400806a4
**Guru Meditation Error: Core  1 panic'ed (Coprocessor exception)**
Core 1 register dump:
PC      : 0x400d1adb  PS      : 0x00060031  A0      : 0x800d7bb8  A1      : 0x3ffbe9b0  
A2      : 0x3ffc55b4  A3      : 0x00000001  A4      : 0x80093912  A5      : 0x00000000  
A6      : 0x00000001  A7      : 0x3ffbaca0  A8      : 0x00000000  A9      : 0x000b4103  
A10     : 0x000007e8  A11     : 0x000000fd  A12     : 0x0ffdac00  A13     : 0x0000abab  
A14     : 0x3ffb9a30  A15     : 0x00000000  SAR     : 0x00000019  EXCCAUSE: 0x00000004  
EXCVADDR: 0x00000000  LBEG    : 0x400df614  LEND    : 0x400df676  LCOUNT  : 0x00000003  
Core 1 was running in ISR context:
EPC1    : 0x400d1adb  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x40082941

Backtrace: 0x400d1adb:0x3ffbe9b0 0x400d7bb5:0x3ffbea90 0x400d7bc1:0x3ffbeab0 0x40081819:0x3ffbead0 0x4000bfed:0x00000000

Rebooting...

I tried to isolate the Callback into a seperate Task but if gave me errors in Setup()
in particular CAN.onReceive(onReceive);

When I Try the Standart can revive example and merge it into a separate Task, all works but slows everything down. In my case the Display refresh rate goes down significantly

When I try to run the Can bus on Core 0, the ESP makes Brown outs /Restarts.

Maybe someone knows a solution to this.

question with the include files used in ESP32SJA1000.cpp file

Hello,
I dont understand how you are using functions like "DPORT_CLEAR_PERI_REG_MASK" in ESP32SJA1000.cpp which is defined in "dport_access.h" without even including this library.
Sorry about my silly question,
Thanks in advance

Regards,
Ajay

Can't set 33.3kbps baudrate

Hello!
I use your library with ESP32 + SN65HVD230 transceiver. It works well on all pre-defined baudrate but I needed two special, too. I quickly managed to set up 95.238 using the calculation method in the source at https://github.com/nhatuan84/arduino-esp32-can-demo but I simply cannot manage 33.3kbps and it drives me mad. I tried Kvaser's calculator and also http://www.esacademy.com/en/library/calculators/sja1000-timing-calculator.html, no luck. I tried

    case (long)33E3:
      modifyRegister(REG_BTR1, 0x0f, 0x0c);
      modifyRegister(REG_BTR0, 0x3f, 75); 

according to Arduino-ESP32 method, and

    case (long)33E3:
      modifyRegister(REG_BTR1, 0x0f, 0x0c);
      modifyRegister(REG_BTR0, 0xfe, 0x8a);

according to Esacademy's calculator. Then I tried every single value between 62 and 124 for
modifyRegister(REG_BTR0, 0x3f, 62);
also no luck. I didn't want to ask such silly thing but I'm out of ideas. Could you please give me a clue what I did wrong?

Thank you in advance!

Multiple CAN instances

There does not seem to be a way to create more than a single instance of the CAN object.

Second CAN Bus

Hi,

i'm using your library for reading the CAN Bus of my Renault ZOE using ESP32, it works great. Thanks for this.

My question: Renault ZOE has a second CAN Bus on two other pins of the CAN plug, and i would like to read this second bus as i do with the first bus. Does the library support this? Can i define a second instance, let's say CAN2? And how?

CAN.endPacket() always returns a 0

Hello,

I just ran the example code with two esp32s.
And I cant get a communication happening, because whatever i do, the command CAN.endPacket() returns me a 0.

Maybe someone can help me.
Thank you!

CAN bus fault detection

Hello :-)

Would it be possible to implement some standard signals concerning CAN bus fault detection?
E.g. Transmit Error Counter (TEC), Receive Error Counter (REC) and the typical CAN bus Error Flags?
Or maybe you can give me an example how to readout the registers directly from my main software.

Besides that, this CAN bus driver in connection with the ESP32 works very well, thank you very much for providing it to all of us !!!

Alex

Arduino Nano to ESP32 communication not working

Hello I am trying to communicate Arduino Nano to ESP32 using sv65hvd230 module but it is not working nothing showing that the point where i am stuck i dont know how to move out from this.

your help is highly appreciable.

Thanks
Bhavik

Send and receive bits

I'd like send and receiver bits of data,not character
I will use in maintenance of machine

20200814_193104

I'd like set the bits 32 33 and 34
I need sent slot of zero and position 32 33 and 34 send 1
I need sent this 000000000000000000000000000000 0111000000000000000000000000000000

Tks

esp32 hangs on CAN.endPacket();

I have no transceiver attached and when sending a packet, the ESP32 hangs upon executing CAN.endPacket();

Also when configured for loopback mode.

Which ESP32 Version do you use?

Missing 83.333 kbps -> Updated and tested.

The mode for 83.333 kbps is missing. I added the following line for the 16MHz clock:
{ (long)16E6, (long)83E3, { 0x03, 0xfe, 0x87 } },
in MCP2515.cpp

These settings work and were tested in my 2008 Dodge Durango poking around CAN-IHS.

I've ordered a few more modules, one with an 8MHz clock to verify the settings for 83.333 kbps, I should have them sometime in the beginning of January 2020.

MCP2515 bandwidth issues at 500K and 1Mbps -> SPI command optimizations

I made a few optimizations to improve the performance of the interface for the MCP2515. There are a couple of commands to reduce the overhead of the SPI to increase the data throughput to and from the MCP2515; LOAD RX BUFFER, RTS, and READ RX BUFFER. I added it endPacket() even though it doesn't matter as much since it waits for the packet to complete sending before returning (there is still an improvement), the improvement in parsePacket() is nice.

int MCP2515Class::parsePacket()
{
  int n;

  uint8_t intf = readRegister(REG_CANINTF);

  if (intf & FLAG_RXnIF(0)) 
  {
    n = 0;
  } 
  else if (intf & FLAG_RXnIF(1)) 
  {
    n = 1;
  }
  else
  {
    _rxId = -1;
    _rxRtr = false;
    _rxLength = 0;
    return 0;
  }
  uint8_t SIDH = readRegister(REG_RXBnSIDH(n));
  uint8_t SIDL = readRegister(REG_RXBnSIDL(n));
  uint32_t idA = ((SIDH << 3) & 0x07f8) | ((SIDL >> 5) & 0x07);
  _rxId = idA;
  _rxRtr = (SIDL & FLAG_SRR) ? true : false;

  _rxDlc = readRegister(REG_RXBnDLC(n)) & 0x0f;
  _rxIndex = 0;

  if (_rxRtr) 
  {
    _rxLength = 0;
  } 
  else 
  {
    _rxLength = _rxDlc;

    SPI.beginTransaction(_spiSettings);
    digitalWrite(_csPin, LOW);
    SPI.transfer(0b10010010 | (n << 2));        //Set to stream RX data from Buffer n
    for (uint8_t x = 0; x < _rxLength; x++)
      _rxData[x] = SPI.transfer(0x00);          //Stream data form RX buffer
    digitalWrite(_csPin, HIGH);                 //unsetting CS pin will reset IRQ flag
    SPI.endTransaction();
  }

  return _rxRtr ? true : _rxDlc;
}

int MCP2515Class::endPacket()
{
  if (!CANControllerClass::endPacket()) 
  {
    return 0;
  }

  int n = 0;

  writeRegister(REG_TXBnSIDH(n), _txId >> 3);
  writeRegister(REG_TXBnSIDL(n), _txId << 5);
  writeRegister(REG_TXBnEID8(n), 0x00);
  writeRegister(REG_TXBnEID0(n), 0x00);

  if (_txRtr)
  {
    writeRegister(REG_TXBnDLC(n), 0x40 | _txLength);
  }
  else 
  {
    writeRegister(REG_TXBnDLC(n), _txLength);    //set packet length

    SPI.beginTransaction(_spiSettings);
    digitalWrite(_csPin, LOW);
    SPI.transfer(0b01000000 | (n * 2 + 1));      //set TX buffer for stream
    for (uint8_t x = 0; x < _txLength; x++)
      SPI.transfer(_txData[x]);                  //stream data to buffer
    digitalWrite(_csPin, HIGH);
    SPI.endTransaction();
  }

  SPI.beginTransaction(_spiSettings);
  digitalWrite(_csPin, LOW);
  SPI.transfer(0b10000000 | (1 << n));          //set RTS for TX Buffer n
  digitalWrite(_csPin, HIGH);
  SPI.endTransaction();  

  bool aborted = false;

  while (readRegister(REG_TXBnCTRL(n)) & 0x08) 
  {
    if (readRegister(REG_TXBnCTRL(n)) & 0x10) 
    {
      // abort
      aborted = true;

      modifyRegister(REG_CANCTRL, 0x10, 0x10);
    }

    yield();
  }

  if (aborted) {
    // clear abort command
    modifyRegister(REG_CANCTRL, 0x10, 0x00);
  }

  modifyRegister(REG_CANINTF, FLAG_TXnIF(n), 0x00);

  return (readRegister(REG_TXBnCTRL(n)) & 0x70) ? 0 : 1;
}

Arduino Mega2560 and MCP2515 not working

Hi, I try with all examples and can't pass form the "CAN.begin(500E3)", always get false.

I have a Toyota highlander 2010 and test with 250E3 and also changed the CAN.setClockFrequency(8E6).

Please someone point me to the right direction.

Thank you

No RTR receiption

Unfortunately RTR messages are not handled correctly. If you look at

void MCP2515Class::handleInterrupt()
{
  if (readRegister(REG_CANINTF) == 0) {
    return;
  }

  while (parsePacket()) {
    _onReceive(available());
  }
}

you can see that _onReceive will only get called if parsePacket returns non-zero.

If the function parsePacket detects the RTR bit set it sets the _rxDlc (data packet length) to zero which in terms of RTR is correct. Unfortunately it returns that zero value.

return _rxDlc;

The solution is simple. Modify the return statement in parsePacket to:

return _rxRtr ? true : _rxDlc;

No communication two ESP32 with SN65HDV230 module

Hello,

I have two esp32 (DOIT devkit esp32) and two module with SN65HDV230. I used yours library. On one is load program CANsender and on second esp32 is program CANReceiver. First ESP32 sending me on serial message "sending packet...done" . My configuration is same like yours. I dont see on second ESP32 no messages. I testing change speed and pins and no reaction.
I have more modules(ESP32 and SN65HDV230) and all of it is the same.
Please help me.

Thank you

Filter for multiple CAN frame ids/masks

Hey,

Im not sure about the SJA1000 but the MCP2515 supports multiple filters, however the api of this library does not support multiple filters.
Maybe a macro constant like MAX_FILTERS and a function multiFilter(int *ids, int *masks, size_t count) would be possible?

I'm using this library together with an Arduino MKR WAN and a MKR CAN shield to read data from a Renault Twizy. Bitwise anding together all the CAN IDs I need results in 0, so using a single filter is not possible.

Doesn't work on SN65HVD230 Transceiver

Nice library but it doesn't work on a SN65HVD230 Transceiver (which are now very common).

Using your simple EngineRPM demo; it hangs at CAN.endPacket() (the standard can library in esp-idf does work with SN65HVD230).

Weirdly, if I put a Serial.println immediately before that it not only hangs but I have to power cycle my ESP32 before it will talk again:

CAN.write(0x0c); // engine RPM
Serial.println("Written 0x0c");
CAN.endPacket();

MCP-2515 not supported for ESP32

Great libraries. But it doesn't support MCP-2515 for ESP32. Not complaining one bit.
But I was a little confused at first. And wanted to leave a note for others.

MCP-2515 for ESP32 would be an awesome feature. But this library is already good enough as-is. Thank you for the awesome work!

MCP2515 Modification to support ESP32

Hello.

I tried to modify to make work the ESP32 with the MCP2515 by ARDUINO_ARCH_ESP32 ifdef conditionals to make it use the MCP2515 lib, but there are some functions like SPI.usingInterrupt(digitalPinToInterrupt(_intPin)) and SPI.notUsingInterrupt(digitalPinToInterrupt(_intPin)) that are only avaiable in AVR microships.
"pierremolinaro/acan2517#1"
In the link you could see how they solved a similar problem, however, I wasn´t able to use it in arduino-CAN Library.
if someone can solved it, please let us know how do it.
Good day, by the way.

Is it possible to set 615,384 baud rate?

Hi,

I am successfully using Arduino + MCP2515 with 615.384 baud rate for one simple project and I want to migrate to ESP32 and use the integrated can controller.

Unfortunately, I can't set the right register values. Tried all calculators which I found but without luck.

Could you please help me to find the right register values?
Thank you!

EDIT: It looks like there is a hardware problem because the ESP32 doesn't work in 500KBPS also. I tried a few libraries. Now I am using the ESP32 with the MCP2515.

Cannot get CAN library and SPI display (ILI9341) working at the same time

I am working on an Arduino MKR Zero based project that combines an MKR CAN Shield as well as a touch screen (2.4” 240x320 using the Adafruit ILI9341 library).

When connected alone, the CAN Shield works fine using the Sandeep Mistry's arduino-CAN library and the CANSender code. When connected alone, the display assembly also works fine.

But I do not get both parts working at the same time. When running CANSender, it gives a “Starting CAN failed!” error message in SerialReader.

I checked whether there was a conflict on resources. The CAN board uses SPI with Chip Select (CS) on port 3, the display and touch panel use SPI with CS on pin A3 and A4 respectively. So, there should not be any conflict of resources there. The CAN board also uses interrupt on Pin 7, which is not used by the display or touch panel.

Interestingly, when I power up with just the CAN shield first, wait for successful initialisation, and THEN connect the display module, the CAN bus traffic continues to work fine (again using just CANSender, no code for the display at all). But when I power up with both connected, everything else equal, I get the above error. So it seems only the initialisation phase that has problems, not the later communication phase.

Am not really a programmer… Anyone any clue or suggestion how to get this working?

Thanks!!

How to sent and recieve int?

Hi, thank you very much for your work.
How can I transmit the potentiometer data from a sender ESP32 to receiver one?

Thank you in advance for your help!
Filippo

Issue with Can Bus Filter ID's

Thanks, Sandeep Mistry for the Library!

I need a little help with my Code.
I am working with an ESP32 and a TCAN334. We are facing issue with Filtering Ids. we are using the sample code provided with the library.
Without filter we are getting the data over can bus. But when we apply filters we did not receive any data.
we checked with the library, and ACR registers are correctly set.

We are trying filter with 0x18daf110 (Honda Jazz)

#include <CAN.h>

const bool useStandardAddressing = false;


void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("CAN Receiver");

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }


  if (useStandardAddressing) {
    CAN.filter(0x7E8);
  } else {

    CAN.filterExtended(0x18daf110  );

  }
}

void loop() {

  if (useStandardAddressing) {
    CAN.beginPacket(0x7DF, 8);
  } else {
    CAN.beginExtendedPacket(0x18db33f1, 8);
  }

  int packetSize = CAN.parsePacket();

  if (packetSize) {
    // received a packet
    Serial.print("Received ");

    if (CAN.packetExtended()) {
      Serial.print("extended ");
    }

    if (CAN.packetRtr()) {
      // Remote transmission request, packet contains no data
      Serial.print("RTR ");
    }
    Serial.print("packet with id 0x");
    Serial.print(CAN.packetId(), HEX);
    if (CAN.packetRtr()) {
      Serial.print(" and requested length ");
      Serial.println(CAN.packetDlc());
    } else {
      Serial.print(" and length ");
      Serial.println(packetSize);
      // only print packet data for non-RTR packets
      while (CAN.available()) {
        Serial.print((char)CAN.read(), HEX);
      }
      Serial.println();
    }
    Serial.println();

  }

maybe someone can help me out.

CAN bus filter does not work as expected

Greetings, all. This is a nice library but I am tearing my hair out because I can't get the CAN filter to work. If I don't set the filter, all incoming packets trigger the onReceive() callback, as they should. However, if I set the filter as Sandeep documents, I do not receive ANY packages at all. Here is a code snippet that shows a packet I'd like to receive, the filter mask to select the wanted bits, and the filter ID that should trigger the onReceive event after masking. According to the documentation (see snippet in code below), everything appears to be correct and the filter should allow the packet through ((packetID & filterMask) == filterID)). This evaluates as true. BUT I receive nothing at all!

Any help or suggestions would be GREATLY appreciated!

`void setup() {
Serial.begin(115200);
// The filter documentation says, regarding CAN.filterExtended(id, mask);
// Only packets that meet the following criteria are acknowledged and received, other packets are ignored:
// if ((packetId & mask) == id) {
// // acknowledged and received
// } else {
// // ignored
// }

// here is an incoming package ID that needs to trigger
// the onReceive event.
uint32_t packetID = 0b10001001110000000010010000001;
//// I only want to trigger on the bits allowed by this mask:
uint32_t filterMask = 0b00011111111111111111000000000;
// after masking, compare to this ID:
uint32_t filterID = 0b00001001110000000010000000000;
// According to Sandeep, this is the operation implemented
// by the CAN.filterExtended(filterID, filterMask) call:
Serial.println((packetID & filterMask) == filterID);
// ... which results in 1, as expected. The packet should be accepted.

// HOWEVER, if I use this call in setup after initializing CAN:
// CAN.filterExtended(filterID, filterMask);
// ABSOLUTELY NO packages are received!
}

void loop() {
}`

When sending data with a length of 8 bytes, endPacket always crashes

I use an Atmel 2560 with MCP2551.
Here the example sketch

// Copyright (c) Sandeep Mistry. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <CAN.h>

unsigned long synchMillis = millis();
unsigned long dataMillis = millis();
const uint8_t NODE_ID = 0x12;
const uint8_t PINIO_CS = 31;
const uint8_t PINIO_IRQ = 21;

/*
   Send all 100mSec the SYNCH message
*/
void sendSynch() {
  uint8_t msg[] = {0x7F, 0xFF};
  sendCanMessage(0x80, 2, msg);
}

void askSDO() {
  uint8_t ask[8] = {0x40, 0x0A, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00};
  sendCanMessage(0x612, 8, ask);
}

bool detectBattery() {
  return true;
}

void sendCanMessage(uint16_t canId, uint8_t sendLen, uint8_t *msg) {
  uint8_t status = 1;
  status = CAN.beginPacket(canId);
  Serial.print("Status begin packet: ");
  Serial.println(status);
  status = CAN.write(msg, sendLen);
  Serial.print("Status write: ");
  Serial.println(status);
  status = CAN.endPacket();
  Serial.print("Status end packet: ");
  Serial.println(status);
  Serial.println();
}

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

  CAN.setPins(PINIO_CS, PINIO_IRQ);
  CAN.setClockFrequency(8E6);
  while (!CAN.begin(250E3)) {
    Serial.println("Init CAN: Error");
    delay(100);
  }

  CAN.onReceive(onReceive);
}

void loop() {
  // if battery is detected then send SYNCH
  if (millis() - synchMillis >= 100) {
    sendSynch();
    synchMillis = millis();
  }

  if (millis() - dataMillis >= 1000) {
    askSDO();
    dataMillis = millis();
  }
}

void onReceive(int packetSize) {
  // received a packet
  Serial.print("Received ");

  if (CAN.packetExtended()) {
    Serial.print("extended ");
  }

  if (CAN.packetRtr()) {
    // Remote transmission request, packet contains no data
    Serial.print("RTR ");
  }

  Serial.print("packet with id 0x");
  Serial.print(CAN.packetId(), HEX);

  if (CAN.packetRtr()) {
    Serial.print(" and requested length ");
    Serial.println(CAN.packetDlc());
  } else {
    Serial.print(" and length ");
    Serial.println(packetSize);

    // only print packet data for non-RTR packets
    while (CAN.available()) {
      Serial.print((char)CAN.read(), HEX);
    }
    Serial.println();
  }

  Serial.println();
}

and the response...

21:07:35.565 -> Status begin packet: 1
21:07:35.565 -> Status write: 2
21:07:35.565 -> Status end packet: 0
21:07:35.565 -> 
21:07:35.673 -> Status begin packet: 1
21:07:35.673 -> Status write: 2
21:07:35.673 -> Status end packet: 0
21:07:35.673 -> 
21:07:35.783 -> Status begin packet: 1
21:07:35.783 -> Status write: 2
21:07:35.783 -> Status end packet: 0
21:07:35.783 -> 
21:07:35.891 -> Status begin packet: 1
21:07:35.891 -> Status write: 2
21:07:35.891 -> Status end packet: 0

Sending and receiving

Sending and receiving works fine.
I have several ESP32 on the bus and they are programmed to send a packet when receiving another.
So 1 ESP sends packet number 2 and all other ESP sends packet number 3 when receiving packet number 2.
This makes f.ex 10 ESP send the same packet at the same time.
If I repeat this , then 1 ESP eventually dies, and after a while only the sender and 1 other is working.
The ESP are dead and need power on/off to live again.
I am thinking receive buffers, anyone experience the same ?

leave loopback mode

Once configured for loopback mode, what is the proper way to restore normal mode?
For the moment, I used CAN.filter(0x00); since it resets the mode back to normal but
can you please update your code so loopback() expects a bool?

int ESP32SJA1000Class::loopback(bool mode = true)
{
_loopback = mode;
modifyRegister(REG_MOD, 0x17, 0x01); // reset

if(mode){
modifyRegister(REG_MOD, 0x17, 0x04); // self test mode
}else{
modifyRegister(REG_MOD, 0x17, 0x00); // normal mode
}
return 1;
}

DLC=0 frames aren't received

I used the library for testing one of my builds and I noticed that it doesn't properly receive frames with DLC=0. While uncommon this type of frame is not ruled-out by the standard. The MCP2515 does acknowledge the frame on the bus properly, but the library does not forward it to the user-code.

I "fixed" the problem in my version by changing the return value of an empty frame to -1 (in parsePacket-function) and checking for a positive return-value in the polling-loop. Maybe you want to incorporate a similar fix into your version.

Can Bus Filter ID´s and Formating Messages.

Thanks sandeepmistry for the Library!

I need a litte help with my Code.

I am working with a ESP32 and a TI SN65HVD230. Everything works fine and I can Monitor RPM and Speed from the Can Bus on my Smart fortwo Car.

my next goal is to show up Gears, I know that the transmission ECU is ID 0x418 and I also know how the message is set up.

for example:

"ID = 0x418 Message = 4E FE 32 25 00 4E FE 37" This is for Neutral

"ID = 0x418 Message ="52 FE 30 68 BB 52 FE 30" This is for Reverse

I only tried a Filter with ID: =0x148

And Print the Bus to Console, what I Got is only 4 Bytes messanges and I need a 32 Byte variable to compare / mask.

(if ID == 418 && Messsage == 4E FE 32 25 00 4E FE 37)
{
Serial.print("Neutral");
}

This is the Console Log:

------------------------------------
30
69
0
4E
FE
31
6A
0
4E
FE
35
6B
0
4E
FE
30
6C
0
.
.
.
-------------------------------------

there is so little information about the ESP32 Can Controller out there, so how to work this out.

maybe someone can help me out

48mhz not supported

I noticed that the library doesn't support faster boards than 16mhz. There isn't a mapping in CNF_MAPPER in MCP2515.cpp. Could the mapping be added for 48mhz boards?

Thanks!

How to find PIDs of a vehicle?

This library is working for me. I can see PID and its data. Now I need any CAN analyzer software which can be used to find PIDs of vehicle or if someone know any predefined list of PIDs?

Potential Issue when using defined CS pin

Hello.

I am working on a project which reads data from an attached GPS module, calculates various date/time values, displays this on a local display (4x20 LCD) and also transmits some of this information over a CAN bus for other devices to eventually read and use.
I've been experimenting with several different CAN libraries for the MCP2515 (MKR CAN Shield) and this one seems the most straight forward to use, but I am running into an issue with the code hanging.

In order for the device to initialize I have to connect the CS pin to what it is defined as (I've tried both the default and a custom one by using setPins) but if I leave it connected, the whole system hangs and does nothing. disconnecting the wire allows the code to proceed. If I briefly touch the wire to the CS pin then remove it, it successfully initializes and the code runs normally (no comm though since CS is now disconnected). Connecting CS to a separate pin that I directly control as CS around when the Send functions are called does nothing. In summary, I can't control it directly yet whenever the MCP2515 CS is connected to the configured pin, the code hangs.

I started out running this on a Pro Mini 5V and I have now migrated to a Teensy 4.0 since I was exceeding the memory capacity of the pro mini. Both exhibit the same hanging issue. The MCP2515 on the Tx side is running at 3.3V and the CAN transceiver is running at 5v. Rx side is another MKR shield and an Arduino Micro (all running at 5V) printing data to a local LCD (2x16).

Any thoughts or suggestions on what is going on here?
Thanks in advance.

Code is attached below.
GPS_Core_v2.txt

How to clear TX buffer

Hello, it seems that these lines

// wait for TX buffer to free
while ((readRegister(REG_SR) & 0x04) != 0x04) {
yield();
}

and

// wait for TX complete
while ((readRegister(REG_SR) & 0x08) != 0x08) {
if (readRegister(REG_ECC) == 0xd9) {
modifyRegister(REG_CMR, 0x1f, 0x02); // error, abort
return 0;
}
yield();
}

can make the device hang, I think that the TX buffer is full when there is nothing connected to the bus to RX and ack the data. Then the buffer gets full and the device hangs.

How can the TX buffer be cleared ? or there should be a timeout for these while loops and then return an error code

No data received with Leonardo ETH

Hello,

first thank you for the quick response on Twitter. I have a problem, I don't receive data with the CAN library or the OBD2 library.
I use the Twitter shared module in combination with a Leonardo ETH. I can upload a picture of the wiring if needed.
https://imgur.com/2IWky3M
I added CAN.setClockFrequency(8E6); CAN.setPins(10, 2); to your Supported PID example.
Do you have an idea?

No CAN communication

Hi,
I tried to connect 2 Arduino UNO with 2 MKR CAN Shields. I uploaded the examples "CANReceiver" and "CANSender" successfully but I have no connection. The serial monitor from CANSender shows "CAN Sender, Sending packet ..." and the CANReceiver shows "CAN Receiver".
Is the Arduino UNO not compatible with the MKR CAN Shield? Should I make any additional configurations?
Thanks!
LK231195

No Sleep Mode

The Sleep Mode (10.2 Sleep Mode) does not work. Mainly it is because of a wrong procedure. The datasheet states to write bits 5-7 (Sleep Mode 001) to the control register (REGISTER 10-1: CANCTRL: CAN CONTROL REGISTER (ADDRESS: XFh)), but the provided function just writes a 0x01 into the register!

WRONG:

int MCP2515Class::sleep()
{
  writeRegister(REG_CANCTRL, 0x01);
  if (readRegister(REG_CANCTRL) != 0x01) {
    return 0;
  }

  return 1;
}

Set bits 5-7 to 001 (Sleep Mode):
RIGHT:

int MCP2515Class::sleep() {
  // We are requesting a sleep mode in the control register
  modifyRegister(REG_CANCTRL, B11100000, B00100000);
  return 1;
}

Please refer to the datasheet for the wake up procedures. The device can be brought back to life via an event on the bus or manually by the MCU.

ESP32 - how can i setup another baud rate?

HI,

After atmel +mcp2515 i'm trying to use ESP32 for can bus communication.
However I can't set custom speed. I need 83.333 kbps.
How did you calculated BTR register values? tried kvasir bit calculator, but can't get same numbers. dont know clock frequency at least.
I managed to use excel :) and to interpolate required bit rate with nice formula:
BTR0 = 2989,2 * BAUD ^ -1,05
for 83.333 i got BTR0 = 29. And it works!!!! 👍

    case (long)80E3:
      modifyRegister(REG_BTR1, 0x0f, 0x0c);
      modifyRegister(REG_BTR0, 0x3f, 30);
      break;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.