Using the HC-06/HC-05 Bluetooth Adapter For Serial Communication With Linux

Normally when I want to send data from a micro-controller to my computer I use a USB-Serial TTL adapter like one of these:

Thus type of adapter has always been perfect for my needs up until recently when I had a breadboard circuit on the end of of a rotating stick like this:


Using wires was pretty much out of the question so I needed a way to wirelessly send data from the breadboard circuit back to my computer. It turns out I had a hc-06 lying around that I had never used before so I decided to give it a try. In the process I figured out how easy these bluetooth-serial modules are to use and how easy they are to access using Linux.

Breadboard circuit with Teensy 3.6, HC-06 Bluetooth Adapter and 9DOF IMU


The HC-06 only has 4 pins. RX, TX, GND and VCC so just connect the power pins and connect the RX and TX on the module to the RX and TX of your micro-controllers serial port.

HC-06 Serial Bluetooth Adapter


I’m using Fedora at the moment so I will show the specific instructions for that operating system but the steps will be similar enough for most other linux distributions. First step is to find the MAC address of the HC-06. In Fedora , go to Settings > Bluetooth.


Fedora Bluetooth Settings

The HC-06 shows up as “Linvor”. Clicking on it brings up this window:

Copy and paste the MAC address into a notepad to save for later use. Initally I tried to connect to the device by clicking on the connection button in the image above which briefly connects and then disconnects about 5 seconds later. There is another method to connect using the MAC address as I outline here.

This is where using Linux makes things nice and easy. You can bind the MAC address to a serial port using this command :

Replace the MAC address with your one.

This will create a serial port , most likely called /dev/rfcomm0 (unless you have another rfcomm device already created in which case it might be rfcomm1, 2 etc.)

To connect to the port, you can use whatever program you normally use to connect to a serial port. It could be a python script or something like Minicom or picocom etc.

To connect using Picocom the command would be:

Once you run this command the light on the HC-06 will go from blinking (which means not connected) to solid red (which means it is connected) and you have a bluetooth serial link.

This is a really handy thing for quickly sending data from any microcontroller back to a computer. The fact that the bluetooth link shows up like a normal serial port and without too much faffing around is what makes this great.

Posted in Microcontrollers | Tagged , , , , , | Leave a comment

OpenWave #7 : Displacement measurement results – peak detect vs zero crossing

This post will detail an experiment in which the wave sensor was attached to a rotating arm at three different diameters. These diameters were 40cm, 60cm and 80cm. For each diameter, measurements were taken at two speeds to get an idea of how rotation frequency affects measurement accuracy. This gives a total of 6 sets of data.

The speeds will be referred to as speed 1 and speed 2. With speed 2 being around 1.5 to 2 times faster than speed 1.

Two seperate methods of resetting the integration counter were used and compared. The first is detecting the peaks of the acceleration signal using this to reset the integration, the second method is using the zero crossings as the reset point.


Zero crossing method:

Speed 1:

Actual(cm) Measured(cm) %Error
40 40.97 2.42%
80 81.67 2.09%
60 62.59 4.32%

Speed 2 :


Peak detect method:

Speed 1:

Actual(cm) Measured(cm) %Error
40 39.14 2.15%
80 82.24 2.8%
60 58.64 2.27%

Speed 2:

Actual(cm) Measured(cm) %Error
80 77.57 3.04%
60 60.76 1.27%
40 38.62 3.45%

The results are very encouraging. In particular it was interesting that the zero crossing method provides results very similar to the peak detect method of integration reset. Zero crossing would be the preferred method for an embedded system because it takes much less processing power to detect zero crossings compared to peaks.

Posted in Uncategorized | 4 Comments

OpenWave #6 : Getting vertical displacement working

In post #5 I outlined the steps used to go from vertical acceleration to vertical displacement and how the results were completely off. I think I’ve figured out what was going wrong. The reason why each of the displacement graphs at the end of the post look so totally different just by changing the integral reset points is because of a negative offset to the velocity signal. I think of it as a negative DC offset, as in the average value of the signal is not zero. This causes huge problems when you go to integrate the signal. Lets take a look at the vertical acceleration signal again:

Z-axis acceleration signal

You may notice that there is a negative offset of somewhere around -0.15 or thereabouts. I was actually correcting for this because without the correction, the first integration to obtain velocity goes completely mad. So I was offset correcting this z-axis acceleration and then double integrating to get displacement. This was the cause of all of my issues. It turns out that even if I offset correct the acceleration signal, the velocity signal may still have an offset present in it. If it does have an offset and you integrate again to get displacement, the displacement is totally off.

Lets take a look at an example graph with which does not offset correct the velocity signal before integrating to get displacement:

The blue vertical lines indicate the seperate chunks of data, with everything being split based on the minima of the acceleration signal. You may notice that the velocity signal has a slight positive bias. When this signal is integrated to get the bottom graph of displacement, the displacement starts at zero but does not return to zero as you would expect as the rotating arm is rotating in a circle.

Now lets take a look at the graphs when you do offset correct before each integration step:

Displacement with offset correction of acceleration and velocity

This plot finally makes some sense, and to make things better, the average displacement for the 5 chunks of data is 41.7cm. This measurement has an error of 4.25 %. The results from offset correcting are very encouraging but more testing needs to be done to verify that this hasn’t been a lucky one off where the end result happens to match the expected displacement of 40cm. I’ve drilled extra mounting holes into the stick at a radius of 20cm, 40cm and 60cm. I’ll repeat the above experiment for each of those heights to verify that the process actually works.

Posted in Uncategorized | Leave a comment

OpenWave #5 : The displacement calculation problem

In this post I will go into detail about the steps I’m currently using to go from vertical acceleration data from the IMU to vertical displacement and the issues I’m having.

Step 1: Getting acceleration data

The first step is to setup the rotating arm with the IMU attached, rotate it for a fixed amount of time, say 60 seconds and capture the raw linear acceleration data for the z-axis which is the vertical axis. See below video for an example of the rotating arm.

Note that this video is just an example of the arm rotating. All of the data used in this post was obtained with the arm set to a 40cm diameter and a rotation speed of approximately 0.2Hz. The recorded z-axis acceleration data looks something like this:

Step 2 : Filtering acceleration signal

As it is, this signal is too noisy to work with and so it is first filtered before any other signal processing steps occur. The low-pass filtered signal is shown in orange below:

Step 3 : Peak detection

Now that we have a relatively smooth signal to work with, peak detection is relatively simple. The orange x marks on the graph below mark the peaks and troughs of the signal.

Step 4: Break signal into chunks and double integrate each chunk

These peak detection points are used to break the signal into chunks where each chunk is separately integrated twice to go from acceleration chunks to displacement chunks. The displacement chunks can then be graphed which looks like this:

Note that I’m using dots to represent the points instead of a continuous line so you can actually see the separate displacement data chunks. Another issue is that the way in which the signal is broken into chunks drastically affects the end result. The above image was obtained by detecting the minima and maxima and breaking the signal into chunks at those points. If you break the signal at just the minima you get the following displacement graph:

Displacement obtained by resetting integration at minima

By using the maxima to reset the integration you get this graph:

Remember that the actual arm diameter was 40cm so we should see a maximum displacement of 40cm. Take the above image for example. The first blueline on the left goes from approximately 0.2m down to -0.5m which is a total displacement of 0.7 meters. The rightmost blue line is a better example of what I’m looking for. It goes from 0.2 down to -0.2 which is exactly what the expected result would be. I’ll do some more testing over the next few days to try and narrow down what the problem is. It may just be that the accelerometer itself has quite a lot of drift even with the short integral reset periods.

Posted in Uncategorized | Leave a comment