Tag - Raspberry PI

Entries feed Comments feed

OpenCyclingComputer update

OpenCyclingComputer is finally reaching the "road ready" stage:

occ.jpg
OpenCyclingComputer, Sep 2018

What works:

  • BLE connection with heart rate sensor. Also automatic re-connection and graceful quiet handling of all errors from bluez stack.
  • BLE connection with speed and cadence sensor. It's really wheel revolution and cadence sensor, but given wheel size it works as speed sensor.
  • Pressure sensor. Iit will be used as an altimeter in the near future. Coded with Kalman filter
  • Temperature sensor
  • GPS module - I still need to do some debugging here, but the drivers were tested on raspberry A+ and worked great.
  • YAML layouts. It's very easy to change the default layout - it's simply a text file + some background images.
  • Saving / reading config file. Also YAML,  so it's a human editable.
  • "Animated" heart rate and cadence icons showing that the related sensors are "alive" and keep sending notifications.
  • All settings can be edited from the OCC screen

Things that need polishing:

  • Calculating averages (speed, heart rate, etc)
  • Implementing Kalman filters where suitable
  • BLE scanning and selecting devices from the OCC screen
  • Calculating altitude and all related parameters like slope, pressure at sea level and others
  • BLE status icon works, but it doesn't show exactly what's happening with the connection
  • Implementing Low Battery warning/shut down (hardware is ready)
  • Improving ride log. Currently the format of the log is hard coded

Code develpoment:

  • defining sensor API for future extensions
  • plugging accelerometer into the current system
  • implementing inertion+gps navigation with multi input Kalman filter
  • code cleaning and refactoring

Open Cycling Computer will be Pi Zero W based

Pi Zero W is the new brain of the Open Cycling Computer. PiTFT 2.8" capacitive dosn't work out-of-the-box, but required modification are very simple.

Modifications required in /boot/config.txt

1. Uncomment dtparam=spi=on

2. Add dtoverlay=pitft28-capacitive,rotate=90,speed=32000000,fps=20

Modifications required in /boot/cmdline.txt

1. Add after rootwait (the end of line) fbcon=map:10 fbcon=font:VGA8x8 logo.nologo

That's it! No other modifications are required.

P.S. 31-Mar-2017: Do not install adafruit kernel as it doesn't support bluetooth/wifi on Pi Zero W yet.

Bluetooth BLE, gatttool and (almost) all those numbers .... explained

It's a short guide to practical side of bluetooth LE using gatttool. How to read characteristics, turn on notifications and where to find more info about all those BLE numbers.

I was strugging for a while to read data from a BLE heart rate strap. It was working flawlessly with android apps, but I needed it to use it with raspberry pi and python. So, I had to dig a bit deeper under the surface of BLE. The results are below.

Prerequisites:

1. A computer with bluetooth v4.0 card or dongle

2. gatttool (part of bluez). Fedora users might have to compile bluez as there is no gatttool in bluez-5.23-1.fc21 bugreport: [1].

3. A BLE (bluetooth Low Energy, Bluetooth Smart) device - I use a Tacx heart rate belt [2]

An example command line session (red - important or info for later use, blue - value from previous steps, green - comment):

$ hciconfig
hci0:    Type: BR/EDR  Bus: USB
^^ hci0: that's our hci device
    BD Address: C4:85:08:06:9F:C7  ACL MTU: 310:10  SCO MTU: 64:8
    UP RUNNING PSCAN
    RX bytes:10243057 acl:34567 sco:0 events:5307 errors:0
    TX bytes:46612 acl:737 sco:0 commands:2685 errors:0

fedora-lan:/home/przemo
$ sudo hciconfig hci0 up
fedora-lan:/home/przemo
$ sudo hcitool -i hci0 lescan
LE Scan ...   <-- LE Scan was not showing anything, so Ctrl-C and hci0 reset
^Cfedora-lan:/home/przemo
$ sudo hciconfig hci0 reset
fedora-lan:/home/przemo
$ sudo hcitool -i hci0 lescan
LE Scan ...
D6:90:A8:08:F0:E4 Tacx HRB 04741
^^ D6:90:A8:08:F0:E4 that's BLE device address
D6:90:A8:08:F0:E4 (unknown)
D6:90:A8:08:F0:E4 Tacx HRB 04741
D6:90:A8:08:F0:E4 (unknown)

^Cfedora-lan:/home/przemo
$ sudo gatttool -i hci0 -b D6:90:A8:08:F0:E4 -t random -I
^^ if you can't connect try to use "-t random"
[D6:90:A8:08:F0:E4][LE]> connect
Attempting to connect to D6:90:A8:08:F0:E4
Connection successful

Reading velue of battery level characteristic
[D6:90:A8:08:F0:E4][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x0011 uuid: 0000180d-0000-1000-8000-00805f9b34fb
attr handle: 0x0012, end grp handle: 0x0015 uuid: 0000180f-0000-1000-8000-00805f9b34fb
^^^ 180f is "Battery Service", see link [3]
attr handle: 0x0016, end grp handle: 0xffff uuid: 0000180a-0000-1000-8000-00805f9b34fb
[D6:90:A8:08:F0:E4][LE]> characteristics 0x0012 0x0015
handle: 0x0013, char properties: 0x12, char value handle: 0x0014, uuid: 00002a19-0000-1000-8000-00805f9b34fb
^^ 2a19 is Battery Level, links [4] and [5]
char properties 0x12: supports NOTIFICATION 0x10 and READ 0x02 (0x10 | 0x02 = 0x12)

[D6:90:A8:08:F0:E4][LE]> char-read-hnd 0x0014
^^ Reading handle value
Characteristic value/descriptor: 64           
^^ value of battery level is 64, but it's hex, so 0x64 = 100. It's in %, link [4]
Reading heart rate
[D6:90:A8:08:F0:E4][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x0011 uuid: 0000180d-0000-1000-8000-00805f9b34fb
^^ 180d is "Heart Rate" service, link [3]
attr handle: 0x0012, end grp handle: 0x0015 uuid: 0000180f-0000-1000-8000-00805f9b34fb
attr handle: 0x0016, end grp handle: 0xffff uuid: 0000180a-0000-1000-8000-00805f9b34fb
[D6:90:A8:08:F0:E4][LE]> characteristics 0x000c 0x0011
handle: 0x000d, char properties: 0x10, char value handle: 0x000e, uuid: 00002a37-0000-1000-8000-00805f9b34fb
^^ 2a37 is Heart Rate characteristic, links [5] and [6]
char properties: 0x10: supports NOTIFICATION
handle: 0x0010, char properties: 0x02, char value handle: 0x0011, uuid: 00002a38-0000-1000-8000-00805f9b34fb
^^ 2a38 is Body Sensor Location, links [6] and [7]
char properties: 0x02: supports READ
[D6:90:A8:08:F0:E4][LE]> char-read-hnd 0x0011
^^ Reading Body Sensor Location
Characteristic value/descriptor: 01
^^ 0x01 it's "Chest", see link [7] for more options
We need more info to switch on NOTIFICATION of heart rate
[D6:90:A8:08:F0:E4][LE]> char-desc 0x000d 0x000f
^^ range of handles for heart rate: 0x000d is start of the range obtained with 'characteristics 0x000c 0x0011'
0x0010 is start of next characteristic minus 1: 0x0010 - 0x1 = 0x000f
handle: 0x000d, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 00002a37-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00002902-0000-1000-8000-00805f9b34fb
^^ 2902 it is Client Characteristic Configuration, link [8]
[D6:90:A8:08:F0:E4][LE]> char-write-cmd 0x000f 01
^^ 01 comes from link [8], NOTIFICATIONS enabled
Notification handle = 0x000e value: 00 3e        <-- heart rate, 0x003e is 63 BPM
Notification handle = 0x000e value: 00 3d        <-- heart rate, 0x003d is 62 BPM
Notification handle = 0x000e value: 00 3d        <-- heart rate, 0x003d is 62 BPM
Notification handle = 0x000e value: 00 3c        <-- heart rate, 0x003c is 61 BPM
[D6:90:A8:08:F0:E4][LE]> char-write-cmd 0x000f 00
^^ 00 comes from link [8], NOTIFICATIONS disabled
[D6:90:A8:08:F0:E4][LE]> disconnect              <-- end of connection
[D6:90:A8:08:F0:E4][LE]>
fedora-lan:/home/przemo/android

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1141909

[2] http://www.tacx.com/en/products/sensors/heart-rate-belt

[3] https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx

[4] https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml

[5] https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicsHome.aspx

[6] https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml

[7] https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml

[8] https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml

Python library for Raspberry PI for Ultimate GPS based on MTK3339 with serial interface as sold by Adafruit

https://github.com/PrzemoF/mtk3339

Python library for Raspberry PI for Ultimate GPS based on MTK3339 with serial interface as sold by Adafruit. The library helps to set different chip parameters in a sane way. Currently supports minimum functional set of commands:

CMD_HOT_START - hot_start()

CMD_WARM_START - warm_start()

CMD_COLD_START - cold_start()

CMD_FULL_COLD_START - cold_reset()

SET_NMEA_UPDATERATE - set_nmea_update_rate()

SET_NMEA_BAUDRATE - set_baudrate()

API_SET_FIX_CTL - set_fix_update_rate()

API_SET_NMEA_OUTPUT - set_nmea_output()

SET_NAV_SPEED_TRESHOLD - set_nav_speed_threshold()

All functions are preforming basic range check to make sure values areaccepted by MTK3339 as there is no check if a call was successfull or not.

Example usage:

import mkt3339

gps = mt3339("/dev/ttyAMA0")

gps.set_fix_update_rate(800)

gps.set_nmea_update_rate(800)

gps.set_baudrate(115200)

gps.set_nmea_update_rate(1000)

gps.set_nav_speed_threshold(1.5)

gps.set_nmea_output(gll = 0, rmc = 1, vtg = 0, gga = 5, gsa = 5, gsv = 5)

That library is part of Open Cycling Computer project

PiTFT capacitive calibration for vertical layout

PiTFT capacitive doesn't require calibration according to Adafruit, but for some reason I couldn't make it work properly with vertical layout and the default values suggsted here [1].

The default values are:

320 65536 0 -65536 0 15728640 65536

I needed to use the screen with Adafruit logo at the bottom [fbtft_device.rotate=90] and with the default /etc/pointercal values I had x axis swapped with y axis.

Explanation how the pointercal values works is here [2]. Some matrix math:

pointercal_equation.png

where:

x,y - the touchscreen coordinates returned by the kernel driver

a,b,c,d,e,f,s - pointercal values

u,v - the screen coordinates

The above equation converts to:

u = (x*a + y*b +1*c)/s

v = (x*d + y*e +1*f)/s

For the default values:

a = 320, b = 65536, c = 0 d = -65536, e = 0, f = 15728640, s = 65536

u = (x*320 + y*65536 + 0) / 65536

v = (x*(-65536) + y*0 + 15728640) / 65536

I wanted to flip x<->y, so

u = (x*(-65536) + y*0 + 15728640) / 65536

v = (x*320 + y*65536 + 0) / 65536

and now a = -65536, b = 0, c = 15728640 d = 320, e =65536 , f = 0,  s = 65536.

However when I tried to use those values in the pointercal file:

-65536 0 15728640 320 65536 0 65536

I found out that x axis is OK, but y axis is still flipped. To fix it we have to change sign of v and add a shift.

v = -(x*320 + y*65536 + 0) / 65536 +320

v = (x*(-320) + y*(-65536) +0)/65536 + 320

v= (x*(-320) + y*(-65536) +0)/65536 + 320*65536/65536

v= (x*(-320) + y*(-65536) +320*65536)/65536

v= (x*(-320) + y*(-65536) + 20971520)/65536

so d = -320, e = -65536 and f = 20971520

Proper pointercal values for vertical layout [fbtft_device.rotate=90] are:

-65536 0 15728640 -320 -65536 20971520 65536


Bosch BMP183 with SPI by Adafruit in python on Raspberry PI

How to measure temperature and pressure with raspberry pi and BMP183

Requirements:

- raspberry Pi
- BMP183 with SPI by Adafruit
- 6 wire female-to-female cable or any other to connect 6 pins between RPI and BMP183

Results:

Temperature: 18.9 deg C

Pressure: 1013.39 hPa

RPI + BMP183: rpi_a_and_bmp183.jpg

Schematic (png): rasperry_pi_and_bmp183_sensor.png

That entry is the first part of Open Cycling Computer project

Schematic (QElectroTech): rasperry_pi_and_bmp183_sensor.qet

BMP183 at Adafruit

All files on github

BMP183 datasheet