pierremolinaro / acan2515

MCP2515 CAN Controller Driver for Arduino
MIT License
74 stars 29 forks source link

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

Closed omitron closed 9 months ago

omitron commented 9 months ago

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

include

//—————————————————————————————————————————————————————————————————————————————— // 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!

pierremolinaro commented 9 months ago

Hi,

First thank you for making this library!

Thank you! Unfortunately, I'm not able to send more than one data frame.

The pin settings are ok, can you try in loop back mode ?

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 same time now.

Can you observe the CAN bus with a logic analyzer ? This can be usefull for finding what is going wrong.

Note you send frames with increasing identifier :

frame.id = gSentFrameCount + 1; //iterate id The priority of the frames are decreasing with identifier values. Is the other CAN tries also to send frames ? Pierre

Le 17 nov. 2023 à 22:16, omitron @.***> a écrit :

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

include

//—————————————————————————————————————————————————————————————————————————————— // 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 same time now.

thank you!

— Reply to this email directly, view it on GitHub https://github.com/pierremolinaro/acan2515/issues/45, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEWKZVCLGRHZT55RIQVDM33YE7HZDAVCNFSM6AAAAAA7QL2Z5OVHI2DSMVQWIX3LMV43ASLTON2WKOZRHE4TSOJTHAZDGMQ. You are receiving this because you are subscribed to this thread.

nsghub commented 9 months ago

I'm having the same exact problem. When I change the send buffer size, the tryToSend success rate changes accordingly. I also didn't have any success in receiving data from the bus. The INT pin is triggered and the ISR is called but then available functions returns false. I didn't try polling yet. I could try an some Arduino nano board, just to verify the hardware setup.

omitron commented 9 months ago

Hi!

Sorry for the late response, I just had today one hour to work on my setup. I switched to LoopBackMode and also did not change the id as recommended. I then went back to the LoopBackExample from the git examples. This is the serial output:

SPI::begin(0), rx=4, cs=5, sck=2, tx=3 SPI::beginTransaction(clk=4000000, bo=MSB) SPI: initting SPI SPI: actual baudrate=4000000 Configure ACAN2515 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: deinitting currently active SPI SPI: initting SPI SPI: actual baudrate=8000000 SPI::transfer(c0), cpol=0, cpha=0 SPI: read back 00 SPI::endTransaction() SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::transfer(02), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(2a), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(55), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(03), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(2a), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(00), cpol=0, cpha=0 SPI: read back 55 SPI::transfer(02), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(2a), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(aa), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(03), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(2a), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(00), cpol=0, cpha=0 SPI: read back aa SPI::endTransaction() SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::transfer(02), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(28), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(06), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(ed), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(c3), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(1f), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(02), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(0c), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(00), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(02), cpol=0, cpha=0 SPI: read back 00 SPI::transfer(0d), cpol=0, cpha=0 SPI: read back 00 Sent: 7 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 8 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 9 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 10 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 11 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 12 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 13 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 14 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 15 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 16 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Sent: 17 SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Send failure SPI::beginTransaction(clk=10000000, bo=MSB) SPI: Reusing existing initted SPI SPI::endTransaction() Send failure .....

I checked the wiring and also measured the cables. All seams fine especially as I could get the very first sample/message over the CAN bus.

I might have more time on Sunday to try more but would always be very happy for any insights!

Thank you! Michael

omitron commented 9 months ago

Hi!

IT WORKS! Finally! The only problem is, I don't know what was wrong. As I couldn't find the problem I decided to start completely over. Did all the hardware setup again, used different wires, etc. I didn't change any of my software except updating to the newest Arduino-pico (https://github.com/earlephilhower/arduino-pico) but I somehow doubt this was the problem. My best guess is some problems with the wires (loose contact inside) so that I got a current through when I measured.

Thank you Michael