Sync’ing blood glucose data over Bluetooth to HealthKit

The code for this project is on my GitHub (here).

While newer blood glucose monitors (BGM) have Bluetooth capability (BLE), they are often designed only to sync data to their own clouds. Many applications call for mixing glucose measurements with data like weight, activity, carb consumption from other apps to enable consumers themselves, coaching, or care teams to use the information directly.

This code pulls glucose measurements from a BLE-enabled BGM and stores in:

  • HealthKit. Many apps and EHRs have HealthKit integration and can use HK as a channel to import glucose data.
  • Open format. Developer can integrate into other database systems.
HealthKit result

The code was developed using a Contour Next One BGM since it was found in a study published by the Diabetes Technology Society to be the most accurate of the set of 18 BGMs tested and one of the few to meet the FDA accuracy standard for glucometers.

The Bluetooth Forum developed a standard “GATT” profile for BGMs. Details can be found here.

Reads from the BGM are performed via its “Record Access Control Point (RACP)” characteristic. The code writes to RACP requesting data from the Bluetooth Glucose Measurement and Glucose read more

Read More »

Blood Glucose Meter tear down: Contour Next One

A recent study by the Diabetes Technology on a cohort of 1000 people found that of 18 popular glucometers in the US, only 6 met the FDA standard for accuracy:

Investigation of the Accuracy of 18 Marketed Blood Glucose Monitors. David C. Klonoff, Joan Lee Parkes, Boris P. Kovatchev, David Kerr, Wendy C. Bevier, Ronald L. Brazg, Mark Christiansen, Timothy S. Bailey, James H. Nichols and Michael A. Kohn. Diabetes Care 2018 Aug; 41(8): 1681-1688.

and another good study on accuracy here: Performance Evaluation of Three Blood Glucose Monitoring Systems Using ISO 15197

I was surprised by 2 things:

  1. Of course that only 6 BGMs met the standard….
  2. The FDA standard itself which specifies accuracy of only +- 15mg/dL at or below 100mg/dl and +-15% above that number. If your fasting blood glucose was measured at say 95mg/dl, that could mean to a 95% confidence level you are anywhere from 80mg/dl (relatively close to hypoglycemia) to 110mg/dl (pre-diabetic).

I decided to take a look inside the best scoring BGM: Contour Next One. Basically it looks like this:

PCB top side

Top side features a simple connector housing for the strip insert, a Toshiba custom analogue front end and an MCU.

A decap of the MCU reveals that it is from Renesas and is likely a R5F51135ADLJ (128KB ROM flash, 32KB RAM, 8KB data flash). This is based on Renesas’ proprietary RX CPU architecture read more

Read More »

Heart and respiration rate detection during sleep…. going balistocardiography!

As you sleep, the motion of the heart beat and resulting surges of blood around the body cause the body and bed to shake. Just a bit, but enough to detect with a MEMs accelerometer like the orientation sensor in your phone as well as in step counting fitness trackers. A good paper on the subject is here:  NIH paper

You can use this effect to detect heart rate, respiration rate, heart rate variance (a good measure of stress) as well as sleep/wake times; all while you sleep without needing to wear a device. This is key since to collect sleep data over months/years, it is important that the process be transparent to the user; just tape the sensor to the edge of the mattress and forget about it.

This approach has been studied for 100 years and has been made practical by emergence of cheap, sensitive technologies like MEMs. Joonas Paalasmaa’s (co-founder of Beddit – acquired by Apple) paper on the subject “unobtrusive online monitoring of sleep at home” is here on Pubmed

Heart rate, read more

Read More »

Pulling Nokia Withings health data API via OAuth1.0

Withings Nokia have a set of connected health devices which allow you to track your activity, blood pressure, weight, fat mass, temperature, sleep etc.

The dataset is available via a set of APIs. Authorization is via OAuth1.0
I put together a Python class library for the authorization steps and data access for use as a module in an Alexa project on Lambda. The code is on GitHub here.

Read More »

Custom Bluetooth Low Energy board with 2.4GHz antenna hack and Nordic nRF51822…

I wanted to experiment with Bluetooth Low Energy:

  • Can you hack together in your garage an antenna and RF section that will work at 2.4GHz?
  • If it works, who good/bad will it be?
  • What is hand soldering QFN packages like? Many BLE devices are only available in CSP or QFN48.

If you want to make IoT and Wearable devices that can be controlled from your phone/tablet/whatever, ZigBee is a neat mesh networking technology; but it’s not in any phones. Bluetooth (and more recently) Bluetooth Low Energy is in all of them. It’s easy to write a BLE control app write yourself using the Cocoa frameworks or download one like the excellent LightBlue for iPhone:

Read More »

Decoding PWM using cross-coupled timers on the STM32F372

The STM32F1xx has some neat features that allow you to cross-couple timers in interesting ways.

In the last post on timers, I synchronized 2 timers by using a master-slave configuration where the master resets the slave on every cycle. This time I use 2 cross-coupled channels of one timer in order to measure a PWM train frequency and mark:space ratio.

The trick to measure PWM is to use one counter to measure the period and the second to measure mark time, the latter reset by the first period counter on every cycle:

PWM

Here’s how it works:

  • The pulse train is applied to the pin of Timer 1 channel 1 (T1C1)
  • T1C1 edge detector outputs rising and falling edge signals as shown below.
  • The MUXs are cleverly designed so that you can use the edge signals from one channel
read more

Read More »

Timer, ADC and DMA autonomous data logging …. no CPU

This post pulls together the work from prior posts on the timers, ADC, DMA and GPIU for the STM32F372.

The idea is to get the MCU to do periodic ADC measurements and store the results away on its own without needing the CPU to intervene. This means no interrupts or polling, just the peripheral blocks working together on their own. This type of design is becoming more and more common in the low power world where the CPU and its subsystem is kept asleep, leaving the peripherals to do their job with the CPU only woken when some control needs doing.

The demo works like this:

ADC_DMA demo

Timer 2 is set up to produce a PWM train with a 5 second period. I use 2 channels in the same counter with the same mark:space ratio settings so that the first can drive the ADC whilst the second flashes an LED so that I know something is happening…

Timer2 has a nice feature where you can set it to send a Trigger Event at each Update Event (UEV). Here I set the UEV to be when the counter spills over the period read more

Read More »

PWM with synchronized Counter Timers and CortexM3 Systick

For this demo I used 3 of the counter timers on the STM32F372 to generate pulse trains of differing frequencies, made more interesting by adding 2 things:

(1) Chaining of timers using synchronization. Surprisingly, even when 2 timers driven by the onboard clock of the F372 are started at the same time, within 30 secs they have often drifted apart by as much as 500mS. This could be caused by differing path lengths on the SoC. The problem can be solved by using the on-board triggering mechanism which allows one timer to generate triggers that will drive another at selectable events. I used this feature to reset the second timer to the first on every cycle, thereby minimizing drift.
(2) Generating a periodic interrupt using the CortexM3 core SYSTICK clock. The SYSTICK clock only has a couple of configuration registers and is much simpler than the CTC Timers. Easy.

The programmers’ models for the timers used in the STM32F1xx and F37x series are similar. I guess ST reused the same IP blocks… There read more

Read More »

Using JTAG and Eclipse on MacOS

Though many eval boards come with an embedded JTAG-USB interface, I still like to use a separate purpose-built JTAG debug box.

If you pick the right one:

  • It can be used with many boards and SoCs. Once set up, one debug toolchain works for many projects.
  • You can use it to debug MCUs on bread-boarded projects. You will need to make a hacked SWD cable like the one I show in this post.
  • Not that expensive. I picked up a Segger JTAG EDU on a home-use deal for $60. I remember the early days at ARM when we first launched our “EmbeddedICE” box; the price then was over $1K….Today you can get some very cheap $20 knock offs from China on EBay and AliExpress. These may or may not work, but I believe it not worth my time to rely on dodgy tools with questionable software.
  • It works natively with Mac OSX. At least the Segger version does. I don’t need to run Fusion, Parallels or Virtual Box.
  • Does not require special USB drivers etc. The Mac version works by looking like a TCP device and speaking IP.
  • Supported directly under Eclipse. Again no special driver required
  • Supports SWD or full JTAG

(1) Connection to the target

The first thing you will need is a SWD cable. I made one out of some 20 core ribbon cable and a 20 pin IDC box connector. The ARM documentation on SWD pinouts is highly ambiguous since they talk about the pins to a “connector”. What’s a connector? Do they mean the plug (male) or socket (female)? I figured out the Segger pin out by using a Salaea Logic Analyzer:JTAG box end

Pin allocation

Segger setup

Breadboard connection

(2) Get the Segger software tools working

On a Mac, this is as simple as starting the JLinkExe terminal application in the Segger Application folder. Don’t try and use the JLinkGDBServer app from terminal.

If all is well, JLinkExe reports something like this:

STM32F100 segger

Note how JLinkExe switched automatically to SWD. This works most of the time, but not always. It depends on whether your target device is “known” to the box or not. If it is not known, you can fix this by read more

Read More »

STM MEMs pressure sensor, gyroscope and accelerometer hook up to ARM MBED

I used a header board for an STM MEMS evaluation kit in order to take a look at some common MEMS sensors:

  • LPS301: Pressure and temperature sensor
  • LG3D20: Gyroscope
  • LSM303DLHC: Accelerometer and magnetometer

The header was an STEVAL-MKI124V1 which is designed to work with an STM motherboard evaluation system. I took a shortcut and used it with an ARM MBED board featuring an NXP LPC1768 MBED.

Hook-up using I2C was trivial:

Screen Shot 2014-08-10 at 9.37.23 PM

The schematic for the evaluation board is here:

http://www.st.com/web/en/catalog/tools/PF253482

The orientation of the sensors on the board is like this:

Screen Shot 2014-08-10 at 9.38.10 PM

MBED-based code I write to drive the I2C is on the MBED website here

The code sets up each of the sensors and then provides a continuous output of temperature, pressure and orientation. Rather than optimize for performance or efficiency, the code here is intended to show clearly how to access the sensors.

An interesting twist was to use the linear accelerometer to find the vector of the earth’s gravitational field (i.e. down) and to use that to make a tilt-adjusted compass. Algorithm read more

Read More »

Breadboard breakout board for 48pin QFP STM32F100

Quick and simple project to make an adapter PCB to use a QFP packaged MCU on a traditional through-hole breadboard.

I ended up making a double-sided PCB to support 2 different QFP sizes. One side set up for 48 pins, the other for 32pins. Usage is to populate one side or the other, not both….

Screenshot 2014-08-13 17.56.56

Simple pin-out to two standard 24-pin headers. No on board components such as decoupling capacitors.

Here is the board in action on a breadboard and loaded up with a 48-pin STM32F100C8:

IMG_3872_safe

Eagle files for the board are on GitHub here.

Read More »

Cortex-M bring up. Post#2: this time with simple software infrastructure

I have found that basic example code from MCU suppliers is often too complex. Vendors want to write one example for their entire product range, so you often end up with a spaghetti of code and linker script that weaves in CMSIS, USB, drivers for fancy peripherals and whatever else. Even if you wanted to strip it down to basics, you would have to deal with multiple file dependencies in a web of directories that make the job harder than it should be.

For new board bring up, once I have shown sign of life using low level JTAG (see this post), the next thing I like is the simplest possible software set-up that I can get working.

Nice theory. Where do I download some code? I was surprised at how much I had to search to find anything useful. So this post has a simple example I made for a new STM32F100C8 board. It should work or at least help for many CortexM0 or M3 MCUs.

In the below diagram, the pieces of code we need to supply for this simple approach are in blue:

Screen Shot 2014-08-11 at 9.09.39 PM

There are countless read more

Read More »

Simplest Cortex-M bring up. Post#1: a no code approach

No Picture

Powering up a new board design or even skiing off-piste with an eval board without vendor-suppled code? This post shows a way to look for first signs of life without depending on working debug toolchain or working target software.

I use a Segger JTAG probe that I covered in a previous post.

Some recent eval boards like the one for Nordic Micro’s nRF51822 ship with an on-board USB debug connection that has a USB-JTAG decoder chip on board. This board uses the same Segger driver as their JTAG box embedded in the decoder, so the below approach should also work.

Segger JLINK application driver has a series of useful commands for examining directly addresses in memory:

  • mem          Read memory. Syntax: mem , (hex)
  • mem8        Read 8-bit items. Syntax: mem8 , (hex)
  • mem16      Read 16-bit items. Syntax: mem16 , (hex)
  • mem32      Read 32-bit items. Syntax: mem32 , (hex)

Since many MCUs have a factory-programmed ID register, you can use JTAG to read this value and check for signs of life.

To start with, I target a STM32F100C8. This MCU has a register at 1FFFF7E0 hex containing a 16-bit value with the flash size of the MCU. This is covered in the STM32F100 programming manual on read more

Read More »

Using MBED SPI to drive Analog Devices AD9850 frequency synthesizer

I was looking for a way to test the frequency response of a new oscilloscope.

Analog Devices has a nice IC that can produce a digitally synthesized sine wave of frequency between 0 and about 70 MHz. AD9850 link is here.

The quickest way to throw together a prototype was using an MBED platform. My code is here

What made things even easier was the availability of ready-to-go evaluation boards from China on Ebay for less than $5. This is the one I used.

This design is limited to about 40MHz if you want a clean signal without aliasing.

Frequency and phase are set by a 40-bit command that has:

  • 32-bit frequency setting
  • 5-bit phase setting
  • 1-bit power up/down
  • 2-bits factory debug access

MBED_SPI packet

Output frequency is given by: fOUT = (frq × CLKIN)/(2^32)

where frq is the 32-bit frequency and CLKIN is the frequency of the on-board crystal (125MHz in this case) So, for example 0x147AE148 is 10MHz.

Frequency resolution has a step size of 29KHz with the 125MHz clock.

You can also change phase in increments of 180°, 90°, 45°, 22.5°, 11.25° or any combination thereof using read more

Read More »

Simplest NSOutlineView Demo

No Picture

Most NSOutlineView examples I have seen are not that helpful since you spend time trying to figure out how the data model behind the example works rather than seeing how to use the framework itself. Yes, the data model is critical, however if you don’t understand the framework then you won’t be able to write a controller to feed the view or the model…

 So. I have tried instead to get started by boiling this all down to the simplest possible configuration.

Before the Memory Leak Police get on to me, the below is not written for memory management beauty but rather to demonstrate the framework; so, the reader is left to figure out the releases. I know I generate lots of objects…and also that I violate MVC….

But, can you make it simpler than this..?

Power up Interface Builder, drop an NSOutlineView into a window, hook up the delegates and outlets like you would for NSTableView. That’s it.

Here is what’s going on in the code.

In Method#1, I hard-wire the code to return that every node has 3 children. You can see that in the output below if you look under the nodes that have been expanded. You could put here any integer or function that returns one.

In Method#2, you have to return a pointer to a unique object for each of the children that you declared in #1. Normally you would ferret around in your data model to find the right object. Here I just generate a new empty object each time and return a pointer to it.

In Method#3 I hard wire-in that every node is expandable.

Finally in Method#4, I demonstrate a point from the last blog entry. You return the data that you want displayed according to with the object you returned from Method#2.

This data can be from within the Method#2 object itself or it can be something completely different, perhaps even completely unrelated to the Method#2 object. For example, you could just return the word “Hello” and have it appear at every node on the view.

I chose to get the address of the Method#2 object (also demonstrating that each object in the tree is unique) and to concat that with some text.

In the next post, a more complicated directory browser. This time with MVC.

Read More »

NSOutlineView: Part 1 Introduction

No Picture

Introduction

Outline views are great for displaying hierarchical data because they allow the user to drill down into the parts of the dataset that are the most interesting.

OutlineView Tree

A common place where they show up is in file handling windows. So. My last example in this column will be a directory browser. To build an outline view, all you have to do is create the view in Interface Builder, hook it up to your code and implement 4 specific delegate methods. Simple really.

It turns out that unless you try and understand some of what NSOutlineView does behind the scenes, the chances of actually hooking up your data right are remote… If you have a bug, what tends to happen is that you either get an exception/crash or nothing happens. And since much of the inner workings take place beneath the hood inside runtime, it’s not as if you can put a breakpoint inside the NSOutlineView to see what’s going on. It can take many NSLogs in your code to get some visibility.

Delegate Methods

You can think of delegate methods like the outsourcing of a task. When the outline view needs to know more about the data that you would like to display in the view, it simply calls the relevant “delegate” method and expects an answer.

These methods are the interface between your dataset and the onscreen view. At a minimum, NSOutlineView requires you to implement 4 delegate methods in your code. There are several other delegates that are strictly optional and which add more functionality to your outline view.

It’s easier to call the 4 compulsory delegates Method 1-4 instead of their full names; besides, this is the order in which runtime tends to call them anyway, so it’s a useful frame of reference.

Let’s dig in to how it all works.

Method#1

– (int) outlineView: (NSOutlineView *) outlineView numberOfChildrenOfItem:(id)item

This is the first delegate that runtime will call to populate your outline view. It asks the question: “For the node that you just clicked on to expand, how many children objects should I allow for?”

This method is only called on one of 2 occasions. Either:

  •  When the view is first displayed at start up and runtime needs to know the contents of the Root level of your data
  • When a node is expanded and runtime needs to start building the display of that node’s children.

Since these cases both happen relatively rarely, Method#1 tends to be called the least frequently out of the 4 delegates.

The next delegate methods #2 and #3 will be called the number of  times you specify in the number you return now. So, if you return “3” here, they will get called 3 times.

2 values are passed to this delegate by runtime:

  •  (NSOutlineView *) outlineView (or whatever you choose to name the view). This pointer is passed to you in all 4  delegates so I’m only going to bother to explain it once here. When you build an outline view in Interface Builder, you have the option of making a multi-column display. You could have 2 different outlines displaying in each column. To let you know which outlineview runtime is talking about, it sends you a pointer. For a simple 1 column outlineview, you can ignore this pointer.
  •  (id) item. This is a pointer to the object associated with the node that the user clicked on. For example, in the above diagram, when the user clicked on “Applications”, the pointer to item here would point to the object associated with Applications. There is one exception to this case and that’s at start up. When the view first displays data, runtime doesn’t know where the data that you want to display is, so it will pass you a null pointer in item. You can test for null to know when you need to return root level data. That’s what many implementations do.

So far so good I hope.

Method#2

– (id) outlineView: (NSOutlineView *) outlineView child:(int) index ofItem:(id) item

I find this is the most tricky delegate. 9 times out of 10 getting my data right for this delegate is the source of my NSOutlineView bugs.

This method says (for example) “In Method#1 you told me the node had 5 children. Give me now a pointer to the data object that you want to be associated with (say) child#3”

You return a pointer to the object that for that child.

Method#2 repeats this loop once for every child that you declared in your return from Method#1. So, if you returned “5” from Method#1, Method#2 will loop 5 times.

It is important to note that each child object of a node must be unique. In that way it’s like an NSDictionary key where each key can only appear once. This is obviously to make sure that there is no ambiguity as to which data object applies to which node in the view. If you do not return a unique object, weird and wonderful bugs will occur that may show up immediately or later after much lurking.

All you need to do is return a pointer to the object that you want to associate with the child node that the method is asking about.

Method#2 delegate passes you 3 pointers:

  •  An outlineView pointer as in Method#1.
  • (NSInteger) index. The number of the child under the node that is in question. If your data is stored in an array, then this integer can be used to reference sequential objects in that array.
  • (id) item. A pointer to the object representing the node in question. If we are dealing with Root, then again this will be null as in Method#1. This is the place where you return a pointer to the data object(s) that will represent the root data items. I show an example of this in the directory browser at the end.

Method#3

– (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item

Easy method. Simply asks “Is the data object that you returned in Method#2 expandable?” If it is, a disclosure triangle is drawn.

We have seen before both of the pointers that are sent to you. One thing to note is that the (id)item sent here may be different than the one in the prior Method#2. Assuming that they will be the same will be at your own great peril… that’s a hard bug to find (been there). Always trap it and check which item is being requested.

All you need to do is return a Boolean of yes or no.

Method#4

– (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item

Last method. Also easy.

“For the object pointed to by item, give me the data that you actually want displayed in the view.”

Subtle difference to Method#2. Method#2 asks you for a pointer to the object to associate with a node. Method#4 asks you for the actual data you want to display. That data doesn’t necessarily need to come from the Method#2 object as I will show in a minute. It could be any text, image or whatever you like. Equally, it could be a member of the object that you supplied to Method#2.

 Overall Flow and Performance

Now the we have covered the delegate methods, let’s delve into what goes on under the hood.

Delegates tend to be called in the order shown in the flowchart.

At the start, Method#1 is called for Root. Methods 2 and 3 are then called in pairs, once for each child node that was returned from Method#1 until the view is full. This is an important point. Runtime uses resources wisely and only asks about nodes for which there is space to display in the view. This saves you a bunch of effort since runtime figures out which nodes should be on the screen and which ones have scrolled out of view. The smaller the view, the lower the number of nodes that will fit in it. Nodes lower down only get called up when the user scrolls down in the view. If Root has 10 children but there is only room for 5 in the view, then Methods 2&3 will get called 5 times each.

Finally, Method#4 gets called once per node in the view. This method also gets called every time that the view needs to be redrawn, for example when the view’s window gets moved or when it gets revealed from behind another window.

When a node is expanded, things happen in a similar fashion, with Method#1 being called first for the expanded node to find out how many children it has.

As an experiment, I ran the directory demo from the end of this blog a few times and logged how many times each delegate method was called as I scrolled around and expanded random nodes. Averaging out the call stats and normalizing relative to Method#1 gave the below.

Apple’s doc makes the point that the 4 delegates get called a lot and that you should therefore take care not to bog them down with a lot of code. This is true, but clearly not all delegates are equal and some are called way more than others.

The performance of your delegate code matters, and it especially matters in Method#4.

Method#1 only gets called at start up and when a node is expanded. So, if you can move processing tasks from Methods 2-4, here is a good place to put it.

Method#4 gets called to set up the initial display of every item on the screen and then for every refresh. So, every time you move the view’s window, you resize it or that you cover the view up, Method#4 gets called a bunch of times to refresh the view. Therefore, your mileage will vary and the number of Method#4‘s that you get will too. In my experiment it was called ~4x more than Methods 2 & 3. So, it pays to keep the code in Method#4 as simple and as fast as possible.

Enough of the intro to NSOutlineView. Next time, the world’s simplest example code…

Read More »