Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use NMEA2000 CANBUS with Arduino UNO R4 Minima #349

Closed
ohoriyoshi opened this issue Sep 14, 2023 · 5 comments
Closed

How to use NMEA2000 CANBUS with Arduino UNO R4 Minima #349

ohoriyoshi opened this issue Sep 14, 2023 · 5 comments

Comments

@ohoriyoshi
Copy link

"I am considering using the Arduino UNO R4 Minima board to build a device analyzer in order to downsize from the DUE. I would appreciate some advice on this."

@ttlappalainen
Copy link
Owner

Either use external MCP2515 chip and NMEA2000_mcp module or study CAN controller withing Arm Cortex m4 and write library compatible driver for that.

@jboynes
Copy link
Contributor

jboynes commented Nov 1, 2023

For the Uno R4, Arduino extended the core's API to include CAN support. I started on a driver that works with that API here.

I've tested this with the Uno R4 Wifi using a generic TJA1050 transceiver module and it at least talks to another device. I tested with the TemperatureSender example using PlatformIO.

[env:uno_r4_wifi]
platform = renesas-ra
board = uno_r4_wifi
framework = arduino
monitor_speed = 115200
lib_deps =
    https://github.com/jboynes/NMEA2000_ArduinoCAN.git

I haven't updated the detection code in NMEA2000_CAN.h yet so to use this you need to include the library directly in your sketch:

#include <NMEA2000_ArduinoCAN.h>

I also knocked up a quick prototype for a shield to use this with. The main design criteria was "parts JLCPCB have to hand" so it's not particularly robust but hopefully will be enough to test it. I should have hardware in hand in a week or so.

@ttlappalainen
Copy link
Owner

I always have big doubts for CAN APIs and NMEA2000 compatibility. At start you should check how do they handle frame sending. Many can controllers has internally several mailboxes. CAN APIs then simply fill next free mailbox, when sending frames. Unfortunately since mailboxes has different priorities, this then destroys NMEA2000 fastpacket sending. Fastpackets contains several frames and they has to be sent in order. Example if there is 3 mailboxes 1-3 and 1 has highest priority. You first write 2 single frames, which go to mailboxes 1,2. Then you write fastpacket with 3 frames so first frame goes to mailbox 3 and others are in buffer waiting. At this point nothing has necessarily sent to but, but mailbox 1 is on the way. So when 1 is out, 2 starts to be sent. At that point fastpacket second frame will be moved to mailbox 1 for waiting. Now when 2 has been finished, CAN controller starts to send next frame from mailbox 1, since that has higher priority. So now fastpacket starting frame is still waiting in mailbox 3 and 2. frame is ont the way and message can not be read by others.

So problem is that to keep NMEA2000 compatibility there should be deeper API to control also controller internal mailboxes. If Arduino offers API and does not offer control for mailboxes, it may work or may not. It works, if hw CAN controller has only one mailbox or API forces to use only one. But if controller has several mailboxes and CAN API just uses them in free order, it does not work and you will see that on missed messages. Also one problem is that API may work with board having CAN controller with only one mailbox, but not with board, which has more powerfull CAN controller with several mailboxes. And this would be very confusing for users!

So before you even try to add Arduino CAN API for NMEA2000 detection code, you should prove that above would work correctly.

@jboynes
Copy link
Contributor

jboynes commented Nov 2, 2023

The CAN function was a recent addition to the official Arduino API (vs. the ones from 3P libraries) and I think the only core that uses it at the moment is the Renesas one for the UNO R4 and Portenta C33.

Although the controller has multiple mailboxes and a FIFO option, the driver for the UNO only uses a single one so reordering should not be an issue. On the chance that might change in the future, I opened an issue on the API site to see if the behaviour could be formalized.

For detection, they have defines which should make that pretty simple. Those are also pretty specific so detection would be tied to a specific board and core rather than a generic API.

@jboynes
Copy link
Contributor

jboynes commented Nov 3, 2023

I had a response from the maintainer at Ardunino (who also implemented the CAN support for the UNO R4) that confirmed the intention that frames would be sent in sequence. This has now been added to the API documentation so I think it would be safe to assume future cores will maintain that behaviour.

I have some detection code in a fork and will submit a PR for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants