Skip to content

CH340 Driver

Users will need to install the appropriate driver for their computer to recognize the serial-to-UART chip on their board/adapter. Most of the latest operating systems will recognize the CH340C chip on the board and automatically install the required driver.

To manually install the CH340 driver on their computer, users can download it from the WCH website. For more information, check out our How to Install CH340 Drivers Tutorial.

How to Install CH340 Drivers

How to Install CH340 Drivers

Arduino IDE

Tip

For first-time users, who have never programmed before and are looking to use the Arduino IDE, we recommend beginning with the SparkFun Inventor's Kit (SIK), which is designed to help users get started programming with the Arduino IDE.

Most users may already be familiar with the Arduino IDE and its use. However, for those of you who have never heard the name Arduino before, feel free to check out the Arduino website. To get started with using the Arduino IDE, check out our tutorials below:

Install Board Definition

Install the latest ESP32 board definitions in the Arduino IDE.

[![Installing Board Definitions in the Arduino IDE](https://cdn.sparkfun.com/c/500-282/assets/learn_tutorials/1/2/6/5/sparkfun_boards.PNG)](https://learn.sparkfun.com/tutorials/1265)
[**Installing Board Definitions in the Arduino IDE**](https://learn.sparkfun.com/tutorials/1265)

Info

For more instructions, users can follow this tutorial on Installing Additional Cores provided by Arduino. Users will also need the .json file for the Espressif Arduino core:

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

When selecting a board to program in the Arduino IDE, users should select the SparkFun ESP32 Thing Plus C from the Tools drop-down menu (_i.e. Tools > Board > ESP32 Arduino > SparkFun ESP32 Thing Plus C). Alternatively, users can also select the ESP32 Dev Module; however, they may lose some pin assignments.

Select the SparkFun ESP32 Thing Plus C from the Tools drop-down menu in the Arduino IDE.

Arduino IDE 2.x.x - Alternative Method

In the newest version of the Arduino IDE 2.x.x, users can also select their board (green) and port (blue) from the Select Board & Port dropdown menu (yellow).

Selecting the SparkFun ESP32 Thing Plus C and COM5 port from the Select Board & Port drop-down menu in the Arduino IDE (v2.0.3).

SparkFun TMAG5273 Arduino Library

The SparkFun TMAG5273 Arduino Library can be installed from the library manager in the Arduino IDE.

SparkFun TMAG5273 Arduino library in the library manager of the Arduino IDE.

Arduino IDE (v1.x.x)

In the Arduino IDE v1.x.x, the library manager will have the following appearance for the SimpleFOC library:

SparkFun TMAG5273 Arduino library in the library managerof the Arduino IDE (v1.x.x).

This library will be primarily used to interact with the TMAG5273 hall-effect sensor and return the rotation angle of the motor.

SimpleFOC Arduino Library

The Simple Field Oriented Control Library can be installed from the library manager in the Arduino IDE.

SimpleFOC library in the library manager of the Arduino IDE.

Arduino IDE (v1.x.x)

In the Arduino IDE v1.x.x, the library manager will have the following appearance for the SimpleFOC library:

SimpleFOC library in the library manager of the Arduino IDE (v1.x.x).

This library utilizes a motor control scheme called field oriented control (FOC), which can utilize a feedback control loop to drive a motor with a higher power efficiency and precision characteristics, like evenly distributed torque control.

Info

For more details about the library, check out the online documentation.

Supported Hardware

For a detailed and up-to-date list of the hardware supported by this library, check out the library's documentation. The following are excerpts taken from the library's documentation page:

Supported microcontrollers

Choosing the Right Microcontroller

There are three main parameters when choosing the microcontroller for your project:

  1. Processing power (clock speed, architecture, etc.) - this will determine the performance of the FOC algorithm and the maximum speed of your motor.
  2. PWM generation capabilities - this will determine the number of motors you can control and the control modes you can use.
  3. ADC sensing capabilities - this will determine the current sensing options you have for your project.

1. Processing power

When it comes to the processing power, the rule of thumb is: - The higher the clock speed the better. - Aim for the FOC execution time of loopFOC() to be above 1kHz (ideally above 5kHz) depending on the motor and sensor combination you are using.

Info

For more details, please refer to the SimpleFOC Arduino library documentation.

Arduino SimpleFOClibrary has a goal to support as many BLDC and stepper motor drivers as possible. Till this moment there are two kinds of motor drivers supported by this library:

Current Limitations

Choosing the Appropriate Driver

Selecting the right hardware is a balance of motor type, power requirements, and the level of control precision you need.

1. Motor Type

  • BLDC Motors: Requires a BLDC driver. Ensure the current and voltage ratings match your motor's specs.
    • ⚠️ No Drone ESCs Traditional drone ESCs are not suitable for FOC because they typically use a fixed commutation scheme and lack the necessary control interfaces.
  • Stepper Motors:
    • Dedicated Stepper Driver: Best for 2-phase motors within standard current ranges (ex.NEMA17)
    • Hybrid Mode: You can actually use any BLDC driver to run a stepper motor. - See example
    • ⚠️ No Step/Dir Drivers Traditional "EasyDrivers" or A4988s (in step/dir mode) cannot be used for FOC because they do not allow direct phase voltage control.

2. Current Requirements

  • Low Current (< 5A): Integrated driver ICs are cost-effective and easy to use.
    • Examples: L6234, DRV8313, DRV8316.
  • High Current (> 5A): Requires discrete MOSFET-based designs with robust thermal management (heatsinks/fans).
    • Examples: DRV8302, VESC-based hardware.
  • Rule of Thumb: Always select a driver with a current rating at least 20-30% higher than your motor's expected continuous current.

📢 Critical: Read before powering up!

Before running any motor, you must ensure your hardware can handle the stall current. FOC can easily pull more current than a driver can handle if not limited in software.

The Worst-Case Calculation Check your motor's phase resistance ($\(R\)\() and your power supply voltage (\)\(V_{DC}\)\(). The maximum possible current (\)\(I_{max}\)$) is:

\[I_{max} = \frac{V_{DC}}{R}\]

Safety Steps: - Compare: If $\(I_{max}\)$ exceeds your driver's rating, you must limit the voltage in software. - Software Limit: Use driver.voltage_limit and (motor.voltage_limit and/or motor.current_limit) to stay within safe bounds. - see motor docs - Power Supply: If you can, use a current-limited lab bench power supply for your initial tests.

Tip

While the TMC6300 isn't directly listed as part of the supported hardware for the SimpleFOC Arduino library, we have verified that is compatible with the library.

Info

For more details, please refer to the SimpleFOC Arduino library documentation.

Arduino SimpleFOClibrary supports two types of BLDC motors:

  • BLDC motors

    • 3 phase (3 wire):

      Gimbal Motors

      Gimbal motors

      Gimbal motors will work basically with any BLDC motor driver, but since the high-performance drivers have current measurement circuits optimized for high currents you will not have any benefit of using them. Therefore low-power BLDC motor drivers will have comparable performance as the expensive high-power, high-performance drivers for gimbal motors. What is in my opinion very cool! 😃 This was one of the main motivations to start developing SimpleFOCShield.

      Some of the characteristics of Gimbal motors are: - High torque on low velocities - Very smooth operation - Internal resistance >10Ω - Currents up to 5A

      High-performance Motors
  • Stepper motors

    • 2 phase (4 wire)
Current Limitations

Before running any motor, you must ensure your hardware can handle the stall current. FOC can easily pull more current than a driver can handle if not limited in software.

The Worst-Case Calculation Check your motor's phase resistance ($\(R\)\() and your power supply voltage (\)\(V_{DC}\)\(). The maximum possible current (\)\(I_{max}\)$) is:

\[I_{max} = \frac{V_{DC}}{R}\]

Safety Steps: - Compare: If $\(I_{max}\)$ exceeds your driver's rating, you must limit the voltage in software. - Software Limit: Use driver.voltage_limit and (motor.voltage_limit and/or motor.current_limit) to stay within safe bounds. - see motor docs - Power Supply: If you can, use a current-limited lab bench power supply for your initial tests.

Info

For more details, please refer to the SimpleFOC Arduino library documentation.

6PWM Motor Driver

Users will need to utilize the BLDCDriver6PWM class to provide the six PWM signals required for the TMC6300 motor driver.

BLDCDriver6PWM

This class provides an abstraction layer for most of the common BLDC drivers, which require six PWM signals. This method offers more control than a three PWM motor drivers, since each of the 6 half-bridges MOSFETs can be controlled independently.

⚠️ Note: When using the 3PWM BLDC driver with a stepper motor, ensure that the common phase Uo is connected to the driver's C phase pin.

Microcontroller Considerations

Step 1. Hardware setup

To create the interface to the BLDC driver you need to specify the 6 PWM pin numbers for each motor phase and optionally enable pin. ```cpp // BLDCDriver6PWM( int phA_h, int phA_l, int phB_h, int phB_l, int phC_h, int phC_l, int en) // - phA_h, phA_l - A phase pwm pin high/low pair // - phB_h, phB_l - B phase pwm pin high/low pair // - phB_h, phC_l - C phase pwm pin high/low pair // - enable pin - (optional input)

⚠️ 6 PWM configuration is very hardware specific and please make sure to respect certain guidelines in order for it to work properly!

  • Hardware PWM


    ⚠️ Note: When using the 6PWM BLDC driver with a stepper motor, ensure that the common phase Uo is connected to the driver's C phase pin.

    Even if the common phase Uo is physically connected to some other driver output (A or B), please provide it as the C phase pin in the driver constructor. This is important for the correct operation of the stepper motor.

    Consider an example of the driver connected to the MCU pins as follows:

    ```cpp

    define PIN_A_H 9

    define PIN_A_L 10

  • Software PWM


    define PIN_C_H 13

    define PIN_C_L 14

    define ENABLE 8

    If the common phase `Uo` is connected to the driver pin `A`, you should still provide it as the `C` phase pin in the driver constructor:
    ```cpp
    // common phase `Uo` connected to driver pin `A` so it is provided as the `C` phase pin
    BLDCDriver6PWM driver = BLDCDriver6PWM(PIN_C_H, PIN_C_L, PIN_B_H, PIN_B_L, PIN_A_H, PIN_A_L, ENABLE);
    

    If the common phase Uo is connected to the driver pin B, you should provide it as the C phase pin in the driver constructor:

    // common phase `Uo` connected to driver pin `B` so it is provided as the `C` phase pin
    BLDCDriver6PWM driver = BLDCDriver6PWM(PIN_A_H, PIN_A_L, PIN_C_H, PIN_C_L, PIN_B_H, PIN_B_L, ENABLE);
    

    Or if the common phase Uo is connected to the driver pin C, you should provide it as the C phase pin in the driver constructor:

    // common phase `Uo` connected to driver pin `C` so it is provided as the `C` phase pin
    BLDCDriver6PWM driver = BLDCDriver6PWM(PIN_A_H, PIN_A_L, PIN_B_H, PIN_B_L, PIN_C_H, PIN_C_L, ENABLE);
    

Arduino UNO support

Info

For more details about the BLDCDriver6PWM class, check out the online documentation.

BLDC Motor

All BLDC motors are handled with the BLDCMotor class.

BLDCMotor

This class implements the BLDC FOC algorithm, motion control loops, and monitoring.

Step 1. Creating the instance of the BLDC motor

To instantiate the BLDC motor we need to create an instance of the BLDCMotor class and provide it the number of pole pairs of the motor. ```cpp // BLDCMotor(int pp, (optional R, KV, Lq, Ld)) // - pp - pole pair number // - R - phase resistance value [Ohm] - optional // - KV - motor KV rating [rpm/V] - optional

Motor Considerations

While, the datasheet for our gimbal motor, indicates that there are 8 pole pairs, we have found that the motor operates more smoothly if the BLDCMotor class is instantiated with 7 pole pairs instead.

cp BLDCMotor motor = BLDCMotor(7);

Info

For more details about the BLDCMotor class, check out the online documentation.

Position Sensor

In order to incorporate the TMAG5273 hall-effect sensor into the FOC algorithm, users will need to utilize the GenericSensor class.

GenericSensor

This class allows users to link a custom position sensor (not already implemented in the SimpleFOC library) by incorporating a few functions into their sketch.

  1. Implement two functions; one to initialize the TMAG5273 and another to read and return the sensor's current position.

    return ...; } ```

    additionally you can optionally implement a function that initialises your sensor

    A quick guide to implement your own sensor class (Advanced)

    Step 1. Implement the function reading your sensor

    Basically all that you need to do in your arduino code is implement a function that reads your sensor and returns an angle in radians between 0 and 2π: ```cpp float readMySensorCallback(){

  2. Instantiate the GenericSensor class and initialize the class by providing it pointers to the two functions.

    } ```

    Step 2. Instantiate GenericSensor class

    To initialize the sensor class you need to provide it the pointer to your function reading the sensor, and optionally the pointer to the function that initialises your sensor. ```cpp

  3. There are two ways to use sensors implemented within the SimpleFOC library:

    • As standalone position sensor
      • In this configuration users would simply read the sensor's position, independently from incorporating the readings into the FOC algorithm.
    • Incorporate it as the motor position sensor for FOC algorithm

      1. Initialize the sensor in the setup() loop:

        Here is a quick example:
        ```cpp
        #include <SimpleFOC.h>
        
        float readMySensorCallback(){
         // read my sensor
         // return the angle value in radians in between 0 and 2PI
         return ...;
        }
        
      2. Link the sensor in the setup() loop:

        float readMySensorCallback(){
         // read my sensor
         // return the angle value in radians in between 0 and 2PI
         return ...;
        }
        
        void initMySensorCallback(){
          // do the init
        }
        

Info

For more instructions on incorporating the GenericSensor class, please refer to the SimpleFOC documentation.

In-line Current Sensing

In order to incorporate the current sensing into the FOC algorithm, users will need to utilize the InlineCurrentSense class.

InlineCurrentSense

This class allows users to link a custom position sensor (not already implemented in the SimpleFOC library) by incorporating a few functions into their sketch.

  1. Instantiate the InlineCurrentSense class and initialize the class by providing the hardware configuration.

    SAMD21 | ✔️
    SAMD51 | ✔️
    Teensy | ✔️ Raspberry Pi Pico | ✔️ Portenta H7 | ✔️ Renesas (UNO R4) | ❌ (TBD) Arduino Nano Matter(📢NEW) | ✔️

  2. Incorporate the current sensor into the FOC algorithm:

    1. Initialize the sensor in the setup() loop:

      InlineCurrentSense current_sense = InlineCurrentSense(shunt_resistor, gain, A0, A1, _NC); // when measuring A and B phase currents and not measuring C // or InlineCurrentSense current_sense = InlineCurrentSense(shunt_resistor, gain, A0, A1); // when measuring A and B phase currents and not measuring C ```

    2. Link the sensor to the motor driver in the setup() loop:

      // - phA - A phase adc pin // - phB - B phase adc pin InlineCurrentSense current_sense = InlineCurrentSense(66.0, A0, A1); ```

    3. Link the sensor to the motor in the setup() loop:

      ```cpp

    current_sense.gain_c = 1.0 / shunt_resistor / gain;

    For example, Arduino <span class="simple">Simple<span class="foc">FOC</span>Shield</span> v2 has the phase B of the current sensing inverted. So in its case you can specify:
    ```cpp
    // inverse current sensing gain on phase b
    current_sense.gain_b *= -1;
    

    // default values of per phase gains
    current_sense.gain_a = 1.0 / shunt_resistor / gain;
    current_sense.gain_b = 1.0 / shunt_resistor / gain;
    

    For example, to invert the phase B current measurement you can easily change it gain to:

    // inverse current sensing gain on phase b
    current_sense.gain_b *= -1;
    

Info

For instructions on incorporating the InlineCurrentSense class, please refer to the SimpleFOC documentation.