Remote Control Differential Drive Robot Car

A remote control differential drive robot car where the linear & angular velocities of the are controlled using a PID control system.

Similar projects worth following
The robot car is a two-wheel differential-drive mobile robot. The wheels are actuated by TTL DC motors whose speed and direction are sensed using quadrature encoders. The linear and angular speeds of the car can be sent over USB from a pc or over Bluetooth using the associated phone app. In order to quickly get to and maintain the desired linear and angular speeds a PID control system was implemented. An Arduino Mega is used as the microcontroller for the car.

Git Repository:


·        Hardware switch to change speed command source from associated phone app and pc with indicator lights

·        Maximum linear speed set to 130 rpm, given wheel radius that is 44.24 cm/s

·        Maximum rotation speed set to 200 deg/s

·        Can see actual linear and angular velocity of the robot on the app

·        App sends velocity commands with start and stop bits so that erroneous commands are ignored

presentation - 543.59 kB - 03/27/2022 at 05:03


MPEG-4 Video - 42.29 MB - 03/17/2022 at 19:42


MPEG-4 Video - 42.54 MB - 03/17/2022 at 19:40


MPEG-4 Video - 39.89 MB - 03/17/2022 at 19:40


Remote Control Robot Car.docx

Summary of project data

document - 3.61 MB - 03/17/2022 at 17:56


View all 11 files

  • 1 × Yikeshu 2WD Smart Car Robot Robot Platform
  • 1 × TT Motor with Encoder Motors with encoders to allow for velocity control
  • 1 × L298N Motor Drive Controller Motor Driver: Control input voltage to DC motors
  • 1 × Arduino Mega Microcontroller used to control robot and receive speed commands
  • 1 × Perseids Robot Car Chassis Kit Provide second layer of robot chassis to support electronics

View all 23 components

  • Project Complete

    Ghani Lawal03/17/2022 at 23:00 0 comments

    Added images of the current robot build and associated app interface.  Uploaded video of me controlling the robot using an app created using MIT App Inventor.  The project is now complete!!

  • Excel Files

    Ghani Lawal03/17/2022 at 05:14 0 comments

    Uploaded excel files showing results of step response test, the relationship between the PWM signal sent to the motor vs the supply voltage value and resulting motor speed.  Also included cost breakdown of the project i.e. Bill of Materials

  • Remote Control of Linear and Angular Velocity

    Ghani Lawal03/03/2022 at 23:52 0 comments

    Can now control the linear and angular velocity of the robot using the phone app via Bluetooth.  In order for the velocity commands to be parsed properly I had to increase app time interval to 100 milliseconds to ensure stable connection and switch which command, linear or angular, was sent at every time interval using a flag.

  • Control Switch

    Ghani Lawal02/28/2022 at 05:01 0 comments

    Using a Baud rate of 9600 is no longer feasible.  Kp and Ki values that gave the motor stable operation (6 and 3) are now causing sustained oscillations for certain step inputs.

    I was able to change the baud rate of the HC-06 Bluetooth module to 19200, will be using the value to communicate over Bluetooth and USB from now on.  May test how increasing baud rate affects stability of the system.  Also adjusted to PID constants to give "smoother response".

    I have also implemented a switch that will allow me to switch control of the robot from the phone app via Bluetooth and using a Serial port via Bluetooth or serial.  For the phone case I am still printing the speed values to the phone and pc so that I can graph the values on the pc.

  • Speed control via Bluetooth and Phone App

    Ghani Lawal02/26/2022 at 22:45 0 comments

    Originally intended to send speed command every time the position on the slider changed.  This was giving me wildly inaccurate values.  According to

    as the slider moves "updates occur very rapidly; this has the potential to overflow the Arduino input buffer.

    Therefore I decided to use the Clock.timer block to send the speed command at the clock interval, which was either 100 or 50 ms at the time.  The data sent was still 'slightly off'; so I rounded the position of the slider to the closest integer and prepended the value with "\r".  This worked... for the most part, but pretty often the app would send only a subset of the desired speed to the Arduino.  E.g. say Speed = "123" the Arduino would only receive "12" or "23".  To solve this last problem I created a added parity bytes to the speed command.  "a" was appended to the desired speed and "b" was prepended to the desired speed i.e. Speed = "a123b".  If the first byte isn't "a" and the last byte isn't "b" then the desired speed value of the Arduino would not be changed.

    ***Now have full, stable and consistent control of the speed of the motors using the app created using MIT app Inventor via Bluetooth,

  • Communication and Control

    Ghani Lawal02/25/2022 at 23:50 0 comments

    Control code works over USB at any given baud rate.  

    Only baud rate of 9600 works over Bluetooth when connected to phone app or computer.  There is probably a setting to change the baud rate of the module but that is not priority right now.  

    At a baud rate of 9600 there were sustained oscillations in both motor when making large downwards steps like say going from 100 rpm to 10 rpm when the Arduino is connected to the computer over USB.  I lowered Kp from 8 to 6 and Ki from 5 to 3.  Takes a while to reach desired value, but no oscillations. 

    Will address above issues once phone app is working.

  • Bluetooth Module Test

    Ghani Lawal02/23/2022 at 22:01 0 comments

    Used an app created from MIT App Inventor to connect to and control an Arduino via Bluetooth.

    Used a variation of the classic "Blink LED" sketch to test functionality.  Test was successful.

  • Simulink Communication

    Ghani Lawal02/22/2022 at 21:04 0 comments

    The tachometer block only uses one encoder/interrupt pin, therefore it can't acquire the direction of the wheel.  The fastest way to slow down the wheel from say 120 rpm to 0 rpm in the CW direction is to command the motor to spin as fast as possible in the CCW direction.  This is how my code works in C/C++ and the motor exhibits an underdamped/critically damped response.  However because I can't acquire direction information with the tachometer the system has to command the motor to spin slower, leading to an overdamped response.  In order to accurately model and test the dynamics of the motor and control system I tried using the two pin Encoder Arduino Block.

    Unfortunately when using the encoder block it was discovered that Simulink can't maintain communication with the Arduino and change values of the parameters at the same time.  

    This coupled with the fact that Interrupts only work in "External IO Mode" make testing the control system in Simulink an arduous task.  Also, when I tested the systems response to a sinusoidal input it lost connection after 30 seconds.

    ******Ordinarily I would not bother using Simulink to complete this project.  It hasn't added any value in terms of getting better control parameters or acquiring a deeper understanding of the motor dynamics.  However a lot of recruiters in the field I want to join want new hires with experience turning Simulink code into C/C++ code and implementing it onto a system 

  • Reading Encoders via Simulink

    Ghani Lawal02/18/2022 at 23:12 0 comments

    Tachometer and Encoder Simulink blocks (anything the requires an interrupt) only works in External Mode (Monitor and Tune), the can't be used in Connected I/O Mode

    When using a pulses/rotation = 1920 for when the trigger is set to CHANGE, there appears to be aliasing in the calculated speed of the motor when the PWM command rises above 120. i.e PWM=[0:120] -> RPM = [0:100], PWM =[120:200] -> RPM=[0:50]

    Therefore, when using Tachometer the trigger will be set to RISING and the pulses/rotation = 960.

    Tried using the Encoder block that requires ports of quadrature encoder to be connected to both be connected to interrupt pins.  Appears to work.

    ***It seems that Simulink is unable to maintain communication with the Arduino when it is receiving messages from more than 2 interrupt pins at once.

  • Dynamic Response

    Ghani Lawal02/17/2022 at 02:06 0 comments

    Completed surface level investigation into dynamic response of the motors.

    For step response to speeds up to 100 the system appears underdamped.  Motor A consistently settles to within 90% of its final value quicker than Motor B.  Motor A usually has a settling time of less than 0.4 seconds.  Motor B usually has a settling time of within 0.8 seconds, thought it can deviate from the desired value 100-300 ms latter, but is definitely is settled within 1.5 seconds of the step input

    For step responses to speeds from 110-130 rpm the system appears critically damped.  Motor A settles to within 90% of its final value within 0.24 seconds.  Motor B settles to within 90% of its final value within 0.26 seconds.  

    When stepping down by more than 15 rpm from any speed the system appears underdamped.  Stepping down by less than 10 rpm system appears critically damped.

    Kp= 8.5, Ki = 5, Kd = 0.02; SampleTime = 20 milliseconds.  Saved plots for ramp, step and sinusoidal responses

View all 14 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

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