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
HardwareCANinterfact (stm32, esp32, teensy for now) - Also has a
GenericCAN: a quick and dirty way to implement CAN similar toGenericSensorandGenericCurrentSenseclasses - See examples here
CANCommander- see here- In the SimpleFOC-drivers repo
- Using the
RegisterIOregisters developed by @runger (a set of SimpleFOC registers) - see here - Similar ID structure as the
CANCommanderby @Jason_Kirsons and @Matt303 - See examples 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-canpackage) - 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-cansupported 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. ![]()