How to select the best possible library for CAN?

I'm planning to use Arduino to control a Maxon EC90 motor that will drive an orthesis and assist a user to walk a bit better. Could be considered as an exoskeleton for the knee joint only.
By using the Arduino and low-level controls, I hope to achieve smooth movement that is a major challenge when motors support human movement.
My hardware setup is connected as follows: Arduino Uno - CAN Shield (Robotdyn MCP2515 based) - CAN bus - Maxon EPOS4 motor controller - Maxon EC90 motor.
I am now facing a few challenges getting CAN to work.
I also see on this forum that attempts have been made, but success was limited (at least reported success on this forum). One project using the Seeedstudio CAN library + seemingly Github _dfs reported ability to communicate with EPOS4 and poll parameters, but no motor movement. This project however already performed a great amount of work building and structuring the data packets for EPOS4 that go on the CAN bus, so I'd like to reuse what I can.
What I already found is

  • many CAN libraries seem to exist and code examples published on this forum only seem to compile with the correct library (and maybe version) installed.
  • Different CAN libraries work in a different way.
  • CAN libraries come in 2 parts: mcp_can and mcp_can_dfs
    My conclusion is that I won't be able to continue from an existing example and will need to start from scratch, importing code from examples where I can.
    The advise I'm looking right now for is: How to select the best possible CAN library to start working with? Once chosen, it will be hard to change to another one.
  • The Arduino Library Manager installs ACAN2515 libraries (pierremolinaro) - also on Github
  • Github has got Arduino CAN for MCP2515 libraries (sandeepmistry)
  • Seeedstudio has a CAN library for MCP2515
    Side question is: Why do these CAN libraries come in 2 parts and what does "dfs" stand for : mcp_can.h and mcp_can_dfs.h
    Thanks in advance for all help.

I use the ESP32 CAN library, its multi threaded and the use of freeRTOS queues allows for background processing of can transmissions.

Idahowalker:
I use the ESP32 CAN library

From the "ESP32" part of that, it doesn't sound like it will be useful to @OldFrank, who is using an Arduino Uno board:

OldFrank:
My hardware setup is connected as follows: Arduino Uno - CAN Shield (Robotdyn MCP2515 based) - CAN bus - Maxon EPOS4 motor controller - Maxon EC90 motor.


OldFrank:

  • The Arduino Library Manager installs ACAN2515 libraries (pierremolinaro) - also on Github

This one I presume:

OldFrank:

  • Github has got Arduino CAN for MCP2515 libraries (sandeepmistry)

That one is definitely of interest. Sandeep Mistry was one of Arduino's firmware developers for years. Sandeep does excellent work, but I haven't tried that library. If anyone else is interested, you can see it here:

OldFrank:

  • Seeedstudio has a CAN library for MCP2515

For the convenience of others, I'll provide the link:

There is another library you didn't mention that seems to be quite popular and is recommended by someone I know who is very knowledgeable about CAN bus:

Unfortunately, when I used this library, I found it has a serious bug, where it is initializing SPI from the constructor, a big no-no. The community submitted a fix here:

but the library author didn't merge it yet. So if you use that one I definitely recommend using the fork from that pull request:

or just making the SPI.begin() part of the pull request manually:

Thanks for all replies and adding the correct links to the relevant repositories. I'll add those myself in the future if asking questions. The replies helped me obtain a much better view on what is out there.
I'll start trying with the ACAN2515 and see how far I can get with that library. Will keep you informed.

Update:
I have learned a lot, but no communications over the CAN bus yet.
I started further analyzing and testing the existing libraries.
One general observation is that there seems a large programming skills gap between library authors and library users. The example code I find is rather advanced, on many occasions using features not documented in the Arduino reference.
For example: The Arduino reference has only this example on constants [and a bit of explanation]

const float pi = 3.14;

What I find in the acan2515-master library - loopBackDemo example is code like this

const bool ok = can.tryToSend (frame);
if (ok) {
      gSentFrameCount += 1 ;
      Serial.print ("Sent Frames: ") ;
      Serial.println (gSentFrameCount) ;
    }else{
      Serial.println ("Send failure") ;
    }

So looking how const is used here for the bool variable ok, there is seemingly much more to know about const than there is in the Arduino reference.

I started evaluating CAN-master from SANdeep Mistry
There are just 3 examples, very basic - almost no comments in the code makes it hard to understand. So I contined with the next one.

The second library was acan2515-master v2.0.6 (The one installed by Arduino Library Manager)
There are 11 example sketches included. 10 of these use the MCP2515 in loopback mode, i.e. the data you sent goes never onto the CAN bus, but is returned inside the MCP2515. I got one to work after some trouble. I got in contact with Pierre Molinaro, who agreed to include my proposed comments in a next release. These will help others to find the non-obvious link between the error messages and the problems.
The 11th sketch runs only on a Teensy 3.x .
There is also an extensive PDF document that explains a lot.
Conclusion: There is still a lot of very basic code that needs to be written from scratch: There is no example code available that can send a frame out on the CAN bus if you have other hardware than Teensy.
The questions I currently have are:

  • Is there something like an "Arduino advanced reference" that explains the many programming features these advanced skill programmers tend to use?
  • My plan is to give up attempts with these libraries and my next attempt will be to start working with the Seeedstudio library and maybe their CAN hardware. Any other suggestions?

OldFrank:

  • Is there something like an "Arduino advanced reference" that explains the many programming features these advanced skill programmers tend to use?

The Arduino programming language is a superset of C++. So any valid C++ code is valid Arduino language code. Because the Arduino programming language can only be used when writing sketches, Arduino libraries are written either in pure C++, more rarely C, or extremely rarely assembly code. This means you can use any of the excellent C++ references/tutorials/etc. on the Internet to learn advanced Arduino programming concepts. I found this tutorial to be very useful:
https://www.cplusplus.com/doc/tutorial/
There are many others though.

But there is something important to understand: a microcontroller is a different environment for a program than a PC. Most of the information you will find on C++ is not going to be specific to programming microcontrollers. So you will need to filter out some of the information that is only relevant for C++ code running on a computer.

OldFrank:

  • My plan is to give up attempts with these libraries and my next attempt will be to start working with the Seeedstudio library and maybe their CAN hardware. Any other suggestions?

I already dumped everything I know about Arduino CAN libraries (which is very little) in my previous reply. Hopefully the more knowledgeable forum members will be able to provide you with better suggestions than I was able to.

I made progress with my Seeedstudio CAN evaluation
Findings are:
Seeedstudio has got 2 completely different CAN hardware models:

  • An Arduino shield with piggyback connectors that communicates via SPI, 3 HW versions, latest hardware version is 2.0. It can no longer be ordered via Seeed, but RS still has stock and many clones exist.
  • A serial CAN bus module that communicates via serial port to an Arduino with more than one serial port.
    What took me some time to find out:
  • The Arduino shield works with CAN library v1.x.x (latest on Github is v1.3.0), you just need to set the SPI and int pins to the correct values for your board.
  • The serial CAN bus module works with CAN library v2.x.x (latest on Github is 2.2.0) library v2.x.x is not backwards compatible with the Arduino Shield. When using the v2.2.0 library with example code that has been written for the shield, you get compilation errors.
    Early in my project, I put Seeedstudio CAN in the fridge, since most example code published has been written for the "Shield + v1.3.0 library" environment and I had all these compilation errors since I installed the latest version v2.2.0.
    Once you have the correct library installed, examples start compiling without errors and start working.
    In general, I have to conclude that all versions of the Seeedstudio CAN HW SW environment seems to have a lot of well-documented, working examples where one can start from.
    After all this trouble, my kind request would be that anybody posting code that makes use of a CAN library would add a comment specifying which library and which version.

My next challenge would be to set up communication over the CAN bus so that communication with the EPOS4 controller would be established.
For the EPOS4, CANopen is needed. Since even a minimal CANopen implementation seems quite a challenge to write and I find no CANopen libraries for Arduino, I'm stuck again. Closest thing to CANopen I can find on this forum is replaying messages to an CANopen robot -that worked to some extent. There also seems to be open-source code available for CANopen, but I find no sign that this has ever been brought to life on Arduino. Any suggestions?

Thanks so much for sharing your findings @OldFrank. I have added a link to this in my notes about MCP2515 modules and the Arduino MKR CAN Shield.

I very much support your request for the Arduino community to do a better job at documenting library dependencies. Hunting down the right library is often the biggest part of the job when we're trying to help people with code problems here on the forum, and them having a missing or incorrect dependency often ends up being the cause of their problem.

Some feedback after switching from CAN to serial communications

  • Serial communication works nicely between Arduino and EPOS4. I use a Mega 2560R3, serial1 is connected to a MAX3232 level converter with DB9 connector removed and wires to a Molex CLIK-Mate single row 5 poles that plugs into the X10 connector on the EPOS4. There is a lot of documentation on connecting EPOS to CAN bus and EtherCAT and not so much about the RS232 interface, which made me overlook this option when starting the project.

  • It is preferred to use an Arduino with 2 (or more) serial ports: the EPOS4 natively starts up at 115200bps and that is a bit too fast for Softwareserial.

  • The serial protocol used follows a complex set of rules like character stuffing and CRC added at the end.

  • maxon works with 2 serial protocols: v1 and v2. You need v1 for EPOS2 and v2 for EPOS4.

  • a good place to start from is GitHub - Denisg76/EPOS4-Arduino: Send commands to Maxon Epos controller but be extremely careful (edit first) since the demo spins your motor up with very high acceleration and speed. It supports v2 serial and is an example of option b) below. It uses softwareserial and requires that you use EPOS Studio first to configure the EPOS4 serial port for 9600bps. For some uses, 9600bps will be a bottleneck, so 115200 via a hardware port is my preference.

  • You need maxon EPOS studio for debugging your Arduino code and maybe for more.

  • The EPOS4 knows absolutely nothing when started up without a config, by loading the correct parameters you do get a very impressive functionality. You will need to do a great deal of studying on the hardware and firmware guides. It is very important to understand how the EPOS4 behaves as a state machine, what is possible in each state and how it can transition from one state to another.

  • There are 2 high-level approaches to get everything working:
    a) Don't store anything in the EPOS4 and send all motor, axis, encoder, gear and other config parameters from the Arduino on power up. Your setup section will be a long one, but it worth doing since all parameters are kept in one place.
    b) Work with EPOS Studio to load all the fixed parameters in the EPOS4, store these parameters in the EPOS4, then send the very last variable parameters to control the motor movement from the Arduino. (NVR memory in the EPOS4 is not very well documented, some sources state NVR doesn't exist, the firmware guide states that you can use object entry 0x1010 and write "evas" ("save" in reverse order) to it to store the current config)

  • In case you want to use multiple EPOS4's : It would be possible to connect the first EPOS via serial like I did and use this one as a bridge. The NMT service of the first EPOS4 would then transfer your packages to other EPOS4's over the CAN bus. I haven't tried since I currently am working with one EPOS4. Code to use NMT is not part of the Github example code. But the nice thing is that this would answer the original question "how work with the CAN bus", the answer being "use one EPOS4 as a bridge".
    Thanks for all help & I hope this could help somebody some day to see a running motor earlier in the project than I did....

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.