First threshold to classify “good” and “bad” roads

After visualizing the sensor data of a 25 time frame (from our first test drive) which contained both, good and bad quality roads we decided that the road quality can be extracted by only using the “z-acceleration” – at least for a first threshold to classify between two simple qualities: “good/okay” and “(really) bad”.

(The green section in the first chart marks a good quality road, the blue sections a “normal” quality road and the red section a “(really) bad” quality road.)

For references: charts for gyroscope and rotation data:



Finding a first threshold

Then we combined our road quality notes of the first test drive with the “Z-acceleration” data of the whole test drive and decided to use 1.4 as a threshold to differentiate between regular quality and “pothole measurements”:

21:49 “bad road”

20:52 “really bad road”

21:05 “quite good road”

21:23 & 21:25 “really bad road”

Controlling Our Measurement Device

After adding the status LEDs and the control button we implemented the control logic:


Sensing: As soon as the GPS and sensor data of all sensors is available (in real-time) at the server-PI it saves the data in CSV files (see this post for details).

Uploading: When the messbox is in “Ready”-state, CSV files exist and the web server is responding to a ping the server-PI tries to upload the CSV files through Websocket. When the upload is successful the CSV files get deleted.

Small Upgrade On The Hardware Side

Our measurement device got a small hardware upgrade: Two status LEDs and a button:


With R1 = U(R1) / I = (U(GPIO) – U(LED)) / 0.010A = (3.3V – 2.0V) / 0.010A = 130 Ohm

We connected the button to GPIO 5 with a pull-up resistor  (10kOhm). This way the Raspberry PI can be booted with the button (no software code needed).

USB Switch

Currently only our RPIs are powered by battieres – our switch is connected to the car on-board-socket (through a converter). If the whole messbox needs to run with battery packs only there are adapters available to plug your low-power switch to a regular USB port (battery pack).

In our case (D-Link DGS-1008D) we need 7.5V, 1A to USB adapter – available e.g. here(1).
(1) This was the only one we found online but the seller confirmed that it works for our device: “Yes, I just checked and our adaptor B00HM59B4C will suit the D-Link DGS-1008D. The current draw will be fine and the tip is the correct size.”

Testing the current state of the messbox

After working on the server-PI and sensor-PIs separately and often virtualized we decided that it’s time to put the messbox together and see what happens.


The PIs boot and connect automatically. The sensor-PIs directly start sensing and forward the data to the server-PI who reads the GPS data and writes the received sensor data to csv files as soon as all sensors are connected.


Here you have a sample csv log file which contains a quake around the timestamp 707020657 (line 844): sample csl file

The format of the csv file is:

sampleID, timestamp, sensorName (GPS), time, lat, lon, speed, course.
sensorName (FL), gyroX,gyroY,gyroZ,acceX,acceY,acceZ,rotaX,rotaY,rotaZ,
sensorName (FR), gyroX,gyroY,gyroZ,acceX,acceY,acceZ,rotaX,rotaY,rotaZ,
sensorName (BL), gyroX,gyroY,gyroZ,acceX,acceY,acceZ,rotaX,rotaY,rotaZ,
sensorName (BR), gyroX,gyroY,gyroZ,acceX,acceY,acceZ,rotaX,rotaY,rotaZ,

And here a chart of the test quake:


Testing MPU-6050 with Node.js and Websockets

After setting up and testing the hardware we need to get going on the software side of the measurement setup.

We decided that each of our four MPU-6050 sensors gets its own RPi (Model B) for sensing the accelerometer and gyroscope data. These samples get directly transferred to a Server-RPi (Model 2-B) where they receive a timestamp and are stored for later use. As a protocol we keep it simple and use websockets for the beginning. We are going to switch to a UDP protocol if the network delays get problematic.

Node.js library for the MPU-6050 sensor

Fortunately there are npm-packages for our sensor out there, let’s try to install them:

  • npm mpu6050 (didn’t compile)
  • npm i2c-mpu6050 (worked!)

Using the example code in the i2c-mpu6050 package provided sensor data with ~35 Hz. After hacking around a bit it went up to ~46Hz. As we don’t need the temperature provided in the package’s regular index.js we uncommented those code lines and got a sensing frequency of ~55Hz (RPI Model B) which should work for us (if the car drives max. 160km/h we still have a sample at least every 80cm). With a RPI 2 we would get ~76Hz.

First sample data

To get a first idea of the sensed data, the delays and if a quake of the underground can be seen in the data we did put 4 RPis with sensors on a common ground and shaked it (by knocking) 5 times while sensing with 55 Hz and sending the data to our server. Here are first results:



With a sensing frequency of 55Hz a difference between the timestamps up to 18ms is regular.

Size of stored data

The data volume we produce and need to store for 4 sensors with 55Hz is ~100MB per hour, thus our class 6 SD card should be able to manage that.

Testing the hardware of our road quality measurement setup

Not only the first bit of hardware arrived but also the second (long USB power cables) so now it’s testing time: Overall power consumption, capacity of the battery packs/power banks and voltage drop for the long USB power cables.

Hardware setup (car)


Overall power consumption

In theory our test setup should consume:

  • each of the 4 RPi-B should consume max. 700mA + 50mA (GPIO) (5V; 3.75W)
  • RPi-2B max. 800mA + 50mA (GPIO) + 80mA (GPS sensor/USB) (5V; 4.65W)
  • Switch (D-Link DGS-1008D) max. 7,5W
  • overall: 4 * 3.75 W + 4.65W + 7.5W = max 27.15W

Testing(1) the overall power consumption:

  • idle: ~19W
  • 100% CPU: ~25W

(1) testing device: SilverCrest model 9149

Battery pack capacity (powering RPis)

Unfortunately our battery packs(2) can not be charged and provide power to consumers at the same time. But as a fully charged pack was able to power two RPi-B(5) for 7h 15min before indicating low battery they are suitable for our test scenario (sensing road quality for a period of a couple of hours).

(2) TP-LINK TL-PB10400 Li-Ion 10400 mAh
(5) both RPis were sensing and transmitting sensor data with 50Hz through websockets continuously

Powering a RPi with a long USB cable (voltage drop)

A possible problem mentioned in my last posting (Choosing a test setup) is the voltage drop over long USB cables for powering our RPis. The RPi specifications require a voltage of 4.75V to 5.25V. Even with short cables (30cm) of bad quality we measured only 4.64V between TP1 and TP2 on our RPis. To avoid an even bigger voltage drop in long cables we ordered high quality 28/21-AWG-cables(3) with a range of 1.8 and 3m. Lets see what the multimeter(4) thinks about our purchase:

cable type voltage (TP1/TP2) RPI model power supply
noname 30cm cables 4.64-4.89V Model B USB charger (A3H10)
3m 21/28AWG 4.98V Model B USB charger (A3H10)
1,8m 21/28AWG 5.00V Model B USB charger (A3H10)
cable type voltage (TP1/TP2) RPI model power supply
noname 30cm cable 4.63V (1A socket)
4.88V (2A socket)
Model B battery pack
3m 21/28AWG 4.85V (1A socket)
4.96V (2A socket)
Model B battery pack
1,8m 21/28AWG 4.88V (1A socket)
5.02V (2A socket)
Model B battery pack

Awesomely, the longer cables provide even higher voltage (due to the smaller cable diameter) than the short ones, mission accomplished!

(3) Anker cables:
(4) Laudmann LM-800 multimeter

All in all the hardware fits our needs. A first test of our measurement software will follow very soon here on this blog.

Choosing a test setup for our road quality measurement project

The goal of the RoadStar project is to measure and evaluate the quality of the road surface automatically through crowdsourcing. Therefore we need to choose a mobile sensor setup which will be implemented inside a car.


As the GPS accuracy lies within a few meters we will only use a single GPS sensor per car to locate the measurements.

To gain data about the quality of the road surface itself we could either use one sensor per wheel (thus 4), one per side (thus 2) or just one per car. We are going to start with 4 sensor to see if we gain more useful information this way or if e.g. the back wheels would mostly provide redundant information of the front wheels.

Those sensors will be connected to the I2C bus of a Raspberry Pi (RPi). Our top candidate sensor (MPU-6050) has two possible device address (0x68/0x69), thus we can connect two to the same RPi without multiplexing (option 1) or each separately to its own RPi (option 2). As I2C is designed for low range we will probably run into multiple problems with option 1 if the cable gets too long: With a capacity higher than 400pF we need to lower the frequency or use a I2C expander and also add pull-up resistors. In addition, we might face voltage drops. With a separate RPi per sensor (option 2) we can keep the I2C wiring to a minimum. Now we need to check if the RPis have to be synchronized or if we can simply send the sensor data in real time to a center (server) RPi – but for that the delays or transmitting the data must not be as identical as possible for all RPis.

(see next posting regarding the delay of websocket in our test scenario)


The on-board power socket of a modern car delivers 12 volt with (normally at least) 8 amps of current. We use RPi Model B and RPi 2-B which both use not more than 4 watts, thus a setup with multiple RPis connected through a switch (~5 watts) should easily be able to be powered.

Checkout the results of us, Testing the hardware of our road quality measurement setup!