Brushless Actuator (Arduino-Compatible)

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

Public Chat
Similar projects worth following
Ardunio-Compatible M0/Zero/SAMD21 (32bit) with Brushless FET Driver, MOSFETs, Absolute Magnetic Encoder, EEPROM, Switch mode 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

50mm square and 58mm 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)
    • 3/6 phase centre aligned PWM motor control (registers/no libraries)
    • 6/7x ADC free running Sequential operation with DMA(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 (6-34V)

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

3V3 Switching regulator from either LiPo or USB (Diode switch over)

6x 2mOhms 40V N-channel MOSFETS (BSC022N04LSATMA1) Power SO-8mm 

3x 3mOhms Sense Resistors

3 Current Shunt Amplifiers in DRV8305N

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 (maybe removed in next revision)
  • Extra Power supply Caps
  • Remove RS485 and use as second TTL UART (maybe removed in next revision)
  • 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


  • Arcade Claw Machine - Room Sized

    Paul Gould08/07/2020 at 10:03 0 comments

    THe Brushless Actuators and GL5010 motors are used in Arcade Claw Machine - Room Sized project in the upper four corners of the room. Linked by RS485 communications. Limited to 2% Power.

  • Software for hardware testing

    Paul Gould07/05/2020 at 16:05 2 comments

    Bootloader programmed using the SEGGER J-FLASH with the BIN file from Sparkfun SAMD21 Dev board bootloader. I will have to create my own custom one in the future. This will require using ATMEL studio which I do not like to use.

    After bootloader is programmed it can be seen as a USB port in the Arduino IDE. Set the board type to Sparkfun SAMD21 Dev and select the detected USB. The variants file has to be modified to disable the SER5 handler.

    Test software runs the following

    • Qwiic I2C OLED display
    • Reset Button and RX LED
    • and write
    • External SPI magnetic encoder
    • On-board SPI magnetic encoder
    • EEPROM I2C Read and write
    • Free running 6x Sequential ADC via DMA
    • DRV8305 
      • SPI Read and write registers
      • Fault and enable
      • 3x Current Monitor into ADC
      • PWM x3 Mode (not x6 Mode yet)
    • RS485 TX and direction (RX not tested yet)
    • On-board MOSFET Temperature sensor into ADC
    • Battery voltage Monitor into ADC

    Features left to test

    • Spare UART TX and RX
    • RS485 RX
    • FAN/Servo PWM output
    • External analogue temperature input

    Full operation test

    On-board magnetic encoder reads the diametric magnet connected to the motor shaft. Motor position is controlled from the USB using Saddle sinusoidal control. Vital information displayed on the OLED display.

  • Assembled PCBs

    Paul Gould07/05/2020 at 15:29 0 comments

    Ordered the boards with assembly 18th June 2020 from JLCPCB in China and they arrived in Perth Australia 29th June 2020. There is a limited range of components available, so I had to order the remaining parts, mainly the connectors and sensors, from LSCS and Mouser.

    I made a mistake with the polarizing of the diodes because I didn't read the full JLC assembly notes.

    I made a mistake with the choice of the SM-regulator and dual power diode. Firstly the reg requires 6V to run the 3.3V supply for the SAMD21. This is fine when running of the external power supply but when operating for the USB this is not good. I reworked the boards with LMR14206 which operates from 4.5V. Which them leads onto the dual power diode. The one I chose has a voltage drop of 1V @ 30mA which is also not good from the USB supply. So a BAT721C can be used as the replacement. It has 0.4V drop at 100mA.

    The second mistake was using the DRV8305N which requires a VREG input voltage of 3.3V. I based the design on the DRV83053 which has an internal 3.3V regulator. The '3' cost twice as much at JLC than the 'N'. I just made a link between to the VREG pin from the closest 3.3V pad.

    The third mistake was with the pin multiplexing limitation of the RS485 TX and RX pins. These had to be swapped over. This required lifting two pins on the RS485 transceiver chip and adding some wire links.

    The fourth mistake was the spacing of the though holes of the fan/servo connector. It was designed for various pitch SMT and TH connectors but a 2.54mm 3pin servo connector wouldn't fit. 

  • 5 Boards with Assembly are on order at JLC

    Paul Gould06/14/2020 at 16:19 5 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 4 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 8 project logs

Enjoy this project?



maxime.lemonnier wrote 10/20/2020 at 02:51 point

Hi Paul, I've been following this project a few months ago. I love the design and possibilities. For the first time in a while I may have enough free time to try it. Unfortunately I don't have a lot of time to order stuff before I leave for a remote place where I'll have internet, but limited delivery roads. In a perfect world you'd point me to an up to date order list/bon to build 4 of these. The project evolved, mistakes were fixed, I have a hard time finding an up to date order list.  I have around 14 days. Probably too short. Can you help? I have an interesting skillset, software (low, high level), electronics, maths, AI, simulation. Would love to contribute.

  Are you sure? yes | no

Mattias wrote 08/14/2020 at 23:20 point


For the 8305 board, do you need to set the internal register over SPI to enable 3x PWM mode or can you use 3x PWM out of the box without any configuration (send the pwm signals to the INHx pins)?

Thanks :)

  Are you sure? yes | no

Paul Gould wrote 08/16/2020 at 08:57 point

For 3x PWM, you must set the SPI Register 7 to 0x296

  Are you sure? yes | no

Mattias wrote 08/16/2020 at 20:21 point

Ah perfect, does that register have to be set every time at start up (to specify the PWM mode) in the drv or does the driver save the state internally?

  Are you sure? yes | no

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

Calum wrote 08/10/2020 at 12:35 point

@Simon Merrett Have you had a look at Klipper? Klipper is a 3D printer firmware that runs on a raspberry pi, and issues commands to standard 32-bit 3D printing microcontroller boards. Many boards are supported, including the SAMD21 controller. I'm wondering if this board could be hooked up to that interface.

  Are you sure? yes | no

Simon Merrett wrote 08/10/2020 at 12:42 point

@Calum no I haven't - not even populated my board yet! So many projects, so many diversions. Thanks for the steer though. 

  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