Brushless Actuator (Arduino-Compatible)

Ardunio-Compatible M0/Zero/SAMD21 running Actuator FOC OS with FET Driver, MOSFETs, Absolute Magnetic Encoder, USB and RS485 comms. ~$US50

Public Chat
Similar projects worth following
Ardunio-Compatible M0/Zero/SAMD21 (32bit) running Actuator Operating System paired with Brushless FET Driver, MOSFETs, Absolute Magnetic Encoder, EEPROM, Switching voltage regulator, temperature, USB and RS485. 30V @ 30A ~$US50

Ardunio M0/Zero/SAMD21 running Actuator Operating System paired with Brushless FET Driver, MOSFETs, Absolute Magnetic Encoder, EEPROM, dual voltage regulators, temperature, USB and RS485. 30V @ 30A ~$US50


  • Brushless Motor Robotic Joints (with SEA)
  • Brushless Motor CNC axis controllers (closed loop)
  • Electric Skateboards motors

46mm square and 52mm round

Ardunio Actuator Operating System

  • Standard Ardunio Boot code (Reset x2 to enable)
  • Foreground 10kHz motor control task update rate
    • Sinusoidal or Field Oriented Controller (FOC)
    • SPI with DMA operation for on board Absolute Magnetic Encoder (motor position)
      • DMA is slower, may just use registers
    • Optional Hall effect (motor position)
    • SPI with DMA operation for external Absolute Magnetic Encoder (1 or 2 daisy chain)
    • 6 phase centre aligned PWM motor control (registers/no libraries)
    • 6/7x ADC free running Sequential operation (no delay)
      • 3 Phase Motor Current Measurement
      • Mosfet Temperature
      • Battery Voltage
      • Motor Temp
      • potentiometer joint position
    • PID joint controller
  • low level interrupt foreground tasks
    • RS485/USB/UART communications
      • RS485 UART with IRQ packet receive and transmit
    • optional Step/Direction
  • Background Tasks
    • OLED I2C (standard Arduino Libraries)
    • Mosfet Driver configuration
    • EEPROM (standard Arduino Libraries)
    • User Functions

2- 8 Cell LiPo

Center positioned Absolute Magnetic Encoder AS5047/AS5147/AS5048 or MA730 with Alignment holes

3V3 Switching regulator from either LiPo or USB

6x 3mOhms 40V N-channel MOSFETS (NVTFS5C453NL) 3x3mm WDFN-8 

3x 1mOhms Sense Resistors with Kelvin Connections

3 Current Shunt Amplifiers in DRV8305

MOSFET Temperature sensor

External connections for 

  • USB programming, configuration and control
  • Connectors for RS485 for daisy chain operation
  • Header for UART
  • Connector for external Temp Sensor
  • Qwiic I2C (OLED display)
  • Connector for External Absolute Magnetic Encoders (SPI) in Single or daisy chain configuration or  Hall effect sensors or potentiometer 
  • Only one spare Digital IO for Servo,  Fan or Limit Switch

Population Options

  • External 24MHz Oscillator
  • Extra Power supply Caps
  • Remove RS485 and use as second TTL UART
  • MOSFET Heatsink and fan


ino - 33.67 kB - 08/21/2019 at 16:35


x-zip-compressed - 3.32 MB - 04/28/2019 at 15:39


Adobe Portable Document Format - 1.01 MB - 04/28/2019 at 15:39


  • 5 Boards with Assembly are on order at JLC

    Paul Gould06/14/2020 at 16:19 0 comments

    Size 50mm square and 58mm round

    On board absolute magnetic encoder is either MA730, MA702, AS5147 or AS5047 There are others in this range.

    Connectors clockwise from the top

    • BLDC motor connectors & Power In/Out
    • External Motor Temp
    • qwiic
    • USB
    • Encoder SPI
    • Fan or Servo CTRL
    • RS485 in/out
    • RS485 out/in

    The connectors are multi footprint JST. Through hole straight / right angle, SMT straight / right angle

    Pitch can be either 1, 1.27, 1.5, 2 or 2.54mm

    Connectors on the back (from the bottom)

    • UART TTL
    • ISP to load the boot code
    • External Capacitor

  • Redesigned for JLC PCB SMT assembly

    Paul Gould01/03/2020 at 13:14 2 comments

    JLC now do cheap PCB manufacture and SMT Assembly.

    I have changed the components to suit what is available at JLC


    DRV8305NPHPR (MOSFET Driver)

          with 3 Phase Current Sensor

    NVTFS5C453NL (N-MOSFETs 3x3mm 3mOhms 40V)

    MA730GQ-Z (Absolute Magnetic Encoder 14-bit SPI) or AS5xxx

    MP2359DJ-LF-Z (3V3 1A DC-DC Converter)

    SP3485EN-L/TR (RS485 comms)

    24LC01BT-I/OT (EEPROM for ID and parameter storage)

    STLM20W87F (Temperature Sensor for MOSFETs)

    Voltage monitor

    External Motor Temperature Connector

    Qwiic connector (I2C) for OLED display

    SPI Remote Encoder connector

    UART Connector

    Servo connector

    USB programming connector

    SWD programming connector (for putting in the Arduino Bootloader

    Reset Button (for getting it into the bootloader)

  • The motor is turning

    Paul Gould08/21/2019 at 16:42 0 comments
  • Actuator Operating System - Base Code

    Paul Gould08/03/2019 at 16:21 0 comments

    Arduino Code for SAMD21 Dev Breakout by Sparkfun

    Updated 2019-Aug-05

    Fixed DRV SPI CS; Added Test Points T0 & T1; Disabled Serial1

    Now on GIT

    Don't use the code below, it will always be out of date

    /* External Encoder SPI
     * Motor Driver Control/Onboard Encoder SPI
     * 3 Phase timer with deadband TCC0
     * Timer IRQ 10KHz Timer 5
     * I2C Diaplay
     * RS485 with time-out Timer 4(start of packet)
     * ADC sequential, free-running (6) and DMA and IRQ
     * SerialUSB is available
     * Serial1 is available but is currently used as test points T0 and T1
     * Joint Control -> PID -> Motor Control (FOC) -> Three Phase Output
    #include <SPI.h>
    #include "wiring_private.h" // pinPeripheral() function
    //  I2c OLED  ///////////////////////////////////////////////////////////
    #include "ssd1306.h" // library by Alexey Dynda
    char display_str[] = "1234567890";
    //  On-Board Encoder + Motor Driver and External Encoder /////////////////
    #define ENC_SPI_MISO 6 //29 D6 PA20 ser 5:2 SER
    #define ENC_SPI_SCK 7 // 30 D7 PA21 ser5:3 SER
    #define ENC_SPI_MOSI A5 //47 A5 PB02 ser5:0 ALT
    #define ENC_CS A0 //PA02
    #define ENC_CS_PORT_PIN PORT_PA02 // Fast Pin Switching REG_PORT_OUTSET0
    #define DRV_SPI_MISO MISO // 21 PA12 SER4:0 ALT
    #define DRV_SPI_SCK SCK // 20 PB11 SER4:3 ALT
    #define DRV_SPI_MOSI MOSI //19 PB10 SER4:2 ALT
    #define DRV_CS 30 // PB22
    #define DRV_CS_PORT_PIN PORT_PB22 // Fast Pin Switching USE REG_PORT_OUTSET1
    uint16_t enc_data, drv_data; 
    //  Three Phase Center Aligned PWM with Dead-band //////////////////
    #define UH 3   //W1 14 PA09
    #define UL 5   //W5 24 PA15
    #define VH 10  //W2 27 PA18
    #define VL 11  //W6 25 PA16
    #define WH 12  //W3 28 PA19 
    #define WL 13  //W7 26 PA17
    //  RS485 Serial with Direction CTRL /////////////////////////////
    #define RS485_TX_SIZE 16
    #define RS485_RX_SIZE 32
    char RS485_txbuf[RS485_TX_SIZE];
    char RS485_rxbuf[RS485_RX_SIZE];
    #define RS485_RX_MAX 4
    #define RS485_TX_PACKET_SIZE 4
    #define UART_ERROR 0x80
    #define TX_COMPLETE 0x02
    #define RX_CHAR 0x04
    char RS485_tx_to_send=0;
    char RS485_tx_left=0;
    char RS485_rx_cnt=0;
    uint8_t i=0;
    #define RS485_RX 38 //PA13 ser2:1 ALT
    #define RS485_TX 4 //PA08 ser2:0 ALT
    #define RS485_DIR 2
    Uart Serial2 (&sercom2, RS485_RX, RS485_TX, SERCOM_RX_PAD_1, UART_TX_PAD_0);
    //  TC4 serial time-out //////////////////////////////////////////
    #define TC4_INTERRUPT 0 //Disable Interrupt 
    //  ADC DMA sequential free running (6) with Interrupts /////////////////
    #define ADCPIN1 A1
    #define ADC_Number 6
    #define HWORDS 7
    uint16_t adcbuf[HWORDS];     
    typedef struct {
        uint16_t btctrl;
        uint16_t btcnt;
        uint32_t srcaddr;
        uint32_t dstaddr;
        uint32_t descaddr;
    } dmacdescriptor ;
    volatile dmacdescriptor wrb[12] __attribute__ ((aligned (16)));
    dmacdescriptor descriptor_section[12] __attribute__ ((aligned (16)));
    dmacdescriptor descriptor __attribute__ ((aligned (16)));
    DmacDescriptor *desc; // DMA descriptor address (so we can change contents)
    static uint32_t ADC_DMA_chnl = 3;  // DMA channel
    /////          BLDC       //////////////////////////////////////////////////////////////////////////////////////
    int count;
    #define SIN_ARRAY_SIZE_BITS 12
    #define MOTOR_POLE_PAIRS    7
    #define FULL_ANGLE 360.0
    #define DEG_RAD (3.1415/180.0)
    #define FULL_PWM_BITS 10
    #define FULL_PWM (1<<FULL_PWM_BITS)
    #define POS_ONE 0
    #define MAGNET_OFFSET -100 //0
    #define PHASE_OFFSET 120
    #define MAX_PWM 250
    /* Store in EEPROM
    #define CONFIG_ARRAY_SIZE 32
    int32 config_array[CONFIG_ARRAY_SIZE];
    #define ID_OS           0
    #define MAG_OFFSET_OS   1
    #define PHASE_OFFSET_OS 2
    #define TEMP_MAX_OS     3
    #define NOMINAL_OS      4
    #define NINETY_OS       5
    int current_config = 0;
    Read more »

  • Software tasks

    Paul Gould04/30/2019 at 16:44 0 comments

    Low Level SAMD21 / Arduino functions with no libraries*

    1. Main OS timer - 100us (10KHz) IRQ                                                 (done)
    2. 3-Phase Motor Controller PWM with deadband                            (done)
      • (6-centre aligned pwms)                                                           (done)
    3. ADC- 6 channels sequential, semi-free-running DMA with IRQ     (done)
      • 3x Current Sensor
      • MOSFET Temperature Sensor
      • Battery Voltage
      • 1 Auxillary Analog Inputs
    4. Dual (same time) SPI (blocking and IRQ)                                             (done
    5. RS485 UART with IRQ (TX & RX)                                                        (done)
      1. with direction CTRL                                                                       (done)
      2. with time-out and packet start detect                                           (done)
    6. UART with DMA                                                                                  (attempted fail)
    7. CPU's Internal EEPROM Emulation (Flash storage)                            (attempted & fail)
    8. External I2C EEPROM support (maybe Libraries)                             (not started, have eeprom)
    9. I2C OLED support (with Libraries)                                                     (done)
    10. SerialUSB with above                                                                         (done)
    11. Serial1 with above                                                                              (done)
    12. Making all the Low level features work together                         (done, done and done)

    High Level Functions

    1. Field Orientated Control (FOC) & Motor Commutation                    (done)
    2. PID Joint Control                                                                                 (done, but just P)
    3. RS485 Packet Structure                                 ...
    Read more »

View all 5 project logs

Enjoy this project?



VALL-E2 wrote 05/26/2020 at 11:03 point

Hello, I have some problem with compilation of Arduino Code for SAMD21 Dev Breakout by Sparkfun. I try to compile BLDC_2_REV1.ino file with Arduino IDE.

And I have recived error

Arduino: 1.8.12 (Windows 10), Плата:"SparkFun SAMD21 Dev Breakout"

core\variant.cpp.o: In function `__static_initialization_and_destruction_0':

C:\Users\Gl.Ingener\AppData\Local\Arduino15\packages\SparkFun\hardware\samd\1.7.4\variants\SparkFun_SAMD21_Dev/variant.cpp:218: multiple definition of `SERCOM5_Handler'

sketch\BLDC_2_REV1.ino.cpp.o:E:\Мои документы\brushless\FOC-Arduino-Brushless-master\BLDC_2_REV1/BLDC_2_REV1.ino:360: first defined here

c:/users/gl.ingener/appdata/local/arduino15/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/bin/ld.exe: warning: changing start of section .bss by 12 bytes

collect2.exe: error: ld returned 1 exit status

exit status 1

What is wrong? How to correct it?

  Are you sure? yes | no

Paul Gould wrote 05/26/2020 at 13:23 point

I modified the variants file. Read line 38 of the ino file says

// Remove //Uart Serial and  void SERCOM5_Handler()

// From Arduino15\packages\SparkFun\hardware\samd\1.5.4\variants\SparkFun_SAMD21_Dev\varients.cpp

  Are you sure? yes | no

VALL-E2 wrote 05/27/2020 at 03:33 point

Thank You very much. I was inattentive.

  Are you sure? yes | no

marvinhotz wrote 05/08/2020 at 08:44 point

Nice Project. Working on something similar.

Is there a way that I can order that PCB?

I uploadet the files to JLCPCB but that didn't work somehow.

(At least there was no preview or something else)

Greetings from Switzerland

  Are you sure? yes | no

Paul Gould wrote 06/14/2020 at 15:55 point

I have just ordered the board from JLC. I will release the PCB files after I get the prototypes working. 

  Are you sure? yes | no

RAW.Exposed wrote 02/05/2020 at 08:18 point

Hey @Paul Gould I am also looking at a similar use case as Simon. Though I am looking to build a 3 axis motion control camera head. I currently have a controller and software that outputs step and direction, normally to servos. My ideal use case is a BLDC motor connected to a harmonic drive, cycloidal reducer or just a pulley reduction to increase torque. Would your controller be suitable for this use case? High position accuracy is very important to my project. Any advice or input would be greatly appreciated. 

Also, when will your controller be available for purchase? 

  Are you sure? yes | no

Paul Gould wrote 06/14/2020 at 15:50 point

I have just order the boards and assembly from JLC, they are due back in 1-2 weeks. The controller can has onboard magnetic encoder (either MA730, MA702 or AS5047) and connection to external SPI magnetic encoders. The encoders can be used for motor commutation or joint position. Usually one of each. They have USB, RS232, I2C or TTL UART for the comms. It could use step and dir but it would be better to just send the target position/speed over the comms. 

How much accuracy do you need? AS5047 is 14bit per 360deg.

I do intend on selling these boards after they have been prototype and tested. Most likely in 2 months. 

  Are you sure? yes | no

Simon Merrett wrote 01/19/2020 at 22:15 point

Hi @Paul Gould I don't know how I missed this project - it looks great. I'd be very interested in using this as a controller to replace stepper motors on a very lightweight XY cartesian motion platform with BLDCs. The aim would be maximise travel speed as the X and Y motion do not need to be coordinated, as long as they both travel the correct total distance. 

Could you please comment on whether you think this project would be a good starting point for that application and what changes would be worth considering? 

  Are you sure? yes | no

Paul Gould wrote 01/20/2020 at 15:23 point

That could be possible. What motor did you have in mind? I foresee it working like a Clearpath servo. 

  Are you sure? yes | no

Simon Merrett wrote 01/20/2020 at 16:01 point

Just like a clearpath but much less sophisticated! As far as motors go, I'd be prepared to consider all sorts but I think they could be relatively small, say something like a commonly available 5010 outrunner, as they're available at low kV, say 360kV. The motor would have to be somewhat matched to the masses and accelerations of the motion platform but I'd plan to start small. Thinking more PNP or plotter than 3D printer or router.

  Are you sure? yes | no

Paul Gould wrote 01/20/2020 at 17:22 point

For a PNP, high speed acceleration is needed, it may be better to go with a longer/thinner motor, possibly an in-runner

  Are you sure? yes | no

Simon Merrett wrote 01/20/2020 at 22:22 point

I'm open to testing a range of motor options. I just need to get a controller rolled (or bodged, more likely to start with). 

  Are you sure? yes | no

noccioli.alessandro wrote 12/03/2019 at 07:03 point

Very cool and detailed project.
Could you use 3 hall sensor at 120°  to get the position of the motor instead of the AS5147? What is the benefit of using that chip instead of the 3 small hall sensor in the motor?

  Are you sure? yes | no

Paul Gould wrote 01/20/2020 at 15:15 point

Three Hall effect sensors will give you 6 steps per electrical rotation. The AS5147 will give 16,384/(pole pairs)‬  (about 1000 steps) per  electrical rotation. This means that you can use FOC or Sinusoidal control to give very precise speed and position at very, very low speeds. It is also easier to add a diametric magnet to the motor's shaft than to add hall sensors. It also means that you can use cheap Chinese large diameter drone out-runner motors.

  Are you sure? yes | no

Javier Laserna wrote 10/02/2019 at 22:44 point

I’m building it but I have a doubt about what type of package is the SAMD21. In the pdf I see ATSAMD21G18A-AU but for solder on the PCB it doesn’t fit. Maybe it would be ATSAMD21G18A-MUT?

  Are you sure? yes | no

Paul Gould wrote 10/03/2019 at 14:57 point

I'm still changing the design of the PCB, the SAMD21 has a lot of pin mapping limitations. Getting all the SERCOM and timer pins correct is a nightmare. I haven't ordered any parts or PCBs yet, so I'm yet to check the BOM.

  Are you sure? yes | no

Andrey V wrote 09/03/2019 at 06:55 point

It's interesting for DIY slow speed applications. But you will have some problems with high RPM motors. Modern FOC devices have slightly different design and able to work with up to 100 000RPM motors. Pay attention on TMC6130 IC it costs only around 3$, but module with it costs 150+$. Just the idea) 

  Are you sure? yes | no

Paul Gould wrote 09/03/2019 at 13:30 point

This is definitely not a "high end" controller but I'm hoping it will be an ok substitute. The motors I plan to use will max out at 5000RPM and I really only need good control at ~0RPM / holding torque. I've search for a lot of FET drivers and I think that the DRV8323RS is the best "cost per features" there is. 

  Are you sure? yes | no

bb-bit wrote 09/02/2019 at 05:03 point


  Are you sure? yes | no

Paul Gould wrote 08/30/2019 at 13:18 point

You maybe able to use those modules to make closed loop brushless controller, I'm just not sure how. 

You may not have complete control over the FETs (only HALL and Speed/dir inputs) and I guess they would get hot at 500W. The Ron might be high.

STM uC doesn't run the Arduino system but they should be able to run the ODRIVE code.

I use an absolute magnetic encoder to find the motor position and get FOC control.

  Are you sure? yes | no

florianrutsch wrote 06/16/2019 at 13:00 point

Really cool, promising project! Hope it all works out, cheers!!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates