Debugging Bluetooth LE Device Using bluetoothctl Tool Under Linux

First of all don’t bother with hcitool and hciconfig tools. They are deprecated. Use bluetoothctl to connect and test your Bluetooth LE devices. It’s an interactive command line utility that provides a convenient interface for testing and probing your devices. Here is a short introduction on how to connect to a LE device that implements “Health Thermometer Service” over GATT profile.

First, start the bluetoothctl tool. It starts as an interactive session, so rest of the commands will be entered into its prompt which appears like this:

[bluetooth]#

You can enter “help” command to see a list of usable commands.

Enter “scan on” command to start the device discovery. This should print something like this if it finds your device:

[CHG] Controller E8:2A:EA:29:3E:6F Discovering: yes
 [NEW] Device 00:61:61:15:8D:60 Thermometer Example

To connect to the device use the “connect” command like this:

connect 00:61:61:15:8D:60

By the way, you can use TAB completion to quickly enter IDs, addresses etc.

This should print a success message and list the device characteristics right after that. In my case I had this response, but it will change depending on your device. By the way I’m using an example project that came with my Silabs bluetooth development kit.

Attempting to connect to 00:61:61:15:8D:60
 [CHG] Device 00:61:61:15:8D:60 Connected: yes
 Connection successful
 [NEW] Primary Service#
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service0001
 00001801-0000-1000-8000-00805f9b34fb
 Generic Attribute Profile
 [NEW] Characteristic
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service0001/char0002
 00002a05-0000-1000-8000-00805f9b34fb
 Service Changed
 [NEW] Descriptor
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service0001/char0002/desc0004
 00002902-0000-1000-8000-00805f9b34fb
 Client Characteristic Configuration
 [NEW] Primary Service
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service000a
 0000180a-0000-1000-8000-00805f9b34fb
 Device Information
 [NEW] Characteristic
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service000a/char000b
 00002a29-0000-1000-8000-00805f9b34fb
 Manufacturer Name String
 [NEW] Primary Service
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service000d
 00001809-0000-1000-8000-00805f9b34fb
 Health Thermometer
 [NEW] Characteristic
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service000d/char000e
 00002a1c-0000-1000-8000-00805f9b34fb
 Temperature Measurement
 [NEW] Descriptor
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service000d/char000e/desc0010
 00002902-0000-1000-8000-00805f9b34fb
 Client Characteristic Configuration
 [NEW] Primary Service
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service0011
 1d14d6ee-fd63-4fa1-bfa4-8f47b42119f0
 Vendor specific
 [NEW] Characteristic
 /org/bluez/hci0/dev_00_61_61_15_8D_60/service0011/char0012
 f7bf3564-fb6d-4e53-88a4-5e37e0326063
 Vendor specific
 [CHG] Device 00:61:61:15:8D:60 UUIDs: 00001800-0000-1000-8000-00805f9b34fb
 [CHG] Device 00:61:61:15:8D:60 UUIDs: 00001801-0000-1000-8000-00805f9b34fb
 [CHG] Device 00:61:61:15:8D:60 UUIDs: 00001809-0000-1000-8000-00805f9b34fb
 [CHG] Device 00:61:61:15:8D:60 UUIDs: 0000180a-0000-1000-8000-00805f9b34fb
 [CHG] Device 00:61:61:15:8D:60 UUIDs: 1d14d6ee-fd63-4fa1-bfa4-8f47b42119f0
 [CHG] Device 00:61:61:15:8D:60 ServicesResolved: yes
 [CHG] Device 00:61:61:15:8D:60 Appearance: 0x0300

To get the list of characteristics you can use the “list-attributes” command, which should print the same list as above:

list-attributes 00:61:61:15:8D:60

To read an attribute you first select it, with the -you guessed it- “select-attribute” command:

select-attribute /org/bluez/hci0/dev_00_61_61_15_8D_60/service000a/char000b

After that you can issue the “read” command, without any parameters.

To read a characteristic continuously (if characteristic supports it) , use the “notify” command:

notify on

This should periodically print the characteristic value sent from the device. To stop run:

notify off

And disconnect with the “disconnect” command. So easy.

 

Hide Distracting “Hot Network Questions” on StackExchange (StackOverflow etc) sites

I’ve created a greasemonkey script to hide rather distracting “hot network questions” section on stackexchange sites. You have no idea how much of my time is lost to that innocent looking list. It is possible that it damaged my productivity more than reddit did!

This script will add a “hide/show” button to turn it on, in case you want to be distracted.

Get it here.

Using ARM Cortex-M SysTick Timer for Simple Delays

ARM Cortex-M based microcontrollers has an included system tick timer as part of the core. It’s generally used as the tick timer of a RTOS. Hence the name “SysTick”. It’s also relatively simple and lacks advanced features.

  • Only counts down
  • 24 bit
  • Auto-Reload register
  • Dedicated interrupt
  • Calibration value for interrupt period
  • Can use system clock or an external clock (*)
  • No input capture, no output compare, nothing fancy

(*) Implementation of SysTick timer somewhat varies between manufacturers. So make sure to check the documentation. In STM32F4 this external clock is the processor clock divided by 8. You can find more information in STM32F4 Programming Manual PM0214.

Here are the registers used to configure systick timer.

  • CTRL : configure systick timer, select clock source, enable interrupt, check countdown hit
  • LOAD : auto reload register, after hitting 0, count (VAL register) is reset to this value
  • VAL : current value register
  • CALIB : calibration register, only relevant for interrupts

Below is a function that delays by a given number of ticks.

void delay_ticks(unsigned ticks)
{
    SysTick->LOAD = ticks;
    SysTick->VAL = 0;
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;

    // COUNTFLAG is a bit that is set to 1 when counter reaches 0.
    // It's automatically cleared when read.
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
    SysTick->CTRL = 0;
}

By default the timer is configured to use system clock divided by 8. With a system clock of 84MHz, timer input is 10,5MHz which corresponds to a 0,095µs~=0,1µs tick period. For example calling this function with ticks=105 would result in a 10µs delay.

Let’s write functions that accepts microseconds and milliseconds as parameters.

static inline void delay_us(unsigned us)
{
    delay_ticks((us * (STM32_SYSCLK / 8)) / 1000000);
}

static inline void delay_ms(unsigned ms)
{
    delay_ticks((ms * (STM32_SYSCLK / 8)) / 1000);
}

Since these are very simple one liners, it makes sense to put them in a header file as inline functions so that compiler can optimize them, including the multiplication and divisions. Note that STM32_SYSCLK is a define for main system clock frequency, in my case 84000000. Its naming can change depending on the platform/libraries you are using.

Embedding Python in C#

Disclaimer: I don’t know C#. Take any line of code you see below with a grain of salt.

I have developed a USB based device. Now I have to provide a driver for it to the client (actually another developer team). Device is actually based on USB UART but we have a slightly complex protocol running over it, so I had to develop a library for interfacing. I did create one in Python. It wasn’t terribly hard, thanks to an awesome python library.  But the client team work in C#. I couldn’t find a similar library for C#, and we are short on time. I know idea of embedding a binary parser/serializer written in Python into a C# library sounds awful but this is a prototype anyway so…

This is my story of embedding Python into a C# application, using Mono. I got confirmation from a friend that this also works on Visual Studio based projects.

First thing first, we are not embedding the regular Python implementation called CPython into C#. Instead we will use another Python implementation called IronPython. This python implementation is identical to the original one from a language perspective. But its designed to be integrated into the .NET platform. It can make use of .net libraries but there are also disadvantages. For example you can’t use a python library if it makes use of C libraries. Also there is only 2.7 version. If your python code makes use of Python 3 only modules or modules that have C library dependencies you better start looking alternatives to them.

Everything you need is included in the IronPython release package. Download it from here: http://ironpython.net/download/ and extract/install to your preferred location.

Create a new C# project. For this example I’m creating a console based project. Now add IronPython DLLs to your project. You can find these in the IronPython installation folder.

  • IronPython.dll
  • Microsoft.Scripting.dll

You will also need to add Microsoft.CSharp DLL to you project as well. In MonoDevelop this can be done from “References” window, “All” tab. I’m guessing its similar in Visual Studio (maybe not even required).

And here is a simple test code running python:

using System;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython;
using Microsoft.Scripting.Hosting;

namespace blog
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            ScriptEngine engine = Python.CreateEngine ();

            var result = engine.Execute ("2+2");

            Console.WriteLine (result);
        }
    }
}

This should be fairly simple to understand. Using Python.CreateEngine we are creating an instance of Python interpreter to run our code. And using Execute() method we are running a piece of python code and assigning its result into a C# variable.

Now lets do something a little more useful. We will run a script, and access variables from inside this script. For this we will need to use a ScriptScope.

using System;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython;
using Microsoft.Scripting.Hosting;

namespace blog
{
    class MainClass
    {
        const string program = @"
a = 3
b = 4
a = b*2
";
        public static void Main (string[] args)
        {
            ScriptEngine engine = Python.CreateEngine ();

            // create a ScriptSource to encapsulate our program and a scope to run it
            ScriptSource source = engine.CreateScriptSourceFromString (program);
            ScriptScope scope = engine.CreateScope ();

            // Execute the script in 'scope'
            source.Execute (scope);

            // access the variables from the 'scope'
            var varA = scope.GetVariable("a");
            var varB = scope.GetVariable("b");

            Console.WriteLine ("a: {0}, b: {1}", varA, varB);
        }
    }
}

Now lets try calling a python function from C#. It’s surprisingly easy.

using System;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython;
using Microsoft.Scripting.Hosting;

namespace blog
{
    class MainClass
    {
        const string program = @"
def sum(a, b):
    return a+b
";
        public static void Main (string[] args)
        {
            ScriptEngine engine = Python.CreateEngine ();

            ScriptSource source = engine.CreateScriptSourceFromString (program);
            ScriptScope scope = engine.CreateScope ();

            source.Execute (scope);

            // get the function from the python side (remember functions are
            // first class objects in python, you can refer to them like they 
            // are variables)
            var sumFunc = scope.GetVariable("sum");

            var result = sumFunc (2, 2);

            Console.WriteLine ("result: {0}", result);
        }
    }
}

Now lets import some python modules in our script. You will see that any module other than sys cannot be imported in python. That’s because IronPython instance that we embedded inside our application doesn’t know where its standard libraries are. But they are right next to DLLs inside the directory named “Lib/” you will say.. Still, it doesn’t know about them. You have two options; either move those libraries into your applications running directory (not adviced), or let know IronPython where they are.

Important note: before running below example add IronPython.Modules.dll to your project as well.

using System;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython;
using Microsoft.Scripting.Hosting;

namespace blog
{
    class MainClass
    {
        const string program = @"
import os
print('running in %s' % os.getcwd())
";
        public static void Main (string[] args)
        {
            ScriptEngine engine = Python.CreateEngine ();
            var paths = engine.GetSearchPaths ();
            paths.Add("/home/heyyo/Apps/IronPython-2.7.6.3/Lib"); // change this path according to your IronPython installation
            engine.SetSearchPaths (paths);

            ScriptSource source = engine.CreateScriptSourceFromString (program);
            ScriptScope scope = engine.CreateScope ();

            source.Execute (scope);
        }
    }
}

If you need other modules for your script you should add their paths too using paths.Add().

That’s all for now. I plan to update this post as I discover more stuff in my adventure into the C# land!

Don’t use SessionAsync

If you are trying to write a Cinnamon extension/applet and having this error when trying to parse some data that you have fetched via Soap.SessionAsync:

Failed to convert UTF-8 string to JS string: Invalid byte sequence in conversion input

Using Soap.Session instead of Soap.SessionAsync may solve your problem.

I’ve encountered this problem when working with StackExchange API which always returns data in compressed format regardless of request headers. It turns out Soap.SessionAsync doesn’t automatically decode data according to its encoding headers. You have to initiate decoding explicitly.

Or you could just use Soap.Session which handles decoding as you would expect.

I’ve wanted to write this because due to historic reasons all of the -already small number of- Javascript Soap library usage examples is written with SessionAsync class. For simple purposes though Session class can be used which is capable of handling both synced and asynced requests.

 

Patching a Debian Package

This is my experience on patching a debian package. Once you learn how to do it, its so simple and straightforward I wanted to demonstrate.

Problem

I develop an application named SerialPlot. It’s programmed with Qt SDK. It makes use of QSerialPort module of Qt for accessing the serial port devices. When I updated my system to Linux Mint 18 which is based on Ubuntu 16.04, SerialPlot got broken. When you remove a USB based serial port device while it is still open in SerialPlot, application goes into a loop and finally crashes. After some investigation I determined this was an issue with the Qt 5.5 . Problem was already fixed in the next version of the Qt.

Solution

I don’t want to update my complete Qt installation. More importantly I didn’t want to force people to update whole Qt library, just for my application. So I decided to port the fixes back to the 5.5 version of the QSerialPort library. This library is distributed in a debian package named libqt5serialport5.

Gathering Requirements

Change to an empty directory. Because below commands will liter the place a little.

mkdir qtserialport-fix && cd qtserialport-fix

Downloading the build dependencies:

apt build-dep libqt5serialport5

Downloading the source package of the libqt5serialport5. Remember, before this step you should have enabled the source package repositories.

apt source libqt5serialport5

Installing some tools that are required to build debian packages:

apt install build-essential fakeroot devscripts

Making the Fix

Now you should have 1 directory and 3 files in your working directory.

qtserialport-opensource-src-5.5.1/
qtserialport-opensource-src_5.5.1.orig.tar.xz
qtserialport-opensource-src_5.5.1-2build1.debian.tar.gz
qtserialport-opensource-src_5.5.1-2build1.dsc

The file *.orig.tar.xz is the original source code.  *.debian.tar.gz file is the packaged debian source code file. *.dsc file is required to upload package to a debian repository. The directory should contain our source package and debian/ directory required to patch and re-build the debian package already extracted.

To patch a debian package properly we will use a tool named quilt. This is a tool specifically created to manage patches to debian packages.

Change into the source directory:

cd qtserialport-opensource-src-5.5.1/

First should apply all the existing (if any) patches.

quilt push -a

Now we create a new patch:

quilt new fix-resourceerror-on-close.diff

Add the file we want to change to current patch:

quilt add src/serialport/qserialport_unix.cpp

Now it’s time to open the file in your favorite editor and make the necessary changes. After you save your file, tell quilt about the changes.

quilt refresh

To finish patching, un-apply all patches:

quilt pop -a

Building the Package

To build the package just call:

dpkg-buildpackage

If build succeeds you should have one or more *.deb files in the parent directory as result. Now you can install your fixed package.

sudo dpkg --install libqt5serialport5_5.5.1-2build1_amd64.deb

What Next?

If you want to distribute your fixed package to others, next steps would be to upload it to a PPA (or a regular debian repository, if you have one). For this you should change the version of the package. This is done by changing the debian/changelog file. But I won’t get into the any more details.

Finally

Please note that this is not a tutorial. If you are going to do this, you should read about debian packaging. Debian wiki is a good place to start. Unfortunately good information is scattered around and it can take some time until you understand what is exactly going on. Good luck!

makestmlib is Now A Part of KiPart

makestmlib.py script hat I’ve introduced in a previous post is now a part of KiPart.

KiPart is a tool to automatically create KiCad symbols from CSV files. It has its own format for this but support for other formats can be easily added. So I did that.

You can install KiPart via pip. And here is the documentation.

Here is an example of how to use kipart to create a library file from Stm32CubeMx output;

kipart -r stm32cube -o stm32.lib pinout.csv

It’s that easy.

And unlike my makeshift solution, KiPart produces a nice looking output taking into account text sizes etc. I hope its useful to someone.

Table for Selecting STM32 F4 Timers

If you didn’t know already, STM32 F4 MCU’s can have a lot of timers. And not all of them are the same. Some are feature packed, some are 32 bits, some doesn’t support certain interrupt types. Even the most feature-full one may not have a specific function you need. In software you are free to choose any one of them you want for any purpose. But if you need timers for external IO, say for interrupt timing, pwm measurement, pwm generation etc, you have to be careful when designing your hardware layout. Because not all the timers are the same and you can connect a timer to certain pins only. Sometimes you may have 2 different pins to choose, but thats about it.

So I’ve created a table to make it easier to select timers during hardware design. This table is prepared from STM32F4 reference manual (specifically manual for STM32F405/415, STM32F407/417, STM32F427/437 and STM32F429/439 series: RM0090). Note that this information may not be valid for all STM32F4 chips. Some information may be incorrect even. Please be cautious and check your reference manual as well.

TIMER # TIM1 TIM8 TIM2 TIM5 TIM3 TIM4 TIM9 TIM12 TIM10 TIM11 TIM13 TIM14 TIM6 TIM7
Resolution (bits) 16 16 32 32 16 16 16 16 16 16 16 16 16 16
Prescaler 16 16 16 16 16 16 16 16 16 16 16 16 16 16
Count Up
Count Down
Count Up Down
Input Capture
Output Compare
PWM
One Pulse
# IO Channels 4 4 4 4 4 4 2 2 1 1 1 1
Complementary Outputs
Sync Circuit
Interrupt (Counter overflow)
Interrupt (Counter underflow)
Interrupt (Counter Initialization)
Interrupt (Trigger)
Interrupt (Input Capture)
Interrupt (Output Compare)
Interrupt (Break Input)
Trigger Input
Driving DAC
DMA trigger (counter overflow)

You can download a slightly better looking version (PDF) of this table here.

Here is the source (ODS) file. You can open it with Libre Office Calc.