GithubHelp home page GithubHelp logo

acan2515's Introduction

MCP2515 CAN Controller Library for Arduino

Compatibility with the ACAN library

This library is fully compatible with the Teensy 3.x ACAN library https://github.com/pierremolinaro/acan, it uses a very similar API and the same CANMessage class for handling messages.

ACAN2515 library description

ACAN2515 is a driver for the MCP2515 CAN Controller. It runs on any Arduino compatible board.

You can choose any frequency for your MCP2515, the actual frequency is a parameter of the library.

The driver supports many bit rates: for a 16 MHz quartz, the CAN bit timing calculator finds settings for standard 62.5 kbit/s, 125 kbit/s, 250 kbit/s, 500 kbit/s, 1 Mbit/s, but also for an exotic bit rate as 727 kbit/s. If the desired bit rate cannot be achieved, the begin method does not configure the hardware and returns an error code.

Driver API is fully described by the PDF file in the extras directory.

Demo Sketch

The demo sketch is in the examples/LoopBackDemo directory.

Configuration is a four-step operation.

  1. Instanciation of the settings object : the constructor has one parameter: the wished CAN bit rate. The settings is fully initialized.
  2. You can override default settings. Here, we set the mRequestedMode property to true, enabling to run demo code without any additional hardware (no CAN transceiver needed). We can also for example change the receive buffer size by setting the mReceiveBufferSize property.
  3. Calling the begin method configures the driver and starts CAN bus participation. Any message can be sent, any frame on the bus is received. No default filter to provide.
  4. You check the errorCode value to detect configuration error(s).
static const byte MCP2515_CS  = 20 ; // CS input of MCP2515, adapt to your design
static const byte MCP2515_INT = 37 ; // INT output of MCP2515, adapt to your design

ACAN2515 can (MCP2515_CS, SPI, MCP2515_INT) ; // You can use SPI2, SPI3, if provided by your microcontroller

const uint32_t QUARTZ_FREQUENCY = 16 * 1000 * 1000 ; // 16 MHz

void setup () {
  Serial.begin (9600) ;
  while (!Serial) {}
  Serial.println ("Hello") ;
  ACAN2515Settings settings (QUARTZ_FREQUENCY, 125 * 1000) ; // 125 kbit/s
  settings.mRequestedMode = ACAN2515Settings::LoopBackMode ; // Select loopback mode
  const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
  if (0 == errorCode) {
    Serial.println ("Can ok") ;
  }else{
    Serial.print ("Error Can: 0x") ;
    Serial.println (errorCode, HEX) ;
  }
}

Now, an example of the loop function. As we have selected loop back mode, every sent frame is received.

static uint32_t gSendDate = 0 ;
static uint32_t gSentCount = 0 ;
static uint32_t gReceivedCount = 0 ;

void loop () {
  CANMessage message ;
  if (gSendDate < millis ()) {
    message.id = 0x542 ;
    const bool ok = can.tryToSend (message) ;
    if (ok) {
      gSendDate += 2000 ;
      gSentCount += 1 ;
      Serial.print ("Sent: ") ;
      Serial.println (gSentCount) ;
    }
  }
  if (can.receive (message)) {
    gReceivedCount += 1 ;
    Serial.print ("Received: ") ;
    Serial.println (gReceivedCount) ;
  }
}

CANMessage is the class that defines a CAN message. The message object is fully initialized by the default constructor. Here, we set the id to 0x542 for sending a standard data frame, without data, with this identifier.

The can.tryToSend tries to send the message. It returns true if the message has been sucessfully added to the driver transmit buffer.

The gSendDate variable handles sending a CAN message every 2000 ms.

can.receive returns true if a message has been received, and assigned to the messageargument.

Use of Optional Reception Filtering

The MCP2515 CAN Controller implements two acceptance masks and six acceptance filters. The driver API enables you to fully manage these registers.

For example (loopbackUsingFilters sketch):

  ACAN2515Settings settings (QUARTZ_FREQUENCY, 125 * 1000) ;
  settings.mRequestedMode = ACAN2515Settings::LoopBackMode ; // Select loopback mode
  const ACAN2515Mask rxm0 = extended2515Mask (0x1FFFFFFF) ; // For filter #0 and #1
  const ACAN2515Mask rxm1 = standard2515Mask (0x7F0, 0xFF, 0) ; // For filter #2 to #5
  const ACAN2515AcceptanceFilter filters [] = {
    {extended2515Filter (0x12345678), receive0},
    {extended2515Filter (0x18765432), receive1},
    {standard2515Filter (0x560, 0x55, 0), receive2}
  } ;
  const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }, rxm0, rxm1, filters, 3) ;

These settings enable the acceptance of extended frames whose identifier is 0x12345678 or 0x18765432, and data frames whose identifier is 0x560 and first data byte, if any, is 0x55.

The receive0, receive1, receive2 functions are call back functions, handled by the can.dispatchReceivedMessage function:

void loop () {
  can.dispatchReceivedMessage () ; // Do not use can.receive any more
  ...
}

acan2515's People

Contributors

arjan-woltjer avatar asukiaaa avatar kek91 avatar koryphon avatar pierremolinaro 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

acan2515's Issues

Acan2515 bitrate problem

Hello.
I am working on mcp2515 with this library. But when i try to send can massage at 16mhz quartz frequency it reduces the bitrate with half of i try to send. If i sen at 1 mbps it sends messages at 500kbps. Also with 10 MHz quartz frequency i saw that when i try to send message with 1 MHz it sends it with 800kbps. While 8 MHz frequency is running, I can send my messages with exactly the bitrate I want. What I want is to reach 1 mbps speed. 8 mhz frequency doesn't support it either. I couldn't solve this problem, can you help me? Sorry for my bad english.

No can.receiveBufferCount()

I use your library ACAN2515 Version 2.0.1 and in general it works great. Thanks.

In your documentation you mention the method can.receiveBufferCount()
Unfortunately this is not available.

I can use can.receiveBufferPeakCount() without problem.

NoReceiveBufferCount

Request: expose error flag register

It would be very useful to be able to read the chip's error flag register (0x2D ?) This enables one to check for error states such as warning level, error passive, bus off, etc. A value of zero means 'no error' and the definitions of the individual bit values can be found in the datasheet.

It is present in the MCP_CAN library as the getError() method.

ESP8266

Can this library work with an ESP8266, please?

ACAN2515::begin() hangs if it is called the 3rd time.

In some caces, I have to change the filters and masks of one of my MCP2515s (yes I have 2, and they have to work together), after that, I have to recall the "begin" method.
In the LoopBackDemo, when I tried to call begin again with "settings.mReceiveBufferSize = 31;" (Just for testing), the Arduino hangs.
Then, I tried setting "settings.mReceiveBufferSize = 8;", and discovered that I can call begin twice, it hangs at the 3rd call.
So I think when begin is called, this driver allocates the recieve buffer to a new space of RAM, not using the old space, and this filled the RAM up.
Maybe I'm wrong, I'm not familiar with C++.
Any solutions? Or I just missed something?

Problem with dual canbus

I tried to connect 2 MCP2515 to MCU via SPI but only first CAN can begin() successful, the second never run
.............
ACAN2515 CAN1(MCP2515_CS1, SPI, MCP2515_INT1);
ACAN2515 CAN2(MCP2515_CS2, SPI, MCP2515_INT2);
........
//This config will run CAN1 OK, CAN2 hang at begin()
const uint16_t errorCode1 = CAN1.begin (settings1, [] { CAN1.isr () ; }) ;
const uint16_t errorCode2 = CAN2.begin (settings2, [] { CAN2.isr () ; }) ;

//This config will run CAN2 OK, CAN1 hang at begin()
const uint16_t errorCode2 = CAN2.begin (settings2, [] { CAN2.isr () ; }) ;
const uint16_t errorCode1 = CAN1.begin (settings1, [] { CAN1.isr () ; }) ;

'class ACAN2515' has no member named 'receiveBufferPeakCount'

Following the PDF chapter 8.4, I just copied the example in 8.4 to the LoopBackDemo, to get the RecieveBufferPeakCount. But when I try to upload it, the IDE tells me "class ACAN2515' has no member named 'receiveBufferPeakCount", is there something wrong? please help. Thanks
My IDE is 1.8.7, Arduino board is pro mini.
code:
if (can.available ()) {
can.receive (frame) ;
gReceivedFrameCount ++ ;
Serial.print ("Received: ") ;
Serial.println (gReceivedFrameCount) ;
const uint16_t peak = can.receiveBufferPeakCount () ; //Line added
}

feature-request: sleepmode and changing filters

nice lib, but I am missing sleep mode and changing filters on the fly. Do you plan to add it?

Bits 5-7 of CANCTRL_REGISTER
000 = Set Normal Operation mode
001 = Set Sleep mode
010 = Set Loopback mode
011 = Set Listen-only mode
100 = Set Configuration mode

Would be nice with bit modifing and readback.
Before setting filters, enter configuration mode and change back to normal mode afterwards.

ESP32 Works in LoopbackMode but not NormalMode

Sketch working in loopback mode just fine, however when I switch to NormalMode, it doesn't get any messages through, and it always starts having Message Send Failures after send # 17. Any thoughts?

Only major change was adding the STBY pin as mapped for the tranciever.

//——————————————————————————————————————————————————————————————————————————————
//  ACAN2515 Demo in loopback mode, for ESP32
//——————————————————————————————————————————————————————————————————————————————

#ifndef ARDUINO_ARCH_ESP32
  #error "Select an ESP32 board" 
#endif

//——————————————————————————————————————————————————————————————————————————————

#include <ACAN2515.h>

//——————————————————————————————————————————————————————————————————————————————
//  For using SPI on ESP32, see demo sketch SPI_Multiple_Buses
//  Two SPI busses are available in Arduino, HSPI and VSPI.
//  By default, Arduino SPI uses VSPI, leaving HSPI unused.
//  Default VSPI pins are: SCK=18, MISO=19, MOSI=23.
//  You can change the default pin with additional begin arguments
//    SPI.begin (MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI)
//  CS input of MCP2515 should be connected to a digital output port
//  INT output of MCP2515 should be connected to a digital input port, with interrupt capability
//  Notes:
//    - GPIOs 34 to 39 are GPIs – input only pins. These pins don’t have internal pull-ups or
//      pull-down resistors. They can’t be used as outputs.
//    - some pins do not support INPUT_PULLUP (see https://www.esp32.com/viewtopic.php?t=439) 
//    - All GPIOs can be configured as interrupts
// See https://randomnerdtutorials.com/esp32-pinout-reference-gpios/
//——————————————————————————————————————————————————————————————————————————————

static const byte MCP2515_SCK  = 8 ; // SCK input of MCP2515 
static const byte MCP2515_MOSI = 10 ; // SDI input of MCP2515  
static const byte MCP2515_MISO = 9 ; // SDO output of MCP2515 

static const byte MCP2515_CS  = 2 ; // CS input of MCP2515 (adapt to your design) 
static const byte MCP2515_INT = 3 ; // INT output of MCP2515 (adapt to your design)
static const byte MCP2515_RESET = 5 ; // RESET input of MCP2515 (adapt to your design)
static const byte MCP2515_STBY = 4; //  STBY input

//——————————————————————————————————————————————————————————————————————————————
//  MCP2515 Driver object
//——————————————————————————————————————————————————————————————————————————————

ACAN2515 can (MCP2515_CS, SPI, MCP2515_INT) ;

//——————————————————————————————————————————————————————————————————————————————
//  MCP2515 Quartz: adapt to your design
//——————————————————————————————————————————————————————————————————————————————

static const uint32_t QUARTZ_FREQUENCY = 20UL * 1000UL * 1000UL ; // 20 MHz

//——————————————————————————————————————————————————————————————————————————————
//   SETUP
//——————————————————————————————————————————————————————————————————————————————

void setup () {
//  STBY OFF
  pinMode(MCP2515_STBY, OUTPUT);
  digitalWrite(MCP2515_STBY, HIGH);

//--- RESET MCP2515
  pinMode (MCP2515_RESET, OUTPUT) ;
  digitalWrite (MCP2515_RESET, LOW) ;
  delay (10) ;
  digitalWrite (MCP2515_RESET, HIGH) ;
//--- Start serial
  Serial.begin (115200) ;
//--- Wait for serial (blink led at 10 Hz during waiting)
  while (!Serial) {
    delay (50) ;
  }
//--- Begin SPI
  SPI.begin (MCP2515_SCK, MCP2515_MISO, MCP2515_MOSI) ;
//--- Configure ACAN2515
  Serial.println ("Configure ACAN2515") ;
  ACAN2515Settings settings (QUARTZ_FREQUENCY, 500UL * 1000UL) ; // CAN bit rate 500 kb/s
  settings.mRequestedMode = ACAN2515Settings::NormalMode ; // Select loopback mode
  const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
  if (errorCode == 0) {
    Serial.print ("Bit Rate prescaler: ") ;
    Serial.println (settings.mBitRatePrescaler) ;
    Serial.print ("Propagation Segment: ") ;
    Serial.println (settings.mPropagationSegment) ;
    Serial.print ("Phase segment 1: ") ;
    Serial.println (settings.mPhaseSegment1) ;
    Serial.print ("Phase segment 2: ") ;
    Serial.println (settings.mPhaseSegment2) ;
    Serial.print ("SJW: ") ;
    Serial.println (settings.mSJW) ;
    Serial.print ("Triple Sampling: ") ;
    Serial.println (settings.mTripleSampling ? "yes" : "no") ;
    Serial.print ("Actual bit rate: ") ;
    Serial.print (settings.actualBitRate ()) ;
    Serial.println (" bit/s") ;
    Serial.print ("Exact bit rate ? ") ;
    Serial.println (settings.exactBitRate () ? "yes" : "no") ;
    Serial.print ("Sample point: ") ;
    Serial.print (settings.samplePointFromBitStart ()) ;
    Serial.println ("%") ;
  }else{
    Serial.print ("Configuration error 0x") ;
    Serial.println (errorCode, HEX) ;
  }
}

//----------------------------------------------------------------------------------------------------------------------

static uint32_t gBlinkLedDate = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
static uint32_t gSentFrameCount = 0 ;

//——————————————————————————————————————————————————————————————————————————————

void printFrm(CANMessage frame) {
  Serial.print(frame.id, HEX);
  Serial.print(", ");
  for(uint8_t i = 0; i < 8; i++) {
    Serial.print(frame.data[i], HEX);
    Serial.print(" ");
  }
}

void loop () {
  CANMessage frame;
  CANMessage frameRx;
  frame.id = 0x01;
  frame.len = 8;
  frame.ext = true;
  frame.data64 = 0xFF;
  if (gBlinkLedDate < millis ()) {
    gBlinkLedDate += 2000 ;
    const bool ok = can.tryToSend (frame) ;
    if (ok) {
      gSentFrameCount += 1 ;
      Serial.print ("Sent: ") ;
      Serial.println (gSentFrameCount) ;
    }else{
      Serial.println ("Send failure") ;
    }
  }
  if (can.available ()) {
    can.receive (frameRx) ;
    printFrm(frameRx);
    gReceivedFrameCount ++ ;
    Serial.print ("Received: ") ;
    Serial.println (gReceivedFrameCount) ;
  }
}

//——————————————————————————————————————————————————————————————————————————————

can any one help to check the code.:only can read the sentCount and receiveCount. i dont know why the frame_rx.id is 18,and the data[] is 0

// ACAN2515 Demo in loopback mode, for ESP32

#ifndef ARDUINO_ARCH_ESP32
#error "Select an ESP32 board"
#endif

#include <ACAN2515.h>
#include <SPI.h>
SPIClass hspi (HSPI) ;

static const byte MCP2515_SCK = 14 ; // SCK input of MCP2517
static const byte MCP2515_MOSI = 13 ; // SDI input of MCP2517
static const byte MCP2515_MISO = 12 ; // SDO output of MCP2517

static const byte MCP2515_CS = 15 ; // CS input of MCP2515 (adapt to your design)
static const byte MCP2515_INT = 32 ; // INT output of MCP2515 (adapt to your design)

#define LED_BUILTIN 33

// MCP2515 Driver object
ACAN2515 can (MCP2515_CS, hspi, MCP2515_INT) ;
// MCP2515 Quartz: adapt to your design
static const uint32_t QUARTZ_FREQUENCY = 8UL * 1000UL * 1000UL ; // 20 MHz
//————————————————————————————————————————————
// SETUP
void setup () {
//--- Switch on builtin led
pinMode (LED_BUILTIN, OUTPUT) ;
digitalWrite (LED_BUILTIN, HIGH) ;
//--- Start serial
Serial.begin (115200) ;
//--- Wait for serial (blink led at 10 Hz during waiting)
while (!Serial) {
delay (50) ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
}
//--- Begin SPI
hspi.begin () ;//MCP2515_SCK, MCP2515_MISO,MCP2515_MOSI
//--- Configure ACAN2515
Serial.println ("Configure ACAN2515") ;
ACAN2515Settings settings (QUARTZ_FREQUENCY, 500UL * 1000UL) ; // CAN bit rate 125 kb/s
settings.mRequestedMode = ACAN2515Settings::LoopBackMode ; // Select loopback mode
const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
if (errorCode == 0) {
Serial.print ("Bit Rate prescaler: ") ;
Serial.println (settings.mBitRatePrescaler) ;
Serial.print ("Propagation Segment: ") ;
Serial.println (settings.mPropagationSegment) ;
Serial.print ("Phase segment 1: ") ;
Serial.println (settings.mPhaseSegment1) ;
Serial.print ("Phase segment 2: ") ;
Serial.println (settings.mPhaseSegment2) ;
Serial.print ("SJW: ") ;
Serial.println (settings.mSJW) ;
Serial.print ("Triple Sampling: ") ;
Serial.println (settings.mTripleSampling ? "yes" : "no") ;
Serial.print ("Actual bit rate: ") ;
Serial.print (settings.actualBitRate ()) ;
Serial.println (" bit/s") ;
Serial.print ("Exact bit rate ? ") ;
Serial.println (settings.exactBitRate () ? "yes" : "no") ;
Serial.print ("Sample point: ") ;
Serial.print (settings.samplePointFromBitStart ()) ;
Serial.println ("%") ;
}else{
Serial.print ("Configuration error 0x") ;
Serial.println (errorCode, HEX) ;
}
}

//------------------------------------------------------------------------------------------------------------static uint32_t gBlinkLedDate = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
static uint32_t gSentFrameCount = 0 ;
//————————————————————————————————————————————
void loop () {
// can.poll ();
CANMessage frame_rx;
CANMessage frame_tx;
frame_tx.len = 8;
frame_tx.ext = false;
frame_tx.rtr = false;
frame_tx.idx = 0;
frame_tx.id = 0x12;

if (gBlinkLedDate < millis ()) {
gBlinkLedDate += 1000 ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
const bool ok = can.tryToSend (frame_tx) ;
if (ok) {
gSentFrameCount += 1 ;
Serial.print ("Sent: ") ;
Serial.println (gSentFrameCount) ;
}else{
Serial.println ("Send failure") ;
}
}
if (can.available ()) {
can.receive (frame_rx) ;
gReceivedFrameCount ++ ;
Serial.print ("Received: ") ;
Serial.println (gReceivedFrameCount) ;
Serial.println(frame_rx.id);
Serial.println (frame_rx.data[0]) ;
Serial.println (frame_rx.data[1]) ;
Serial.println (frame_rx.data[2]) ;
Serial.println (frame_rx.data[3]) ;
Serial.println (frame_rx.data[4]) ;
Serial.println (frame_rx.data[5]) ;
Serial.println (frame_rx.data[6]) ;
Serial.println (frame_rx.data[7]) ;
}
}

print result as below: only can read the sentCount and receiveCount. i dont know why the frame_rx.id is 18,and the data[] is 0

10:08:17.947 -> Sent: 443
10:08:17.947 -> Received: 443
10:08:17.947 -> 18
10:08:17.947 -> 0
10:08:17.947 -> 0
10:08:17.947 -> 0
10:08:17.947 -> 0
10:08:17.947 -> 0
10:08:17.947 -> 0
10:08:17.947 -> 0
10:08:17.947 -> 0

request: instrumentation counters

Firstly, thank you for such well-written and documented libraries for the 2515 and 2517.

It would be helpful if you could maintain a number of counters regarding buffer usage. This would enable users of memory-constrained MCUs to tune the buffer count and memory use. e.g.

  • buffer high-water-mark = the highest buffer use, to identify unused buffers
  • dropped messages count = lost messages due to insufficient buffer space

Thank you.

can.begin crashes when using rpi pico, with offical mbed rp2040 board

Hi
I have a raspberry pi pico, using Arduino offical mbed rp2040 board. When I test the LoopBackDemoRaspberryPiPICO sketch, my pico crashes and the LED blinks 4 short and 4 long and repeat. With some digging in(insert Serial.println into src/ACAN2515.cpp), I found that it crashes at the mSPI.beginTransaction (mSPISettings) ; line in fuction ACAN2515::beginWithoutFilterCheck, then I checked this line: mSPISettings (10UL * 1000UL * 1000UL, MSBFIRST, SPI_MODE0),, after reading the comment, I think maybe the "UL suffix" is incompatible with offical mbed rp2040 board, so I simply changed the frequency to 10000000, and uploaded the sketch, my pico never crashes!
I don't know how to edit the cpp to adapt both AVR arduino and rpi pico, so I just report this bug.
Thanks for your hardwork.
qwec01

Not able to send more than one frame (using raspberry pico)

Hi!

First thank you for making this library!

Unfortunately, I'm not able to send more than one data frame.
My setup:
Sender: raspberry pi pico with an MCP 2015 (https://joy-it.net/en/products/SBC-CAN01, handles 2 voltages)
Receiver: CANable 2.0 USB Stick / Arduino with CAN-BUS Shield V2.0 (https://wiki.seeedstudio.com/CAN-BUS_Shield_V2.0/) / Arduino MCP 2015

My sketch:

//——————————————————————————————————————————————————————————————————————————————
// ACAN2515 Demo in loopback mode, for the Raspberry Pi Pico
// Thanks to Duncan Greenwood for providing this sample sketch
//——————————————————————————————————————————————————————————————————————————————

#ifndef ARDUINO_ARCH_RP2040
#error "Select a Raspberry Pi Pico board"
#endif

//——————————————————————————————————————————————————————————————————————————————

#include <ACAN2515.h>
#include <SPI.h>

//——————————————————————————————————————————————————————————————————————————————
// The Pico has two SPI peripherals, SPI and SPI1. Either (or both) can be used.
// The are no default pin assignments so they must be set explicitly.
// Testing was done with Earle Philhower's arduino-pico core:
// https://github.com/earlephilhower/arduino-pico
//——————————————————————————————————————————————————————————————————————————————

static const byte MCP2515_SCK = 2 ; // SCK input of MCP2515
static const byte MCP2515_MOSI = 3 ; // SDI input of MCP2515
static const byte MCP2515_MISO = 4 ; // SDO output of MCP2515

static const byte MCP2515_CS = 5 ; // CS input of MCP2515 (adapt to your design)
static const byte MCP2515_INT = 1 ; // INT output of MCP2515 (adapt to your design)

//——————————————————————————————————————————————————————————————————————————————
// MCP2515 Driver object
//——————————————————————————————————————————————————————————————————————————————

ACAN2515 can (MCP2515_CS, SPI, MCP2515_INT) ;

//——————————————————————————————————————————————————————————————————————————————
// MCP2515 Quartz: adapt to your design
//——————————————————————————————————————————————————————————————————————————————

static const uint32_t QUARTZ_FREQUENCY = 16UL * 1000UL * 1000UL ; // 16 MHz

//——————————————————————————————————————————————————————————————————————————————
// SETUP
//——————————————————————————————————————————————————————————————————————————————

void setup () {
//--- Switch on builtin led
pinMode (LED_BUILTIN, OUTPUT) ;
digitalWrite (LED_BUILTIN, HIGH) ;
//--- Start serial
Serial.begin (115200) ;
//--- Wait for serial (blink led at 10 Hz during waiting)
while (!Serial) {
delay (50) ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
}
//--- There are no default SPI pins so they must be explicitly assigned
SPI.setSCK(MCP2515_SCK);
SPI.setTX(MCP2515_MOSI);
SPI.setRX(MCP2515_MISO);
SPI.setCS(MCP2515_CS);
//--- Begin SPI
SPI.begin () ;
//--- Configure ACAN2515
Serial.println ("Configure ACAN2515") ;
ACAN2515Settings settings (QUARTZ_FREQUENCY, 500UL * 1000UL) ; // CAN bit rate 500 kb/s
settings.mRequestedMode = ACAN2515Settings::NormalMode ; // Select loopback mode
const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
if (errorCode == 0) {
Serial.print ("Bit Rate prescaler: ") ;
Serial.println (settings.mBitRatePrescaler) ;
Serial.print ("Propagation Segment: ") ;
Serial.println (settings.mPropagationSegment) ;
Serial.print ("Phase segment 1: ") ;
Serial.println (settings.mPhaseSegment1) ;
Serial.print ("Phase segment 2: ") ;
Serial.println (settings.mPhaseSegment2) ;
Serial.print ("SJW: ") ;
Serial.println (settings.mSJW) ;
Serial.print ("Triple Sampling: ") ;
Serial.println (settings.mTripleSampling ? "yes" : "no") ;
Serial.print ("Actual bit rate: ") ;
Serial.print (settings.actualBitRate ()) ;
Serial.println (" bit/s") ;
Serial.print ("Exact bit rate ? ") ;
Serial.println (settings.exactBitRate () ? "yes" : "no") ;
Serial.print ("Sample point: ") ;
Serial.print (settings.samplePointFromBitStart ()) ;
Serial.println ("%") ;
} else {
Serial.print ("Configuration error 0x") ;
Serial.println (errorCode, HEX) ;
}
}

//----------------------------------------------------------------------------------------------------------------------

static uint32_t gBlinkLedDate = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
static uint32_t gSentFrameCount = 0 ;

//——————————————————————————————————————————————————————————————————————————————

void loop () {
CANMessage frame ;
if (gBlinkLedDate < millis ()) {
frame.len = 4;
frame.data[0] = 42;
frame.data[2] = 0;
frame.data[3] = 42;
frame.data[4] = 1;

frame.id = gSentFrameCount + 1; //iterate id

gBlinkLedDate += 2000 ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
const bool ok = can.tryToSend (frame) ;
if (ok) {

  gSentFrameCount += 1 ;
  Serial.print ("Sent: ") ;
  Serial.print (gSentFrameCount) ;
  Serial.print (" - ") ;
  Serial.println (frame.id) ;

} else {
  Serial.println ("Send failure") ;
}

}

}

//——————————————————————————————————————————————————————————————————————————————

I receive always the first frame, and then nothing more. The sender (pi pico) then fails after the 17th iteration (full send buffer). So it seems, there is never a receive ack. I would be very happy for any ideas or hints as I have stared at my code for quite some time now.

thank you!

Filter RTR frames

Hi, Pierre

I got a question on RTR frames. I want to tell apart whether a received message is a RTR frame by the value of RTR bit. But when I sent a RTR frame with RTR bit == 1, and tried to use a filter to receive it, in the end the RTR bit of this received message becomes 0.

Then I notice that in the ACAN2515 document, section 9.2 on page 20, it says :

Filter remote and data frames. The MCP2515 filters do not handle the RTR bit: for example, you cannot specify you want to accept data frames and discard remote frames. This should be done by your code.

Does that mean a filter will set the RTR bit to 0 automatically, even I set it to 1 before sending?
If that is true, to tell apart a RTR frame, do I have to manually dispatch the received messages as decribed in section 8 on page 18?

kTooFarFromDesiredBitRate-issue with Arduino MKR Wifi 1010

Hello,

I am using this MKR CAN Shield for an Arduino MKR Wifi 1010. When I try your example "LoopBackDemo.ino" I get the following error:

Configuration error 0x1

This has to with a kTooFarFromDesiredBitRate-issue. But I haven't changed anything on the code and the bitrate is set to:

ACAN2515Settings settings (QUARTZ_FREQUENCY, 125UL * 1000UL) ;

Can this be a problem with the CAN shield itself? I would expect that the LoopBackDemo-code should not give this error.

Thanks in advance,
Bart

Can not receive EXT CAN

Can you check why This code can print standard can id but not ext can id. If I receive 11 bit ID then it can receive ok but if i receive 29 bit id then the loop function never print anything. Note that in my BUS have 11 bit ID and 29Bit ID too
`
#include <ACAN2515.h>
CANMessage canMsg_rx;
static const byte MCP2515_CS1 = 10 ; // CS input of MCP2515 CAN1
static const byte MCP2515_INT1 = 2 ; // INT output of MCP2515 CAN1
ACAN2515 CAN1(MCP2515_CS1, SPI, MCP2515_INT1);
static const uint32_t QUARTZ_FREQUENCY = 16UL * 1000UL * 1000UL; // 16 MHz
void setup() {
Serial.begin (115200) ;
while (!Serial) {
delay (50) ;
}
SPI.begin();
ACAN2515Settings settings (QUARTZ_FREQUENCY, 500 * 1000UL);
settings.mTransmitBuffer0Size = 5 ;
settings.mTransmitBuffer1Size = 0 ;
settings.mTransmitBuffer2Size = 0 ;
settings.mReceiveBufferSize = 5 ;
settings.mRequestedMode = ACAN2515Settings::NormalMode;
const uint16_t errorCode1 = CAN.begin(settings, [] {CAN.isr();});
if (errorCode1 != 0) {
Serial.print ("Configuration CAN error 0x") ;
Serial.println (errorCode1, HEX) ;
} else {
Serial.println ("Configuration CAN OK!") ;
}
}

void loop() {
if (CAN.receive(canMsg_rx)) {
Serial.println(canMsg_rx.id, HEX);
}
}

`

Test sketch block after 17 send messages

What did I do wrong within this sketch on arduino UNO?
it will send only 17 meassages , then I have "failure" in the serial interface .

<
/*
*
*/
#include <ACAN2515.h>

static const byte MCP2515_CS = 10 ; // CS input of MCP2515 (adapt to your design)
static const byte MCP2515_INT = 3 ; // INT output of MCP2515 (adapt to your design)

ACAN2515 can (MCP2515_CS, SPI, MCP2515_INT) ;

static const uint32_t QUARTZ_FREQUENCY = 8UL * 1000UL * 1000UL ; // 8 MHz

void setup() {

Serial.begin (38400) ;

while (!Serial) {
delay (50) ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
}
SPI.begin () ;

ACAN2515Settings settings (QUARTZ_FREQUENCY, 500UL * 1000UL) ; // CAN bit rate 500 kb/s
const uint16_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
if (errorCode == 0) {
Serial.print ("Bit Rate prescaler: ") ;
Serial.println (settings.mBitRatePrescaler) ;
Serial.print ("Propagation Segment: ") ;
Serial.println (settings.mPropagationSegment) ;
Serial.print ("Phase segment 1: ") ;
Serial.println (settings.mPhaseSegment1) ;
Serial.print ("Phase segment 2: ") ;
Serial.println (settings.mPhaseSegment2) ;
Serial.print ("SJW: ") ;
Serial.println (settings.mSJW) ;
Serial.print ("Triple Sampling: ") ;
Serial.println (settings.mTripleSampling ? "yes" : "no") ;
Serial.print ("Actual bit rate: ") ;
Serial.print (settings.actualBitRate ()) ;
Serial.println (" bit/s") ;
Serial.print ("Exact bit rate ? ") ;
Serial.println (settings.exactBitRate () ? "yes" : "no") ;
Serial.print ("Sample point: ") ;
Serial.print (settings.samplePointFromBitStart ()) ;
Serial.println ("%") ;
}else{
Serial.print ("Configuration error 0x") ;
Serial.println (errorCode, HEX) ;
}
}
static uint32_t gBlinkLedDate = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
static uint32_t gSentFrameCount = 0 ;
byte msg[8] = {0, 0, 0, 0, 0, 0, 0, 0};

void loop() {

byte msg[8] = { 12, 23, 33, 44, 55, 66, 77, 28};

CANMessage frame ;
frame.id = 31 ;
frame.ext = true ;
frame.rtr = false ;
frame.idx = 0 ;
frame.len = 8 ;
for (int i=0 ; i<8 ; i++) {
frame.data [i] = {msg[i]} ;
}
/* frame.data [0] = {egt[1]} ;
frame.data [1] = {egt[2]} ;
frame.data [2] = 33 ;
frame.data [3] = 44 ;
frame.data [4] = 55 ;
frame.data [5] = 66 ;
frame.data [6] = 77 ;
frame.data [7] = 88 ;
*/
if (gBlinkLedDate < millis ()) {
gBlinkLedDate += 50 ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
const bool ok = can.tryToSend (frame) ;
if (ok) {
gSentFrameCount += 1 ;
Serial.print ("Sent: ") ;
Serial.println (gSentFrameCount) ;
}else{
Serial.println ("Send failure") ;
}
}
}

INT pin not working in LoopBackDemo example

Hi Pierre

I am trying to use your library for an MCP2515 connected to a Raspberry Pi Pico. Using your LoopBackDemo sketch (among others), it seems that the configuration of the MCP2515 runs fine.

However, when it comes to transmitting and receiving frames, it only prints "Sent: 1" up to "Sent: 17". As you explain in the sketch's comments, this indicates to be a problem with the interrupt. I have checked the INT pin on the MCP2515 with an oscilloscope while running the sketch, and it doesn't generate an interrupt on that pin. Could there perhaps be something that is not configured correctly when the MCP2515 is initialised?

I see that in the function internalBeginOperation() you write the value 0x1F to register CANINTE, which enables the TX and RX interrupts, so I would expect the interrupt to work when the frames are sent. However, this doesn't happen.

My test is performed using a 12 MHz crystal and the Raspberry Pi Pico. The same test performed with an Arduino Due has the same result.

What could be the cause of this?

Thank you in advance.

Info: ACAN2515 works fine on Raspberry Pi Pico

Pierre,

Just to let you know that your library works fine on the Raspberry Pi Pico with the 'unofficial' core: https://github.com/earlephilhower/arduino-pico

The Pico SPI peripherals can use any pins, and there are no defaults, so you need to explicitly set these before initialising the library. The Pico has two SPI peripherals, SPI and SPI1, so you could use either (or both).

#include <SPI.h>

static const byte PICO_INT = 1;
static const byte PICO_SCK = 2;
static const byte PICO_MOSI = 3;
static const byte PICO_MISO = 4;
static const byte PICO_CS = 5;

// configure SPI pins
SPI.setSCK(PICO_SCK);   // SCK
SPI.setTX(PICO_MOSI);   // MOSI
SPI.setRX(PICO_MISO);   // MISO
SPI.setCS(PICO_CS);     // CS

There was a minor bug in the core (NOT_AN_INTERRUPT was not #defined) but this has been fixed now.

Let me know if you want to support this board explicitly and I'd be happy to test any changes.

Work is in progress by the Arduino project on an 'official' core for the Pico.

ACAN25215 avec le CAN-BUS shield seeedsstudio et Arduino Mega

Bonjour Pierre,

Je teste votre bibliothèque avec un shield seeeds et un Arduino UNO sans aucun problème. Mais je n'arrive pas avec un MEGA.

Voici mes réglages

`//——————————————————————————————————————————————————————————————————————————————
// ACAN2515 Demo in loopback mode
//——————————————————————————————————————————————————————————————————————————————

#include <ACAN2515.h>
//——————————————————————————————————————————————————————————————————————————————
// MCP2515 connections:
// - standard SPI pins for SCK, MOSI and MISO
// - a digital output for CS
// - interrupt input pin for INT
//——————————————————————————————————————————————————————————————————————————————
// If you use CAN-BUS shield (http://wiki.seeedstudio.com/CAN-BUS_Shield_V2.0/) with Arduino Uno,
// use B connections for MISO, MOSI, SCK, #9 or #10 for CS (as you want),
// #2 or #3 for INT (as you want).
//——————————————————————————————————————————————————————————————————————————————

#ifdef ARDUINO_AVR_MEGA2560

static const byte MCP2515_SCK = 52 ; // SCK input of MCP2515
static const byte MCP2515_SI = 51 ; // SI output of MCP2515
static const byte MCP2515_SO = 50 ; // S0 output of MCP2515

static const byte MCP2515_CS = 53 ; // CS input of MCP2515
static const byte MCP2515_INT = 2 ; // INT output of MCP2515

#endif

#ifdef ARDUINO_AVR_UNO

static const byte MCP2515_SCK = 13 ; // SCK input of MCP2515
static const byte MCP2515_SI = 11 ; // SI output of MCP2515
static const byte MCP2515_SO = 12 ; // S0 output of MCP2515

static const byte MCP2515_CS = 10 ; // CS input of MCP2515
static const byte MCP2515_INT = 2 ; // INT output of MCP2515

#endif`

Merci pour votre aide.

Christophe

How to locate errocode

When I tried this, I met an error. The errorcode is 0x8, but I cant find out what it exactly is.
image

RX0OVR bit gets stuck

Sometimes, under heavy receive load, the RX0OVR bit in the error flag register get 'stuck' on. The errorFlagRegister() method returns 64. It's difficult to reproduce reliably.

RX0OVR: Receive Buffer 0 Overflow Flag bit
Sets when a valid message is received for RXB0 and RX0IF (CANINTF[0]) = 1 - Must be reset by MCU

It does coincide with a 'lost' message at the application level (I track a message sequence number in my code). Only a power cycle or grounding the reset pin will resolve it.

I am not using interrupts and am polling frequently for new messages. Receive buffers = 8 but the high watermark is never above 2.

Any thoughts ? Thanks.

MCU is an AVR (1284P).

ESP32 crashes when irq pin set to -1 and inInterruptServiceRoutine is NULL

When there are no IRQ pin specified, acan2515 requires inInterruptServiceRoutine to be NULL

There is no check for mINT != 255 thus this task is still created

    #ifdef ARDUINO_ARCH_ESP32
      xTaskCreate (myESP32Task, "ACAN2515Handler", 1024, this, 256, NULL) ;
    #endif

It also seems that 1024 is not enough stack size for the task on my esp32 because i've got stack cannary watchpoint triggered before noticing the main issue(Probably stack overflow).

After i fixed the problem it appeared that attachMCP2515InterruptPin
attaches NULL to -1 pin which causes crash.

#ifdef ARDUINO_ARCH_ESP32
  static void myESP32Task (void * pData) {
    ACAN2515 * canDriver = (ACAN2515 *) pData ;
    while (1) {
      canDriver->attachMCP2515InterruptPin () ;
      xSemaphoreTake (canDriver->mISRSemaphore, portMAX_DELAY) ;
      bool loop = true ;
      while (loop) {
        loop = canDriver->isr_core () ;
      }
    }
  }
#endif

I tried to remove iterrupt task at all, but then i noticed that there are no mechanisms to poll messages, so it would not work anyway.

I didn't look more throught the code, so i am curious how to use this library without an IRQ pin on ESP32?

Default SPI on Pi Pico (RP2040)

Wanting to use your library on a Pi Pico, sitting on a prebuilt circuit board that has an SPI device (MCP2515) on the 'default' SPI pins of the Pi Pico module (GPIO 16 - 19)

Unfortunately, the 'standard' Arduino SPI library uses GPIO2 - GPIO5 - I've proved this by running an SPI 'loopback' test
And I see your library uses this library <SPI.H>
The default <SPI.H> doesn't appear to allow you to redefine the pins used

Any idea how I can resolve this? (I'd rather not cut pcb tracks to re-work the physical pins)

I did get the SPI test working on the 'default' pins using <mbed.h> instead of <SPI.H>, as <mbed.h> allows you to redefine the pins used, but the syntax of the SPI functions seems to be slightly different, and of course your library uses <SPI.H>, so I don't see how that helps

If it's any use, here's the build info for the working test I mentioned using <SPI.H>

`
PLATFORMPLATFORM: Raspberry Pi RP2040 (1.5.0) > Raspberry Pi Pico
HARDWARE: RP2040 133MHz, 264KB RAM, 2MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, jlink, raspberrypi-swd)
PACKAGES:

  • framework-arduino-mbed 2.6.1
  • tool-rp2040tools 1.0.2
  • toolchain-gccarmnoneeabi 1.90201.191206 (9.2.1)
    `

can.tryToSend crashes when using rpi pico, with offical mbed rp2040 core

I have a raspberry pi pico, using Arduino official mbed rp2040 core
framework-arduino-mbed 2.6.1
tool-rp2040tools 1.0.2
When I test the 'generic' LoopBackDemo sketch, my pico crashes on the can.tryToSend call and the LED blinks 4 short and 4 long and repeat.
(the "LoopBackDemoRaspberryPiPico" doesn't compile with the offical mbed core, it seems to use other 'SPI' commands)

The "Configure ACAN2515" section runs fine and prints out the expected results (attached below)

So, I'm assuming the SPI is talking to the MCP2515 just fine?

If I comment out the can.tryToSend (with a true return) the loop runs fine

I saw a similar previous issue here but that crashed at can.begin(), which isn't my issue (my code runs past this command), so although I tried their work around, not surprisingly it didn't help
`
Any idea what I could try or what to look at to resolve this?

Bit Rate prescaler: 4
Propagation Segment: 5
Phase segment 1: 5
Phase segment 2: 5
SJW: 4
Triple Sampling: yes
Actual bit rate: 125000 bit/s
Exact bit rate ? yes
Sample point: 62%
`

Error and Wake-up interrupt handling

Using this with MKR Zero and MKR Can Shield. My program freezes randomly without crashing. I've tested on SRAM overflow, memory corruption etc and everything should work fine.

I'm currently suspecting it has todo with the ACAN2515::isr_core routine
MCP2515 Datasheet says that one have to set every intflag to zero with BIT_MODIFY command. But in the isr_core routine if an Error Interrupt or Wake-Up Interrupt flag is set. It will never bet unset so the while loop will never exit.

I've probably missed something on why you do that. But can you explain me on how the while loop in ACAN2515::isr_core will exit when Error or Wakeup Intflag is set?

Feature request: Interruptable ISR

Hi Pierre,

I found that I can allow the ISR to be interruptable, thereby lowering the latency of other interrupts significantly, as follows:

static void can_isr () { // We don't want to block interrupts whilst performing low-level CAN processing ...
  detachInterrupt(digitalPinToInterrupt(CAN_INT)) ;
  interrupts();
  can.isr();
  noInterrupts();
  attachInterrupt(digitalPinToInterrupt(CAN_INT),can_isr,LOW);
}

However, that's a bit of a hassle, including the attachInterrupt after ACAN2515::begin and the detachInterrupt prior to ACAN2515::end.

Can you add ISR interuptability as an option?

Kind regards,
Sebastian

Librairie ACAN2515

Excusez-moi si je parle francais.J'ai mis ci dessous une traduction de google:
j'utilise les exemples donnés sur Locoduino ou sur d'autres sites avec la bibliotheque ACAN2515 de Pierre Molinaro.
J’utilise un arduino UNO R3 qui n’est pas un clone et 2 HailegeMCP2515 CAN bus module TJA 1050 Receiver SPI for Arduino AVR.
. Dans le programme loopback avec donnees j’ai le message d’erreur « Erreur 0x1 ».
J’ai réalisé le programme ’application de commande deux LED via le bus CAN « J’ai le message d’erreur « probleme de connexion » sur les deux arduino. J’ai corrigé la bibliothèque :
#include <ACAN2515_Buffer16.h>
#include <ACANBuffer.h>
#include <ACAN2515Settings.h>
Mais les deux premières lignes n’apparaissent pas en rouge. Elles sont pourtant bien dans le dossier bibliothèque de ACAN2515.
J’ai vérifié et revérifié toutes mes connexions. J’ai ponté J1.
Toujours idem".
Quelques soient les programmes utilisés, meme les plus simples tous "bug" soit à la compilation, soit lors de l'exécutionJe ne trouve pas de solution.
merci d'une réponse.
I use the examples given on Locoduino or on other sites with the ACAN2515 library by Pierre Molinaro.
I use an arduino UNO R3 which is not a clone and 2 HailegeMCP2515 CAN bus module TJA 1050 Receiver SPI for Arduino AVR.
. In the loopback program with data I get the error message “Error 0x1”.
I created the application program for controlling two LEDs via the CAN bus. “I have the error message “connection problem” on both arduinos. I corrected the library:
#include <ACAN2515_Buffer16.h>
#include <ACANBuffer.h>
#include <ACAN2515Settings.h>
But the first two lines do not appear in red. However, they are in the library folder of ACAN2515.
I checked and rechecked all my connections. I bridged J1.
Always the same.”
Whatever programs are used, even the simplest ones, all "bug" either during compilation or during execution. I cannot find a solution.
thank you for a response.

Sleep mode example

Firstly thank you for this library it is very very useful.

I'm trying to understand the sleep function, would it be possible to add to your examples, that would be great.

At the moment I put the transiever in standby then change the mode to sleep. I have also enabled the interrupt pins wake on CAN function.

When there is traffic on the CAN the interrupt works, I then take the transiever out of standby and change the mode to normal.
The return value from the changeModeOnTheFly function is 0, so appears good.

I then use CAN tryandsend (which returns true) but nothing appears on the CAN bus where as it did before I put the unit into sleep.

If I don't put the can transiever into stanby and only use sleep the same happens.

When I come out of sleep mode the can recieve message appears to be constanlty fired as if the read register bit is not being cleared anymore....

I could well be doing something wrong and thanks for any help.

stuck in begin()

On Arduino Nano 168 with standard loopbackdemo the mcu get's stuck and shows only "Configure ACAN2515".

CAN extended send,but not receiv

` CANMessage Message ;
Message.ext=true;

if (gBlinkLedDate < millis ()) {
gBlinkLedDate += 1000 ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
Message.id = 0x542;
const bool ok = can.tryToSend (Message) ;
if (ok) {
gSentFrameCount += 1 ;
Serial.print ("Sent: ") ;
Serial.println (gSentFrameCount) ;
}else{
Serial.println ("Send failure") ;
}
}
// if (can.available ()) {
Message.ext=true;
if (can.receive (Message)){
gReceivedFrameCount ++ ;
Serial.println ("Received: ") ;
Serial.print ("id: ");Serial.println (Message.id,HEX);
Serial.print ("ext: ");Serial.println (Message.ext);
Serial.print ("rtr: ");Serial.println (Message.rtr);
Serial.print ("len: ");Serial.println (Message.len);
Serial.print ("data: ");
for(int x=0;x<Message.len;x++)
{
Serial.print(Message.data[x],HEX);Serial.print(":");
}
Serial.println ("");
Serial.println (gReceivedFrameCount) ;
}
}`

standart frame work good (sending and receving)
29bit frame work sending but not receving
can.available method return false and can.receive method return false

CAN extended only sending standard ID

Great library you have here and incredibly well documented. I have two devices CAN lines connected to each other sending data back and forth. The chip with the ACAN library can receive CAN packets no problem but when it transmits packets extended ID's become standard ID's. This is not a problem with receiving so I am a little stumped what could be the issue. I have attached my code of transmitting below. Thank you so much for your help.

            can1.poll();

	CAN1_Transmit_Frame.rtr = false;
	CAN1_Transmit_Frame.ext == true;
	CAN1_Transmit_Frame.id = 0x180238f1;
	CAN1_Transmit_Frame.len = 8;
	//CAN1_Transmit_Frame.id;

	CAN1_Transmit_Frame.data64 = mcu_power_control.controller_out;

	Serial.print(CAN1_Transmit_Frame.id,HEX);
	Serial.println(",");

	bool can_attempt = can1.tryToSend(CAN1_Transmit_Frame);
	if (can_attempt)
	{
		Serial.print("packet_sent");
	}

question experience CAN-bus Nissan Leaf 2016

Hello,

First of all thanks for the great library. I want use your library to smartcharge my electric car, a Nissan Leaf model 2016. Do you have a simple example code for this?

Thanks in advance,
Bart

ACAN2515::begin() hangs if less than about 900b free RAM is left on Arduino UNO

To reproduce put the following code before ACAN2515::begin() in LoopBackDemo:
static char Buf[600]; Serial.print(Buf);
Result:
Sketch uses 7532 bytes (24%) of program storage space. Maximum is 30720 bytes.
Global variables use 1122 bytes (54%) of dynamic memory, leaving 926 bytes for local variables. Maximum is 2048 bytes.
Checked with Arduino IDE 1.8.8 (1.8.19.0 in Windows Store). I would expect some error to be returned instead, and if the library has indeed so large memory requirements then it could be stated in the documentation. It also prevents usage of two instances (with two CAN interfaces).

lookbackdemoESP32:I only can read the receiveFrameCount and the sentFrameCount, Can not read and send the data[],why . Can any one give a sample about to sent data and receive data. thanks

void loop () {
CANMessage frame_rx;
CANMessage frame_tx;
frame_tx.len = 8;
frame_tx.ext = false;
frame_tx.rtr = false;
frame_tx.idx = 0;
frame_tx.id = 0x12;

if (gBlinkLedDate < millis ()) {
gBlinkLedDate += 2000 ;
digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ;
const bool ok = can.tryToSend (frame_tx) ;
if (ok) {
gSentFrameCount += 1 ;
Serial.print ("Sent: ") ;
Serial.println (gSentFrameCount) ;
}else{
Serial.println ("Send failure") ;
}
}
if (can.available ()) {
can.receive (frame_rx) ;
gReceivedFrameCount ++ ;
Serial.print ("Received: ") ;
Serial.println (gReceivedFrameCount) ;
Serial.println (frame.data[0]) ;
Serial.println (frame.data[1]) ;
Serial.println (frame.data[2]) ;
Serial.println (frame.data[3]) ;
Serial.println (frame.data[4]) ;

}
}

ESP32 Some MCP2515 not response to ESP32

I'm connecting 3 MCP2515 to esp32 each of which Initializing is done After that, some MCP2515 stops are available to esp32.
I measure single CS and INT during not a response to esp32, CS always HIGH and INT always LOW.

My setup
// Init CAN
SPI.begin();

ACAN2515Settings settings1(QUARTZ_FREQUENCY, 500UL * 1000UL); // 500 kpbs
ACAN2515Settings settings2(QUARTZ_FREQUENCY, 500UL * 1000UL); // 500 kpbs
ACAN2515Settings settings3(QUARTZ_FREQUENCY, 500UL * 1000UL); // 500 kpbs

settings1.mRequestedMode = ACAN2515Settings::NormalMode;
settings1.mReceiveBufferSize = 100;
uint16_t errorCode1 = can1.begin(settings1, []
                                 { can1.isr(); });

delay(50);

settings2.mRequestedMode = ACAN2515Settings::NormalMode;
settings2.mReceiveBufferSize = 100;
uint16_t errorCode2 = can2.begin(settings2, []
                                 { can2.isr(); });

delay(50);

settings3.mRequestedMode = ACAN2515Settings::NormalMode;
settings3.mReceiveBufferSize = 100;
uint16_t errorCode3 = can3.begin(settings3, []
                                 { can3.isr(); });

delay(50);

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.