Student project review: Bluetooth controlled RC car
Last week I was asked to review a graduation project done by Martin Grigorov and Emiliyan Sokolov – two students at the TUES (electronics) high school of Sofia, Bulgaria. Their assignment was to take an RC toy car and turn it into an intelligent, Bluetooth enabled car that can be controlled from an Android phone. Here is an overview of the solution that they implemented.
Apart from the RC toy car, the project makes use of the following hardware:
- Arduino Uno board
- Nordic Nrf8001 Bluetooth Low Energy shield
- HC-SR04 sonar
- BH1750 light sensor
- Some directed light LEDs
- Android phone with BLE
First, the students reverse engineered the car’s control circuits and plugged them in an Arduino board. Then they added the Bluetooth module, so they can talk to the Android phone. And finally they connected the light sensor and the LEDs.
Once they had the Bluetooth connectivity running, they created an Android application with software buttons that move the car in the four directions. To make it even more intuitive to the user, they also added functionality on the Android side that uses the accelerometer and gyroscope modules of the phone to control the car, so that when the phone is tilted forward, the car would also move forward.
The HC-SR04 sonar can measure the distance from the car to an obstacle in front of it. To make good use of it, the students added user programming options to the Android application, that would have the car react to events – for example, back up when there is an obstacle in front. To define this behavior, end users would use a simple Android UI in order to define the events to be reacted upon, their value and finally the appropriate action. For example, if distance to obstacle is less than 10 cm, then back up the car.
Light sensor is used to turn the LED lights of the car automatically when the ambient light is insufficient. The functionality utilizes the PWM output so that the lights are turned on gradually.
The final piece of hardware work was a battery indicator. Battery level is measured using an analog (ADC) pin on the Arduino board and displayed on the Android UI as a well recognized battery indicator.
When the students demonstrated the solution to me it looked good and worked nicely, except the ultrasonic sensor. It would sometimes give false readings that would trigger unnecessary events. Therefore, my first question was how to implement a software solution to ignore or smooth out these faulty values. Some of solutions suggested were to use a moving average algorithm for smoothing out. Then came the idea to run the sensor for a while on several preset distances in order to capture the histogram of the erroneous readings for each given distance. Then we discussed adding a differential approach to the previous probabilistic data in order to come to more meaningful heuristics (e.g. did the value change a lot and is the new value within the regions of the histogram with the higher probability). The goal was to be able to determine the probability of the reading being faulty with enough confidence, so that it can be ignored by the next algorithms in the chain.
Our next discussion was regarding power supply. The device used two sets of batteries, one for the Arduino itself and the original RC toy car batteries as well. We discussed approached to reducing the sets of batteries to only one. The suggested solution was to only use the original toy car battery set and add a DC/DC converter in order to power the Arduino from the same batteries.
Then came the question about the algorithm used to measure the battery level. The students had used a lookup table with voltages and their corresponding battery levels. This was somewhat problematic due to two things. First, there are two types of batteries with different discharge curves – single use, alkaline batteries and rechargeable (NiMH) batteries. Single use batteries start at higher voltages (around 1.5V) and decline more gradually, while the NiMH start around 1.3V and sustain about 1.2 V for a long period of time. Another important point regarding battery level is that the “load zero” voltage doesn’t tell us that much about the remaining battery capacity. Therefore, we came to an alternative, that would also measure the battery voltage when the car is moving, so that there is load on the batteries. Thus it could be detected with better confidence which type of batteries are in place and to make more accurate judgements about their remaining capacity.
Last question was about security. The initial implementation would trust any phone in the range, which would be problematic if the device is used in an adversarial environment – lots of kids trying to control each other’s car 🙂 . We discussed a few approaches for associating a car with a phone and came to the conclusion that the most user friendly would be a hardware button on the car that would put it in pairing mode. Thus the user would be able to go to a non-adversarial place and prove that they are in physical possession of the car. Only then would the car accept a security token from the connected phone and use it in subsequent sessions. That token would be human readable, so that the user can configure another phone with the car without pairing it again (which would have deleted the previous token).
Even though it looked as a toy project at a first glance, it actually presented quite a lot of real world challenges that would be encountered in a more business oriented project as well. After the review I gave my recommendation to admit the students to their final exam. After a week I was notified that they did great on it and got the best possible rating.
Pavel Genevski is a Researcher at SAP Labs Bulgaria with interests in the areas of IoT, Security and Artificial Intelligence.