SMC_L298N PID MOTOR CONTROLLER OVERVIEW
The SMC_L298N PID MOTOR CONTROLLER is an easy-to-use PID motor driver module/system based on the popular L298N driver IC designed for controlling the angular velocities of geared DC motors with quadrature encoders via velocity commands rather than the traditional PWM commands. It has a GUI application that allows one to easily set up motor PID parameters as well as libraries for easy interfacing with ROS2-based and Arduino-based projects (as well as Python and Cpp projects).
It can easily be used by hobbyists, students, learners, researchers, etc.
Before one can begin sending angular velocity commands to the DC motors, some parameter setup (PID gains, encoder PPR, etc.) needs to be done. To fully setup the smc_l298n_pid_driver module, follow the steps below:
- Geared DC Motor (with quadrature encoder) connection as well as Power connection.
- Downloading and running the Setup Application
- Motor output (M+ and M-) pins and encoder pulse (A and B) pins connection check with Setup Application
- Encoder Pulse Per Revolution Parameter Setup
- Motor Maximum Commandable Angular Velocity Check
- PID Gains Setup Empirically
- Choosing a default motor positive direction
- I2C Address Setup.
HERE IS THE LINK TO THE FULL SETUP VIDEO PLAYLIST ON YOUTUBE: [LINK TO PLAYLIST]
1. MOTOR CONNECTION AND POWER CONNECTION TO THE DRIVER MODULE
First things first, you need to ensure the driver module is properly powered and the encoder(s) is(are) properly powered also.
Then connect the M+ and M- motor output and the A and B pulse pins. You don’t necessarily need to get these pin connections right at first as there’s a way to check the correct connection (which we will do later in the steps below).
Also, connect the FTDI module to the driver module and the PC.
NOTE: it is compulsory to get the power connections right
2. DOWNLOADING AND RUNNING THE SMC_L298N SETUP APPLICATION
Ensure you have connected the Geared DC motor and its encoder to the smc_l298n_driver module and properly powered it up (based on the above instruction). Also, connect the driver module to the PC via the FTDI module for serial communication.
You can easily download and run the GUI application via a Python virtual environment following the instructions for its GitHub repo here: [link to the GitHub repo].
NOTE: It has only been tested on Windows 10, 11, and Ubuntu 22.04 LTS. It should work on other OS as long as you have python3 installed.
Once you run the application and connect to the smc_l298n_driver module, you will see a page that allows you to choose the USB port to connect to the driver module, select the right port, and click connect. Wait for about 5 seconds and you should have a successful connect dialog appear, click ok to continue.
On the left-hand, you should now see a menu with different setup processes. If you’re setting up for the first time, you can reset all parameters by selecting the reset menu to start the setup process with a clean slate.
3. CONFIRM PROPER MOTOR AND ENCODER PIN CONNECTION
On the module, your motor and encoder would be connected to one of the MOTOR A or MOTOR B ports.
On the Application menu, you should see the MOTOR A ENC menu option, select it (NOTE: if yours is connected to that of MOTOR B port, select MOTOR B ENC).
You should now see options for setting Encoder Pulse Per Revolution (PPR), Motor Default Direction for positive PWM or velocity commands (DIR), Test Control PWM ( TEST_PWM), and Test Duration (DURATION).
You will also see the Motor’s angular position and angular velocity readings with two buttons – one to send a PWM command to the motor and the other to reset the hand of the virtual motor.
Leave the PPR settings as is and the DIR settings to forward. Set a PWM value and leave the DURATION as it is for now.
To complete this part it requires two checks (with tests):
- Motor Power (M+ and M-) Connection Check
- Motor Encoder Pins (A and B) Connection Check
MOTOR POWER (M+ and M-) CONNECTION CHECK
For this check, you’ll watch the Actual Motor, not the Virtual Motor. Ensure the DIR is set to forward and command the Motor with a PWM value. Watch the Actual Motor begin to rotate, if rotation is counterclockwise then the motor (M+ and M-) is properly connected. If not (i.e. it’s rotating clockwise), switch the M+ and M- connection and test it again you should see it now rotating counterclockwise.
MOTOR ENCODER PIN (A and B) CONNECTION CHECK
For this check, you’ll watch the Virtual Motor, not the Actual Motor. Ensure the DIR is set to forward and command the Motor with a PWM value. Watch the Virtual Motor begin to rotate, if rotation is counterclockwise then the motor encoder (A and B) is properly connected. If not (i.e. it’s rotating clockwise), switch the A and B connections and test it again you should see the Virtual Motor now rotating counterclockwise.
4. SETTING THE ENCODER PULSE PER REVOLUTION PARAMETER
Before you commence this step, first of all, test-control the motor with the lowest possible PWM you can control for it to rotate. You want to make sure you can make the motor move as slowly as possible (as much as it can allow). PWM values between 70 and 100 should do. Once done, note the value (I will call it slow PWM).
Also, add a form of marker to your Actual Motor to track the position during the test. This can be easily done by attaching a wheel to it and marking the wheel to track its angular position.
The PPR value is the number of encoder pulses per full rotation on the outer shaft (after the gearing). You can initially choose to leave the PPR value as the default value (1000) or you can choose to calculate the initial value from your motor’s datasheet with the formula below.:
PPR_initial = gear_ratio * motor_PPR (from the datasheet)
NOTE: The PPR usually given in the motor’s datasheet is not for the outer shaft rotation, hence, the need to multiply it by gear ratio.
Once you have calculated the initial PPR value, enter it and click the SET button to set it.
First, align the Actual Motor so its marker is positioned vertically, then click the RESET HAND button to align the Virtual Motor marker vertically. Both the Actual Motor and Virtual Motor Markers should now be pointing vertically upward.
Command the motor with the slow PWM gotten earlier and notice the marker motion of both the actual and virtual motor till both come to a stop.
Check the Virtual Motor marker to the Actual Motor marker position. You are checking if the Virtual Motor marker leads or lags behind the Actual Motor marker (i.e. if the Virtual Motor marker is faster than [leading] or slower than [lagging] the Actual Motor marker).
If the Virtual Motor marker is faster than the Actual Motor marker, increase the PPR value and go back to aligning the Actual and Virtual motor markers and commanding with the slow PWM again (as stated previously).
If the Virtual Motor marker is slower than the Actual Motor marker, reduce the PPR value and go back to aligning the Actual and Virtual motor markers and commanding with the slow PWM (as stated previously).
Keep doing the above until you get a satisfactory value (i.e. both are moving at the same pace and stopping at the same angular position).
NOTE: You can also manually turn the shaft instead of sending PWM commands although this might not be good for the motor in the long run.
5. CHECK THE MAXIMUM POSSIBLE ALLOWABLE MOTOR COMMAND SPEED (in rad/sec)
As the heading implies, we want to know the maximum possible angular speed (w_max) the motor controller can allow based on the encoder PPR parameter obtained in the previous step.
Select the MOTOR A PID menu (if your motor is connected to the motorB port, select the MOTOR B PID menu). You should see the PID gains (KP, KI, and KD). Also, you’ll see the W_MAX(rad/s) variable which holds the maximum target command velocity that can be sent to the motor as allowed by the driver module (the motor is connected to).
Anytime you change the PPR value in the MOTOR A ENC page, the W_MAX(rad/s) variable will automatically be changed to ensure good operation of the angular velocity computation via interrupts, the velocity filtering operation, and the PID computation (as well as other processes going on on the driver module’s microcontroller).
The W_MAX(rad/s) value is automatically calculated (anytime the PPR value is changed) with the formula below:
w _allowable = (2 * PI * 2000) / PPR [round the answer to the nearest whole number]
NOTE: You do not necessarily need to know this as the microcontroller already does the calculation.
Next, we check the actual motor’s max speed (in rad/sec) using the datasheet OR the velocity data obtained from the GUI.
- From the datasheet:
w_motor_max = (2 * PI * RPM_rated) / 60
OR
- from GUI:
Go back to the MOTOR A ENC page, send a high PWM value (200) to the motor, and note the VEL(rad/sec) value being printed, use this as the actual motor’s max speed (in rad/sec).
If the actual motor’s max speed (in rad/sec) is less than the initial computed W_MAX(rad/s), change it. if not leave it as it is (as you cannot change it to any value above the initial computed value).
6. SET THE PID GAINS (KP, KD, and KI) FOT THE MOTOR EMPIRICALLY
On the Application menu, you should see the MOTOR A PID menu option, select it (NOTE: if yours is connected to that of MOTOR B port, select MOTOR B PID).
The PID gain is set empirically. You can learn more from this video by Kevin Lynch -> Empirical PID Gain Tuning
Set the KP (while KD = 0 and KI = 0, the signal is set to STEP) by increasing, adjusting, and testing it to see its output on the graph.
Keep increasing and adjusting until the actual velocity signal begins overshooting beyond the target velocity signal.
Increase the KP gain until the actual value is close enough to the target value without the signal being unstable (there would be some overshooting).
NOTE: The higher the KP value, the faster (quicker) it reaches the Target value (set point).
Set the KD (while KP remains the same and KI = 0, the signal is set to STEP) increasing and adjusting it until the overshooting actual velocity signal is damped (smoothened out).
NOTE: The higher the KD value, the driving force effect of the proportional will be reduced
You can also use the square wave signal to test KD gain (while KP remains the same and KI = 0, the signal is set to SQUARE). This is good for checking and removing any form of jerking (i.e. little reverse motion) during an abrupt stop (halt). Increase the KD gain till you see no jerking in the motor when stopping abruptly (halt).
This setting is very good for mobile robots.
Finally, Set KI (while KP and KD remain the same, the signal is set to STEP) increasing it until the steady-state error is removed (i.e. till the actual velocity signals meet the target velocity signal). Remove the steady-state error without overshooting.
NOTE: The higher the KI value, the signal can become unstable.
Once done, test with other signal types (and even other target velocity values) to see if you are satisfied with the result. If not, you can repeat the process of the PID gain setting tweaking it to your taste and application.
7. CHOOSE A PREFERRED POSITIVE MOTOR DIRECTION
Select the MOTOR A ENC menu option (NOTE: if yours is connected to that of MOTOR B port, select MOTOR B ENC).
You can set the default positive direction to forward or reverse.
Set it to forward if you want to use it as a “left wheel” or if you want the positive rotational direction to be counterclockwise.
Set it to reverse if you want to use it as a “right wheel” or if you want the positive rotational direction to be clockwise.
8. I2C ADDRESS SETUP
You can also set its i2c address for communication with Arduino microcontrollers.
Select the I2C SETUP menu and set your preferred address value (between 1 – 127). The default address value is 1.