S19: Hot Wheels

From Embedded Systems Learning Academy
Jump to: navigation, search

Hot Wheels


Hot Wheels

Self Navigating RC car using CAN communication based on FreeRTOS.

Demo day challenge


Hot Wheels is a Self Navigating RC car using CAN communication based on FreeRTOS. While navigating to the destination, if car sees any kind of obstacle, it avoids that too. The RC car takes real time inputs and covert it into the data that can be processed to monitor and control to meet the desired requirements. In this project, we aim to design and develop a self-driving car that autonomously navigates from the current location to the destination which is selected through an Android application, avoiding all the obstacles in the path. The car comprises of 5 control units communicating with each other over the CAN Bus, each having a specific functionality that helps the car to navigate to its destination successfully.


The project was divided into 5 modules:

Sensor Controller This module detects obstacles in the driving path with the help of ultrasonic sensors.
Motor Controller This controller drives the DC motor and Servo in the car and controls the speed of the car.
Geographical Controller This module assists the car in navigating to a destination with the help of location details

provided by GPS and the orientation(heading angle) provided by the compass.

Android Application Application developed on Android-based phones to communicate with car.

Destination coordinates,Start and Stop signals are send to car using this application.The Application also displays sensor values in real time for debugging purposes.

Bluetooth Controller The controller uses Bluetooth to communicate with an Android application on the Android phone.

Destination coordinates are provided by this module. The Bluetooth module also displays important
data like Ultrasonic sensor values and GPS coordinates on the app and LCD.

Master Controller This module collects inputs from all other modules and controls the motor. It is responsible for

system health monitoring, Obstacle avoidance and navigation to the destination.

Team Members & Responsibilities

Hot Wheels-Team Photo

Gitlab Project Link - Hot Wheels


Color Component


Master Controller


Geographical Controller


Communication Controller (Bridge)


Motor/IO Controller


Sensor Controller


Android App






Week# Start Date End Date Task Status
  • 02/26/2019
  • 03/05/2019
  • Team: Read previous projects, gather information and discuss among the group members.
  • Team: Assign team responsibilities for each module.
  • Team: Analysis of component required for each module
  • Completed
  • Completed
  • Completed
  • 03/05/2019
  • 03/12/2019
  • Team: Project plans and timelines discussed
  • Team: Finalize Components and order them
  • Team: Set-up GIT and Slack
  • Completed
  • Completed
  • Completed
  • 03/12/2019
  • 03/19/2019
  • Master Controller: Discuss with other Modules about what all the Master will communicate with other controllers. Work on having common DBC.
  • GEO Controller: Make Initial GEO code push on GIT
  • Android Application: Start taking tutorial to build basic app
  • Bridge Controller: Initial Bridge code push on GIT
  • Motor Controller: Push Initial Motor Code on GIT
  • Sensor Controller: Initial Sensor code push on GIT
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • 03/19/2019
  • 03/26/2019
  • Android: Get access tokens for Google API to enable maps in the application
  • GEO Controller-GPS: Get raw values from MPU9150 IMU sensor
  • Bridge Controller:Implementation of mDNS protocol for discovery of device on local subnet
  • Motor Controller: Get PWM values from Oscilloscope for DC Motor and Servo Motor
  • Master Controller: Finalize and code the overall software architecture including how many files to have for modular design, with unit testing capability in mind.
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • 03/26/2019
  • 04/02/2019
  • Android: Embed Google maps onto the Android App and add the project to the git repository
  • GEO Controller-GPS: Implement driver to get filtered values from the IMU
  • GEO Controller-Compass: Implementation of software interface to communicate with CMPS14
  • Bridge Controller: Implementation of local MQTT Broker on ESP8266 and Cloud broker on EC2 Instance
  • Team: Pin Layouts sharing from all groups
  • Motor Controller: Write Hello World program for DC and Servo Motor.
  • Master Controller: Develop health monitoring algorithm for the complete system.
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • 04/02/2019
  • 04/09/2019
  • GEO Controller-GPS: Send and receive coordinates and other parameters between Car and application
  • GEO Controller-Compass: Implementation of dedicated switches and 7-segment display for CMPS14 calibration
  • PCB layout 1st Iteration
  • Bridge Controller: Configure ESP8266 (as Wifi-to-serial bridge) to receiver data over Wifi and push it on UART
  • Motor Controller: Write Hello World program for DC and Servo Motor.
  • Sensor Controller: Experiment with the different sensors to check for which type works best for the RC Car
  • Master Controller: Develop basic obstacle avoidance algorithm including reversing the car and unit/actual test it .
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • 04/09/2019
  • 04/16/2019
  • GEO Controller-GPS: Send and receive coordinates and other parameters between Car and appS
  • GEO Controller-Compass: Calibration of CMPS14 module
  • Bridge Controller: Program for MQTT Client to UART link on ESP8266 module
  • Motor Controller: Find optimal Frequency and PWM values to drive Steering and Rear Wheels
  • Sensor Controller: Obstacle detection with SJ One board
  • Master Controller: Fine tune proximity thresholds and reversing algorithm for obstacle avoidance.
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • 04/16/2019
  • 04/23/2019
  • Android: Read the current position and get user input for the destination
  • GEO Controller-GPS: Get GPS and COMPASS readings and parse them
  • GEO Controller-Compass: Implementation of offset addition to raw compass values on switch press
  • Bridge Controller: MQTT to UART to CAN Bus Link and Bridge Controller MQTT to Android application Connection Link
  • Master Controller: Solving discrepancies regarding interfaces due to uncommon DBC and testing the developed code so far.
  • Motor Controller: Implementation of basic maneuvering of the RC car and test it with Master Commands through CAN
  • Sensor Controller: Integration with the RC Car and distance calculation
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • 04/23/2019
  • 04/30/2019
  • Android: Configure the UI elements for live monitoring in the app.
  • GEO Controller-GPS: Get the destination and waypoints from the Bridge Controller
  • GEO Controller-Compass: Arrange stand for mounting CMPS14 on car and test compass values with running car
  • GEO Controller-Compass: Transmit heading angle and CMPS14 debug messages to master and mobile app through CAN bus
  • Bridge Controller: Define messages and MQTT topics for bridge to app communication
  • Master Controller: Introducing different modes of operation of the car like: Self navigating mode, obstacle avoidance mode.
  • Motor Controller: Implement RPM sensor to calculate speed
  • Sensor Controller: Final Testing
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • 04/30/2019
  • 05/07/2019
  • Android: Define the message parameters and packing format for communication between car and app and plot the waypoints for the given coordinates
  • GEO Controller-GPS: Calculate Bearing and send navigation instructions to the Master
  • GEO Controller-Compass: Fix and test CMPS14 magnetic interference issue caused by DC motor
  • GEO Controller: Implement nearest checkpoint calculation algorithm
  • Bridge Controller: Encapsulation and parsing the data from MQTT payload
  • Master Controller: Developing basic Navigation algorithm based on bearing angle and heading angle.
  • Motor Controller: Fine Tune Steering and drive motors PWM values for speed calculated through RPM and implement uphill and downhill ramp logic
  • Team: Collect GPS checkpoints throughout university campus
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • 05/07/2019
  • 05/14/2019
  • Android: Send coordinates to Car
  • GEO Controller-GPS: Mount on the car and start testing on the field and make final changes accordingly
  • GEO Controller-Compass: Take compass value samples at different locations in the university and tune the compass calibration on the spot
  • GEO Controller: Implement navigation algorithm and test it
  • Bridge Controller: Update debug messages
  • Master Controller: Fine tuning the navigation algorithm and testing it for various destinations, with and without ramp.
  • Motor Controller: Implement RPM sensor to calculate speed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
  • 05/14/2019
  • 05/21/2019
  • Android: Add additional commands to the app (stop, reset, reroute)
  • GEO Controller: Final system testing
  • Bridge Controller: Display interfacing and final Testing
  • Master Controller: Final testing and handling of corner cases
  • Motor Controller: Final Testing
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
13 05/22/2019
  • Completed

Parts List & Cost

Item# Part Desciption Vendor Qty Cost
1 Traxxas Slash 4x4 [1] Traxxas 1 $239.00
2 Traxxas 5800mAh 7.4v 2-Cell 25C LiPo Battery [2] Traxxas 1 $69.99
3 Traxxas Battery Charger [3] Traxxas 1 $69.99
4 Traxxas RPM Sensor 6522 [4] Traxxas 1 $12.00
5 Traxxas Magnet Holder, Magnet and Spur Cover 6538 [5] Traxxas 1 $5.11
6 Traxxas Gear Cover 6537 [6] Traxxas 1 $5.13
7 GPS Module (Ultimate GPS Breakout V3) [7] Adafruit 1 $33.95
8 Compass Module (CMPS14) [8] Robotshop 1 $33.99
9 CAN Transceivers MCP2551-I/P Microchip [9] 8 Free Samples
10 Graphics LCD module 1 From Preet
11 Bluetooth(HC-05) HiLetgo 1 $9.00
12 SJ1 Boards Preetpal Kang 5 $400.00

Printed Circuit Board


The project requires to connect five ECUs (SJOne Boards) via CAN modules, Sensors, GPS, Compass, LCD, and lots of other connections for controlling RC Car. Initially, we used a general purpose board to connect all these modules together. Though due to the small size of the board ( 10mm x 30mm ), there were lots of congestion and wiring. The arrangement helped us to start initially testing. Though lots of wiring was a headache and was a hurdle to get consistent output so we decided to design PCB to get consistent output and also reduce wirings.

We designed the PCB using EGAL PCB Design Software. In our previous project (CMPE 244) we used KiCAD for PCB design. KiCAD is opensource software and features nicer and simpler UI, shortcut keys for fast development ( It was a really nice and nice to have a feature ) and inbuilt 3D PCB view. Though the problem with KiCAD was lack of library support, unorganized components library, and manual matching of the component with the footprint was a pain so we looked for other options. AutoCAD offers a free EGAL's license to students and hobbyists. EGAL is more organized compared to KiCAD and has good support of the component library. Bad UI and lack of shortcut keys slowed down our development process though it was trading. We can use Fusion 360 software from Auto CAD to visualize a 3D model of PCB.

We designed FRC connectors for each ECUs. Along with that we also populated 17x2 male header to incorporate any new changes in the future. Other major things were onboard CAN IC for each ECUs, connectors for four sensors, GPS, Compass and Bluetooth. We also provided support for the DB9 connector and onboard steady power supply.

PCB Schematics

Power Supply

We decided to go with a single power supply i.e. power from a LiPo battery of Traxxas RC car. Based on battery specification it is sufficient to provide require current, though one concern was during speed increase in the motor it can bring down overall voltage significant down below 5V which can cause to shut down or restart of SJOne board. To overcome this issue we used Buck-Boost convert. The S7V7F5 switching step-up/step-down regulator efficiently produces 5 V from input voltages between 2.7 V and 11.8 V. Its ability to convert both higher and lower input voltages makes it useful for applications where the power supply voltage can vary greatly, as with batteries that start above but discharge below 5 V.

5V Step-Up/Step-Down Voltage Regulator

Traxass ESC gives 6V output which we provided to Buck-Boost which then provides regulated 5V to all required components. Instead of designing a separate power supply for 3.3V we used the 3.3V output from SJOne Board which is working well.


PCB was sent to fabrication to JLCPCB China which provided PCB with MOQ of 5 with the lead time of 1 week. We implemented 2 layers of PCB with most of the parts in top layer. This time we decided to go with all SMD components due to the freedom it gives in terms of space. Also, our CAN IC was not available in DIP package. Soldering of SMD components is intimidating in the first place but after try on a few samples, it was very easy.

PCB front side
PCB Back side


PCB designing was there on our agenda but due to delay in sensor selection and prioritizing other tasks, PCB designing was delayed. We believe that PCB greatly improved car's robustness. So every team should finalize components in early stage and try to integrate PCB in design as soon as possible.

After receiving first order we came to know about a few bugs in PCB design. One of the major bugs was we accidentally swapped CAN high low pins, which we corrected by using external CAN trance receiver instead of onboard CAN IC. Due to lack of communication and rigorous PCB review instead of swapping UART Tx-Rx pins for GPS and Bluetooth we connected them directly as it is So we need to use wires for those modules. Still, PCB design helped us a lot to reduce our wire count.

Bill Of Materials






CAN Transceiver SN65HVD230DR 10 $2.38
5V Step-Up/Step-Down Voltage Regulator S7V7F5 1 $8.99
Header Connectors Kit LED-0603 2 $9.99
Diode Diode 1 $0.32
0.1uF Capacitor SMD 0805 0.1uF Capacitor 10 $0.23
0 ohm Resistor SMD 0805 0 ohm Resistor 25 $0.1
120 ohm Resistor SMD 0805 0 ohm Resistor 10 $0.44
IDC Extension Flat Ribbon Cable uxcell 34P 34 Way 2.54mm Pitch F/F IDC cable 6 $9.0

Mounting Mechanism

Mount mechanism

This is one of the first things which we did once we received our RC car. The mounting board is an essential part of the hardware design. This will provide support to all ECUs, sensor, and PCB. We used Acrylic glass Sheet for this purpose. We used MakerSpace (located in ground floor SJSU egineerring building) to cut the sheet in required shape and make holes for mounting. To mount sensor we ordered some readymade sensor stand from Amazon.

CAN Communication

Controller Area Network (CAN) is a communication protocol for off-board communication between various devices. The overall working of the Self driving car is completely dependent on proper CAN communication among all the control units at all times. To ensure this, there is a health monitoring system in the form of heartbeat messages which the master controller receives periodically from all the other control units. Apart from that, the CAN protocol provides appropriate speed of data transfer among all the control units for the proper functioning of the car. There is also the Message Is Absent (MIA) management facility to detect a break in communication thereby causing particular messages not being received at a certain rate when they are expected to be received, by the MIA timeout and replace their values with some safe values as configured in MIA data structures. Care has been taken to ensure that high priority messages are transmitted at a lower rate so that no message ever gets starved to get hold of the bus.

Hardware Design

System layout and CAN bus interfaces

DBC File

Gitlab link to DBC file [10]


NS_ :



 SG_ BRIDGE_START_STOP : 0|8@1+ (1,0) [0|1] "cmd" MASTER
 SG_ MOTOR_COMMANDS_stsp : 0|8@1+ (1,0) [0|1] "" MOTOR

 SG_ APP_HEARTBEAT_signal : 0|8@1+ (1,0) [0|255] "" MASTER
 SG_ GEO_HEARTBEAT_signal : 0|8@1+ (1,0) [0|255] "" MASTER
 SG_ MOTOR_HEARTBEAT_cmd : 0|8@1+ (1,0) [0|0] "" MASTER

 SG_ MASTER_SPEED_STEER_VAL_speed : 0|8@1+ (0.1,0) [0.0|2.0] "m/s" MOTOR
 SG_ MASTER_SPEED_STEER_VAL_steer : 8|8@1+ (0.1,0) [10.0|20.0] "%dc" MOTOR
 SG_ MASTER_SPEED_STEER_VAL_dir : 16|8@1+ (1,0) [0|2] "" MOTOR
 SG_ GPS_Latitude : 0|31@1+ (0.000001,-90.000000) [-90|90] "degrees" GEO,MASTER
 SG_ GPS_Longitude : 32|32@1+ (0.000001,-180.000000) [-180|180] "degrees" GEO,MASTER
 SG_ ULTRA_CMD_Front_Left : 0|9@1+ (1,0) [2|400] "" MASTER,APP
 SG_ ULTRA_CMD_Front_Center : 9|9@1+ (1,0) [2|400] "" MASTER,APP
 SG_ ULTRA_CMD_Front_Right : 18|9@1+ (1,0) [2|400] "" MASTER,APP
 SG_ ULTRA_CMD_Back_Center : 27|9@1+ (1,0) [2|400] "" MASTER,APP

 SG_ GEO_TELECOMPASS_compass : 0|13@1+ (0.1,0) [0|365.0] "" MASTER,APP
 SG_ GEO_TELECOMPASS_bearing_angle : 13|12@1+ (0.1,0) [0|360.0] "" MASTER,APP
 SG_ GEO_TELECOMPASS_distance : 25|12@1+ (0.1,0) [0|0] "" MASTER,APP
 SG_ GEO_TELECOMPASS_destination_reached : 37|1@1+ (1,0) [0|1] "" MASTER,APP

 SG_ GEO_CURRENT_COORD_LAT : 0|32@1+ (0.000001,0) [36.000000|38.000000] "degrees" MASTER,APP
 SG_ GEO_CURRENT_COORD_LONG : 32|32@1+ (0.000001,-123) [-123.000000|-120.000000] "degrees" MASTER,APP

 SG_ DBG_STEER_VAL_speed : 0|8@1+ (0.1,0) [13.5|16.5] "%dc" MASTER,DBG
 SG_ DBG_SPEED_STEER_VAL_steer : 8|8@1+ (0.1,0) [10.0|20.0] "%dc" MASTER,DBG
 SG_ DBG_SPEED_STEER_VAL_dir : 16|8@1+ (1,0) [0|1] "" MASTER,DBG

 SG_ GEO_DEBUG_CMPS_CALIB_STATUS_System : 0|2@1+ (1,0) [0|3] "" 
 SG_ GEO_DEBUG_CMPS_CALIB_STATUS_Magneto : 2|2@1+ (1,0) [0|3] "" 
 SG_ GEO_DEBUG_CMPS_CALIB_STATUS_Accelero : 4|2@1+ (1,0) [0|3] "" 
 SG_ GEO_DEBUG_CMPS_CALIB_STATUS_Gyro : 6|2@1+ (1,0) [0|3] "" 

 SG_ GEO_DEBUG_DEST_COORD_Latitude : 0|31@1+ (0.000001,-90.000000) [-90|90] "degrees" 
 SG_ GEO_DEBUG_DEST_COORD_Longitude : 32|32@1+ (0.000001,-180.000000) [-180|180] "degrees"

CM_ BU_ DRIVER "The driver controller driving the car";
CM_ BU_ MOTOR "The motor controller of the car";
CM_ BU_ SENSOR "The sensor controller of the car";
CM_ BO_ 100 "Sync message used to synchronize the controllers";

BA_DEF_ "BusType" STRING ;
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 0;
BA_DEF_ SG_ "FieldType" STRING ;

BA_DEF_DEF_ "BusType" "CAN";
BA_DEF_DEF_ "FieldType" "";
BA_DEF_DEF_ "GenMsgCycleTime" 0;

BA_ "GenMsgCycleTime" BO_ 100 1000;
BA_ "GenMsgCycleTime" BO_ 500 100;
BA_ "GenMsgCycleTime" BO_ 101 100;
BA_ "GenMsgCycleTime" BO_ 400 100;
BA_ "GenMsgCycleTime" BO_ 200 100;
BA_ "FieldType" SG_ 500 IO_DEBUG_test_enum "IO_DEBUG_test_enum";

VAL_ 500 IO_DEBUG_test_enum 2 "IO_DEBUG_test2_enum_two" 1 "IO_DEBUG_test2_enum_one" ;

Sensor ECU

Group Member

Sensor Selection


Selecting the correct sensor for applicating is very important. For this project, the sensor should be able to responsive, accurate, able to work in the outdoor environment and it should provide long-range obstetrical detection. Though there are lots of option available for distance, we can divide them into three main categories 1) Lidar 2) Ultrasonic and 3) IR sensor. We choose to go with the ultrasonic sensor due to it is proven and easy to implement compared to Lidar and IR sensor, moreover, it is cheaper than both other option. We specifically selected SparkFun Ultrasonic Sensor - HC-SR04 to measure the distance from the back, left and right of the robot while we used MaxBotix Inc. Ultrasonic Distance Sensor MB1240-000 XL-MaxSonar-EZ4 as the center sensor. MaxSonar-EZ4 is able to detect obstetrical in 700cm range while HC-SR04 can detect obstetrical in the 300-400cm range. MaxSonar-EZ4 uses more narrow beam and more accurate than HC-SR04, though it is five times costlier than HC-SR04.

Design & Implementation

Ultrasonic Sensor calculation

Hardware Design

We ordered the HC-SR04 sensor's mounting bracket from Amazon. We printed 3D mounting bracket for MaxSonar-EZ4 sensor from SCE lab.

The HC-SR04 Ultrasonic Module has 4 pins, Ground, VCC, Trig and Echo. The Ground and the VCC pins of the module needs to be connected to the Ground and the 5 volts pins on the Board respectively and the trig and echo pins to any I/O pin on the SJOne Board. In order to generate the ultrasound, you need to set the Trig on a High State for 10 µs. That will send out an 8 cycle sonic burst which will travel at the speed sound and it will be received in the Echo pin. The Echo pin will output the time in microseconds the sound wave traveled.

For example, if the object is 10 cm away from the sensor, and the speed of the sound is 340 m/s or 0.034 cm/µs the sound wave will need to travel about 294 u seconds. But what we will get from the Echo pin will be double that number because the sound wave needs to travel forward and bounce backward. So in order to get the distance in cm we need to multiply the received travel time value from the echo pin by 0.034 and divide it by 2.

Software Design

We designed APIs in generalize manner and tried to avoid hard-coding any pin configuration in API itself. To make API 100% testable we used dependency injection concept. All sensors we initialize before stating periodic task. We used the 10Hz periodic task to update sensor value.

In beganing, using periodic take do any work was a mandatory/ requirement of the project. Though the way in which sensor works it takes more than or almost 100ms so we ran into task overrun issue. This we overcome by just measuring only any two sensor value in a single iteration. This helped us to reduce interference and also it made the code more robust. Though this logic reduced the speed at which sensor update its value.

Instead of using inbuilt timer interrupt or polling GPIO we used the fixed delay to get a response from echo pin, which made our code more deterministic.


Init Sensor API
Update Sensor API
Update All Sensors

Motor Controller

Group Members

Design & Implementation

Hardware Design

Motor Module Schematic

SJOne Pin Connections
Pin Number Pin Function
P2.0 Servo Motor
P2.1 Electronic Speed Controller (ESC)
P2.5 RPM Sensor

Hardware Specifications

ESC and DC Motor

ESC and DC Motor

The Traxass Slash 4x4 has XL-5 Electronic Speed Controller (ESC) and Titan 12T DC Motor installed in it. The ESC is powered by LiPo Battery which further controls the DC motor. The ESC comes with the feature of calibrating the DC motor using the EZ set button that is present on ESC. It comes with three modes

  • Sport mode (100% Forward, 100% Brakes, 100% Reverse)
  • Training mode (100% Forward, 100% Brakes, No Reverse)
  • Racing mode (50% Forward, 100% Brakes, 50% Reverse)

For our project we used Sport mode because we needed full capability of the motor for uphills and rough terrains. Also we used our ESC in Low-Voltage Detection activated mode. In order to know more about ESC profiles, Battery modes and how to calibrate them, refer to Traxxas official link here [11].

DC Motor Pin Connection
Wires on (ESC) Description Wire Color Code
(+)ve Positive Terminal RED
(-)ve Negative terminal BLACK
ESC Pin Connection
Wires on (ESC) Description Wire Color Code
(+)ve Connects to (+)ve of DC Motor RED
(-)ve Connects to (-)ve of DC Motor BLACK
(+)ve Connects to (+)ve of Battery RED
(-)ve Connects to (-)ve of Battery BLACK
P2.0 (PWM1) PWM Signal From SJOne WHITE

Servo Motor

Traxxas Servo Motor

Servo Motor is responsible for steering the car. Traxxas Slash 4x4 has Servo Motor 2075 pre-installed in it. It controls the front two tires of the car.

Servo Motor Pin Connection
Pin No. (SJOne Board) Function Wire Color Code
P2.1 (PWM2) PWM Signal WHITE

RPM Sensor

Traxxas RPM Sensor

RPM sensor is used to calculate speed of the car. A magnet is placed inside the spur gear with the help of magnet holder and every time a tire completes one rotation, RPM sensor detects a pulse. RPM sensor it self is placed in the gear cover. In order get the RPM Sensor working, following Telemetry items from Traxxas are required

  • Traxxas RPM Sensor 6522
  • Traxxas Magnet Holder 6538
  • Traxxas Gear Cover 6537

To install these, there is very detailed step by step tutorial by Steve Jones (Cstoneav) on Youtube which can be found here [12]

RPM Sensor Pin Connection
Pin No. (SJOne Board) Description Wire Color Code

Hardware Interface

Software Design

For Motor Controller module, we made a singleton class for it. Some groups from our batch and from previous batches faced an issue that PWM object was going out of scope and they weren't able to get it run. We adapted this implementation from start, learning from experiences of our seniors of this course and never faced any issue regarding this. This class would only have one object, which initializes PWM objects for both Servo and DC at 100Hz in it's constructor.

Motor Controller Class

In Periodic Init function, CAN1 is initialized at baudrate 100bps and TX/RX queues of size 10. In same function, to detect RPM rotation, an interrupt is enabled at port 2.5 at rising edge. In 1Hz Task, we check is bus is off, then we just reset it if it's off. Similarly, in 10Hz Task, we are detecting the speed of the car and driving the car. Then in 100Hz Task, we are sending heartbeat to the Master along with actual speed and debug messages on CAN. In same task we are receiving the values of direction, speed and steer from the Master on CAN and storing them in our global variables.

Motor Controller Class

ESC and DC Motor

The only tricky part in this is sending reverse, rest every thing is pretty much straightforward. For Traxxas ESC, to move car from forward to reverse we need to send following commands is sequence:

  • STOP

For implement this logic, we kept it very simple, we took a global variable and increments when first time reverse came, for first time it would send REVERSE to ESC, second time if again reverse is recieved, it increments again then sends STOP to ESC and then 3rd time it sends reverse again after incrementing it for last time. If Master keeps on sending reverse, we won't change anything on ESC as we have already given ESC reverse command and is it going reverse. As soon as master sends Stop or Reverse command, this variable will be set to zero and new PWM value will be send to ESC. We sent PWM values to ESC at 10Hz. We were sending it at 100Hz first but that was too fast for ESC and would miss some value. So we moved to 10Hz and worked perfectly fine.

ESC and DC Motor

Servo Motor

Servo Motor is very straightforward, the flow is mentioned in the flow diagram below along with the PWM values.

ESC and DC Motor

RPM Sensor

We used one magnet to detect the rotation, we thought it's not enough in start we should have gone with more than one magnet, but it worked well at the end. The most important part where we need it most is while going up and down the ramp. We enabled the interupt for port 2.5, and whenever interrupt occurs it just increments the global variable we have for rpm counts. At 200ms, we are calculating the speed and resting the rpm count variable to zero. Then, once we have the actual speed in our global variable, we are comparing it with our requried speed and playing with PWM values as mentioned in ESC and DC software implementation.

ESC and DC Motor

Technical Challenges

  • One major issue which motor module faced was that Car would just randomly stop when Master was sending reverse, but if Master send Forward it would recover and starts functioning normally. The issue we figured out was we were sending Command to ESC at 100Hz, which is to fast for ESC. For reverse ESC needs to receive Reserve Stop and Reverse, when we were sending it at 100Hz, ESC would miss any of these commands and just stop. Without any other change when we moved our function call to 10Hz, it fixed this issue.
  • We burned our Speed Controller most probably due to shortage of wires, we borrowed a car from the group and used our circuit on their chassis, but there's a shop in San downtown NorCal hobbies, they have cars as well as parts for RC cars, go and buy from their, don't waste time in waiting for online order.
  • Another challenge is you need to know what is the RPM value when car is running so that you can make your logic accordingly, one way is to show it on app or LCD, but when there was a deadline for Ramp demo, these two were in initial stages, so we showed the RPM values on 7-seg display just for debugging purpose.
  • Using both PWMs at same frequency, it wasn't actually a challenge nothing broke from this, but we did not know this in start that we have to run all PWM objects at same frequency so it kind of wasted some time for us in debugging it.

Geographical Controller

Group Members

Hardware Design:

Geo Module
GPS ultimate breakout.jpg

Module Interface

The GEO module primarily consists of two independent hardware modules: the GPS module and the compass module. The GPS module provides the current location of the car as it moves and the compass module provides the heading angle of the car with respect to true north. For the GPS module, we are using Adafruit's "Ultimate GPS Breakout V3" and for the compass module, we are using "CMPS14" module from Robotshop. CMPS14 module uses I2C interface to connect with the SJ-One board whereas, the GPS module is interfaced to SJ-One using UART.

Module Selection

Selecting the appropriate module for both the compass and the GPS sensing were difficult decisions. We initially ordered "GPS - Readytosky Ublox NEO-M8N GPS Module" from Amazon as it came with a stand and an inbuilt compass module. This would have been cheaper as we would save money on the compass module. However, we later found out that the inbuilt compass values were not reliable enough and the GPS in this module was not original Ublox. Original Ublox GPS has an inbuilt flash memory to update its firmware for GPS calibration. We would thus have to rely on the factory calibration for the GPS. After considering all this, we decided to move to better modules as navigation was key for our project's success.

Compass modules are very sensitive to magnetic interference. We selected CMPS14 module as our compass as it has commands to dynamically check the calibration status of the module at runtime. We mapped this calibration status value to the 7-segment display on the SJ-one board which proved to be very useful in detecting magnetic interference across the campus and take decisions accordingly. Note however that CMPS14 does not return the current gyro calibration status. This is a bug which is mentioned in its data sheet. For the GPS module, we went with Adafruit's Ultimate GPS breakout module as it is known for its reliable GPS values.

CMPS14 Registers

CMPS14 Commands

Software Design

Geo Navigation

This layer uses the current GPS coordinates from the GPS module, the destination GPS coordinates from the mobile app and the current car heading angle from the compass module to calculate the bearing angle and the distance remaining from the destination. The bearing and heading angle along with the distance remaining to the master controller. The master controller then simply subtracts the bearing angle with the heading angle to get the turning angle which is used to turn the car towards the destination or next checkpoint.

We have taken manual checkpoints across San Jose State University campus and calculate the nearest checkpoint to navigate towards the destination. We need to take checkpoints manually as checkpoints provided by Google maps may not be maneuverable for the car. For example, A human can easily climb stairs but the car cannot.

Geo Module
   Turning Angle = Bearing Angle - Heading Angle

The heading angle is nothing but the car's compass value. This angle is with respect to the true North. Note that the compass needs to be fully calibrated to get accurate readings. This is critical to the working of the navigation algorithm.

Bearing Angle Calculation

Bearing angle is the angle of the destination or checkpoint with respect to the true North. The Bearing (in Degrees) is calculated using the Forward Azimuth formula:

      bearing = atan2( sin(longDiff_rad)*cos(lat2_rad), cos(lat1_rad)*sin(lat2_rad)-sin(lat1_rad)*cos(lat2_rad)*cos(longDiff_rad))

Here, (lat1, long1) are the car's current GPS coordinates and (lat2, long2) are the destination GPS coordinates. The Forward Azimuth formula assumes a virtual point on the latitude access to calculate this angle.

Distance to Destination Calculation

The distance (in Meters) is calculated using the Haversine Formula:

   a = sin^2(latDiff_rad/2) + cos(lat1_rad) * cos(lat2_rad) * sin^2(longDiff_rad/2)
      formula: c = 2 *atan2(sqrt(a), sqrt(1-a))
      d = Radius of Earth * c

Here again, (lat1, long1) are the car's current GPS coordinates and (lat2, long2) are the destination GPS coordinates.

The heading, bearing, and distance values are shared with the Master controller which calculates the turning angle. A moving average with a window of 10 was implemented to filter out any possible bad GPS parsing. We marked any distance value above the moving average as invalid and dropped it.

To navigate the car towards the destination, the difference of the heading and bearing should be approximately zero. After many test runs, we realized that this difference should be within a range of +/- 3 degrees to account for sensor inconsistencies.

CMPS14 Start Calibration Process

To start the compass calibration, write the following to the command register 0x98, 0x95, 0x99 with a 20 millisecond delay after each byte. You can then send the setup byte to the command register. It takes the form:

Start Calib Sequence SW
Start Calibration Sequence

Switch 1 dedicated for this purpose.

CMPS14 End Calibration Process

To end the calibration and store the updated calibration profile in CMPS14, write the following byte sequence to the command register with a 20 millisecond delay after each of the three bytes: 0xF0, 0xF5, 0xF6. Switch 4 dedicated for this purpose.

Start Calib Sequence SW

CMPS14 Erase Calibration Profile

To erase the stored calibration profile in CMPS14, write the following byte sequence to the command regiester with a 20 millisecond delay: 0xE0, 0xE5, 0xE2. Switch 3 dedicated for this purpose.

Start Calib Sequence SW

Technical Challenges and Solutions

1. Calibrating Compass Module

   The compass module was not giving stable values on default calibration.
   The compass north changed every time the module powered off.
   The compass value would change after a full 360-degree rotation.
   The compass value moved up on tilting the module.


   Step 1: Keep the compass stable on the ground to calibrate the gyro sensor.
   Step 2: Now, randomly move the module to calibrate the magnetometer.
   Step 3: After this, tilt the compass module in all directions and slowly move the module 360-degrees clockwise and anti-clockwise
           to calibrate the accelerometer.
   Make sure the calibration status of the respective in-built sensor reaches the maximum value of 3 on each of the above steps.
   Note: Compass is best calibrated in a non-magnetic environment. To check the magnetism in any area, use a mechanical (magnetic)compass.
   Note: There are underground electrical lines spread throughout the university which cause magnetic interference in the compass module.
         We found 10th street parking, 6th floor to be a good spot for testing and calibrating compass and GPS module.

2. Compass Calibration Unreliable

   After calibrating the compass, the calibration status was changing at runtime due to magnetic interference from the ground and shaking of the car.
   This occurred even after turning off the auto calibration feature in CMPS14 module. 


   Mapped system calibration status to on-board 7-segment display to keep track of the compass calibration at run-time and provided dedicated switches
   to start calibration, end calibration and erase calibration profile. This allowed us to perform instant re-calibration of the compass
   if the calibration is affected.
   Also provided dedicated switch to add offset to the compass value.
   This enabled us to set true North according to the mechanical compass in high magnetic interference areas.

3. Magnetic Interference from Motor

   Unlike interference from the ground and underground electrical lines, interference from car's DC motor was causing the compass value to
   increment constantly even when the car was not moving. This interference increased as the car speed increased.


   To avoid this interference, we magnetically shielded the car's DC motor. To achieve this, we simply covered the motor with aluminum foil.
   Aluminum is magnetic and absorbs magnetism. This significantly reduced the magnetic interference to the compass from the motor.
   Note: There is no known material that blocks magnetic fields without itself being attracted to the magnetic force. Magnetic fields can only be redirected,
   not created or removed. The magnetic field cannot be completely blocked. Magnetic shielding can be done by any material which absorbs magnetism.
   Note: Shielding the compass module would block the earth's magnetic field from reaching it which is why we cannot cover the compass module with foil.

4 Inaccurate GPS Coordinates

   The GPS module took a lot of time to get a fix and after it got a fix, the values were not accurate.


   We used the GPS antenna to get a faster fix and we noticed a lot more accurate GPS coordinates after connecting the antenna.

5 Unreliable GPS lock

   After the GPS module got a lock, it would sometimes lose the lock and give incorrect GPS coordinates.


   To fix this issue, we checked the GPS lock status and sent pre-determined error value to the master so that the master knows the GPS module 
   is giving incorrect values and take decision accordingly. Also used a dedicated onboard LED to indicate GPS fix.

Communication Bridge Controller,Android Application and LCD

Group Members

The user communicates with the car through the Communication Bridge Controller. This module consists of the LPC1758 communicating with the Android application on the phone via Bluetooth. The user selects the final destination on the google map to which the car should navigate, through an android application. LCD is used to display the recorded values of the ultrasonic sensors, the current latitude, and longitude values from GPS, bearing and heading angle from the compass for the car. Along with that, these values can be seen on Android application as well.

connection diagram

Hardware Design


The HC-05 Bluetooth module was used to communicate the Android application in the Android phone with the car. This module is based on the Cambridge Silicon Radio BC417 2.4 GHz Bluetooth Radio chip. This is a complex chip which uses an external 8 Mbit flash memory. It includes the Radio and Memory chips, 26 MHz crystal, antenna, and RF matching network. The right section of the Bluetooth Board has connection pins for power and signals as well as a 5V to 3.3V Regulator, LED, and level shifting. The Bluetooth from mobile phone communicates with the microcontroller through the Bluetooth module interfaced to it dedicated to receiving the messages from the phone, parse those messages and convert them into an appropriate data type that was transmitted to the expected receiver through the CAN Bus.

  • HC-05 PinOut :
    • EN: In case brought HIGH before power is applied, forces AT Command Setup Mode
    • VCC: +3.3V Power
    • GND: Ground
    • TXD: Serial Transmit pin connected to RXD2 of SJOne board
    • RXD: Serial Receive pin connected to TXD2 of SJOne board
    • STATE: States if connected or not
  • LED Blinking signals:
    • if flashing RED fast: ready to pair
    • if flashing RED slow: paired and connected

Liquid Crystal Display

A 20x4 LCD(CM 204-1) with LCD driver by SJValley Engineering is used for accessing the LCD through UART. The driver and LCD are soldered directly to avoid any loose connection. To power up, LCD 5V supply is given from common 5V source which is coming from ESC (6V) and converting it to 5V using buck-boost. As soon as the LCD is powered on, it is initialized to a baud rate of 38500 and 0xF0 command is sent. After 0xF0 is sent, the data can be transmitted using UART. Before that two commands are sent to set brightness level and clear screen. If you are getting some junk values, make sure that the baud rate is set correctly and check the soldering.

Software Design


A special format for the strings received was used to make extracting of the important aspects such as start/stop command, latitude and longitude of the destination. Similarly, we also kept a specific format for the string that was to be transmitted to the mobile application which made data parsing and displaying in the android application easy . The specific formats that we chose are as shown below:

  • Format for the string received from android application: ~start/stop@latitude!longitude#
 ~ denotes the start of the string and also the start of the start/stop variable
 @ denotes the start of latitude value
 ! denotes the start of longitude and the end of latitude values
 # denotes the end of the entire string
 example: ~1@37.337897!-121.885623# 
  • Format for the string transmitted to android application: ~Sensor values@latitude!longitudeCcompass_value^bearing angle$distance#
 ~ denotes start of the string 
 @ denotes start of latitude
 ! denotes start of longitude
 C denotes start of the compass_values
 ^ denotes start of bearing angle
 $ denotes start of distance
 # denotes end of the string  
 example: ~L300R200F150B200@37.337897!-121.885623C140.12^310.87$26#

Keeping such dedicated formats made data parsing convenient and easy to convert and process the data further ahead.

Communication Process Flow Diagram

Liquid Crystal Display

On boot up, LCD is initialized at baud rate 38400 and 0xF0 is sent through UART. Then Brightness is set and the screen is clear. This is done only for the first time. After this Ultrasonic sensor values are displayed on LCD through UART and our screen is getting updated after every 1 second and this value will continue for a total of 3 seconds and then GPS coordinates and Compass values are shown similarly by clearing the screen and in this way, it goes on continuously until power off. By default, the cursor value is at first row and the first column, to jump to the next column we send the desired column and row through GOTO command. We implemented the LCD driver such that all this is handled in one function call.

LCD Flow Diagram

LCD Commands
Command Description
$BLIGHT:100 To set brightness to 100(full)
$CLR_SCR To clear screen
$GOTO:3:4 To move cursor to particular position (col:row)

Technical Challenges

  • Connection between Application and Module is not stable. Over a medium-long range, the application gets disconnected with HC-05 module.
Solution: We used "Reconnect Button" on our Android application to re-establish Bluetooth socket connection instead of re-opening the application.
  • When multiple cars are around and if they are using the same HC-05 module since the pairing password for the HC-05 module is same for everyone, the application ceased to connect to the Bluetooth due to interference from Bluetooth of other Android applications.
Solution: Change the password of the Bluetooth module using the AT commands using an Arduino. 
  • Getting junk values when LCD is power ON and only 2 lines were displaying.
Solution: Soldering issue possibly or driver also, so better test it before soldering to get a clear idea. In our project, we change our LCD and the second one works well.

Android Application

User Communicates with the car using Android application.We have three modes on application namely
1.Self-Drive Mode
2.Obstacle Detection Mode
3.Communication mode.

UI of Application

Home_screen Connect_screen send_data Mode_select Obstacle_avoidance send_data

Technical Challenges

  • Connection between Application and Module is not stable. Over a medium-long range, the application gets disconnected with HC-05 module.
Solution: We used "Reconnect Button" on our Android application to re-establish Bluetooth socket connection instead of re-opening the application.

References for Android Application

Master Module

Group Member

Hardware Design

The Master control unit has only the connections to the CAN bus apart from the power supply. Below diagram describes the connections. CAN transceiver MCP2551-I/P is used which converts single ended individual TX/RX signals to CAN_High and CAN_Low differential signals.

Master control unit

Software Design

  • The Master control unit is the heart of the Self-driving car as it takes all the critical decisions based on inputs it receives from the other control units like App, Sensor, Geo and drives outputs which are the Motor control Unit.
  • The Master control unit mainly performs Navigation of the car to the selected destination and Obstacle avoidance as and when they come in the car's way. Besides, it also continuously monitors the health of the overall system by means of periodic heartbeat CAN messages received from all the other control units. This ensures that the car is moving in a controlled manner all the time.
  • For navigation to the destination through numerous checkpoints, the bearing angle, heading angle and the distance to the destination is provided by the GEO control. The App control provides the start and stop commands.
  • The Sensor control unit provides the ultrasonic sensor values of the 4 sensors regarding obstacle avoidance.
  • The Navigation and Obstacle avoidance algorithms are run @25Hz, CAN inputs are processed @100Hz and health monitoring is done @1Hz. The detailed flowcharts are shown below.

Master control Algorithm

Obstacle avoidance Algorithm

Navigation Algorithm

Technical Challenges

  • It was tedious to tune the proximity thresholds for the 4 sensors for proper obstacle avoidance, because it involved changing them, build them, flash them and test again and again till we get fine tuned results. This was time and effort consuming. To save time, I placed a CAN debug message in the code to write directly into the threshold variables, via PCAN dongle and busmaster whenever I want. So basically I change the thresholds anytime within seconds and immediately test.


We were able to navigate our RC car from current destination of the car to the destination chosen through the android application successfully . The car was also able to avoid obstacles in its path throughout the journey to the marked destination.The project helped us gain a working knowledge of CAN bus and communication, interfacing various components such as motors, GPS, Bluetooth and ultrasonic sensors along with some knowledge regarding pulse width modulation (PWM), UART, I2C. This course and project also gave us a deep understanding of FreeRTOS, Android, Unit testing and Git. It taught us the important aspect of team work, coordination and surely taught us the importance of proper planning and hard work.Overall, it was a superb experience enriched with knowledge and hands on experience that molded us into better than we were before.

Project Video

Team Hot Wheels-Project Video

Team Hot Wheels-Obstacle avoidance and self rerouting

Project Source Code

Team Hot Wheels-Gitlab

Advise for Future Students

  • Do thorough research on all the sensors before ordering them. We had previously ordered some cheap sensors but had to replace them with good quality sensors.
  • For Motor Module, take time in reading seniors projects, the only tricky part in it is ramp testing, which takes some time and logic. Otherwise if you are stuck in ESC or Servo motor, you haven't done your homework.
  • Achieving steady readings and calibration for compass is tricky, so start with the compass module as soon as possible. The navigation algorithm depends upon the compass module.
  • Be patient when calibrating compass. Try to do the calibration with teammates. This will save time and avoid conflicts.
  • Use a mechanical (magnetic)compass for calibration. Do not rely on compass mobile apps when calibrating your compass as mobile apps rely on the electronic compass in the mobile which may not be fully calibrated.
  • For Android application design remember to close the mchat sockets and disable bluetooth adapter before exiting the application or changing the intent
  • To save a lot of time during testing/fine tuning anything, have plenty of CAN debug messages. Say for tuning proximity thresholds of Ultrasonic sensors, you can have a debug message which you can simply write through a PCAN tool via busmaster and test it instead of changing them in code, building them, flashing them and then test.
  • If you are sure of the requirement of say a function, Perform Unit testing to test your logic. It saves time to find a bug via unit testing instead of finding it while testing it in the car.


We would like to thank our professor, Preetpal Kang for designing such an amazing course and including the project of self-navigating car in the coursework. He has been an inspiration to us and was always there to guide and push us to achieve our goal of implementing a self-navigating car successfully. We would also like to thank the ISA member,Pratap for providing his insights and feedback after demos and motivating us to do well. We would also like to thank all the members of the other teams who selflessly coordinated and helped us,forgetting all their differences when in need.