A new CAN communication standard for SimpleFOC - CANCommander

Hi guys,

It has recently come to my attention that there have been many attempts in making a SimpleFOC communication layer with CAN.
There have been a lot of people who implemented in on their own with different levels of complexity and abstraction. See this topic for more info.

In the effort to unify and channel the community work towards a common SimpleFOC CAN standard I’ve made an attempt to create a goto CAN implementation that we can build on top of and extend it in future steps.

The new can code consists in 3 main parts:

  • SimpleCANio: - see here
    • A low-level cross-platform CAN implementation
    • Implementing a standardized HardwareCAN interfact (stm32, esp32, teensy for now)
    • Also has a GenericCAN: a quick and dirty way to implement CAN similar to GenericSensor and GenericCurrentSense classes
    • See examples here
  • CANCommander - see here
  • pysimplefoc: - see here
    • A python package, developed by @runger, that implements several SimpleFOC communication standards (commander, telemetry,… )
    • Now it allows for CAN communication as well
    • It requires an USB dongle supporting CANable or Socketcan (basically has to be supported by python-can package)
    • See example here

Main features

  • Supported architecutes: STM32, ESP32, Teensy + GenericCAN interface for quick implementation of new support
  • A standardized set of register input/outputs based on RegisterIO
  • A python package allowing for simple interfacing (requires python-can supported usb dongle)

Example code

The arduino code:

CANio can(rxPin, txPin); 
CANCommander commander(can, 0x12); // address 0x12

void setup(){
 ...
 commander.init();
 commander.addMotor(&motor);
 ...
}
void loop(){
 ...
 commander.run();
}

The python code:

import simplefoc.can as can
from simplefoc import MotionControlType, TorqueControlType

# Connect to CAN bus
motors = can.can_bus(
    interface='can0',           # CAN interface name
    target_address=0x12        # SimpleFOC driver's address
)
motors.connect()

# Get motor and control it
motor = motors.motor(0)
motor.set_mode(MotionControlType.torque, TorqueControlType.voltage)
motor.enable()
motor.set_target(2.0)

# Read motor state
velocity = motor.get_velocity()
angle = motor.get_angle()

Future steps

I’m really happy with the results, especially with the python package, as it makes the job of interfacing the boards to the PC much easier.

So far the support is not yet merged in the main repos, I hope that we will be able to do it soon. If some people are interested I’d be happy to hear your feedback. There are quite a few people that are made much more advanced CAN and CAN FD support (especially with regards to non-blocking and thread-safe operation). But consider this as a first step and the one that is a condensation of the community efforts so far. And one that will evolve in the future. :smiley:

4 Likes