Wednesday, November 21, 2018

Standalone fitness band

I now have a MI Band displaying Glucose without a paired iPhone.  You just need the iPhone to push the calibration details to the device.

Lots to do here:
  1. Get the CC2500 code working on the Feather (SPI protocol)
  2. Get central to MI communication working.  Adapt what people have done in Python, to work on the Arduino.  See https://medium.com/machine-learning-world/how-i-hacked-xiaomi-miband-2-to-control-it-from-linux-a5bd2f36d3ad for a start.
  3. Also code the peripheral side so the feather can communicate with an iPhone, pushing the isig and retrieving the slope/intercept.
  4. Build the circuit
  5. Print a container
  6. Get a reasonable battery life


First started with everything on a breadboard, Feather NRF52 and a CC2500 board on a breakout.

Getting the CC2500 working wasn't too bad.  Only some question as the where the Chip Select/Slave Select pin was on the feather.  I recently found some mention that it was A8.  My code has it on A3, since I couldn't find where it was mapped initially.

Central to MI took allot of time, knew that going in.  To really understand what was going on, I had to get that working first in Python on a Raspberry PI.  This guy had a great script: https://github.com/vshymanskyy/miband2-python-test .  

Hardest part of the conversion is doing the AES 128 ECB encryption for the key exchange with the MI.  This reminded me of communicating with the Dexcom back at the start of this blog where you had to calculate a CRC.  In either case, there are lots of methods available, and lots of public implementations that may or may not work.  I probably tried 10...  In the end this did the trick.
Finally, very little out there for Central samples.

The peripheral side of things was tricky for me because of the way the iPhone caches BLE Characteristics.  For a couple of days, I could enumerate my new characteristics from Linux, but the phone, and xCode and light blue wouldn't show anything.  Turns out you need to restart your phone.
Modified my iPhone app to work with the new device and finally display the dexcom transmitter battery level.

With that, squeezed together a circuit:


I may do a PCB in the future, I don't trust the wires.  Also, would have been allot easier.  The connections on the CC2500 are very small, not easy to solder to.

And printed another box, 2.25 x 1.6 x 0.4 (inches)


First week, could only get 12 hours on a charge.  That works out to 9 ma/hr.  Broke out the current measuring apparatus and started watching things.  My initial central only sketch was hitting 9ma on pairing then settling down to 3ma, but the full code base was fluctuating between 9ma and 13ma after the first CC2500 receive event and refusing to drop below 9ma.  Hmm.
Did some desperation googling, found a Nordic post on how some low level errors will prevent the Microcontroller from ever entering low power mode.  A note here, you can run the NRF52 in debug mode and get some extra detail in the serial monitor.  In this case, I noticed a few unhandled error messages, that don't crash the micro, but they prevent low power mode.  An example of one, would be attempting to connect to a peripheral after you've already established a connection.  The central examples that come with the feather are prone to this...  Fixed these issues, battery life is now 3 ma/hr or lower.  Codewise, doesn't appear that waitForEvent has any impact on battery, delay does.
99% of the time, the device is at 2.5ma, the CC2500 uses 27ma for 2 seconds every 5 minutes, and communication with the MI costs 9ma for a few seconds every 5 minutes or much much less, since I don't send value every 5 minutes unless the current glucose level is a concern.

Nothing to be gained space wise, so no point going to a smaller battery, done.

Display is a bit small, and the regular notifications are cleared very quickly.  The real alerts vibrate until dismissed so you'll get to read those without issue.  Like the VivoSmart, I'm not displaying glucose in the traditional manner.  Example, if my blood sugar is in range, and not at risk of being high or low in the foreseeable future, nothing is sent to the band.  If I'm really paranoid I can always check on the iPhone.  Battery life on the MI is weeks.  You can also still connect to MI Fit to get your step counts, although I don't let it pair.

See my github for the code.  





Tuesday, October 23, 2018

BLE Dual Mode finally coming up

Started poking around at my many year old (and mostly useless) BLE Nano's.  Turns out they're supposed to be able to support S130.  After a few hours, gave up, and finally threw them out so I won't waste more time on them next year.

A little more googling, turns out Adafruit has a feather that does S130 (actually S132 in this case).
So...

Add this doo dad:

And I have a phone free CGMS, again.

So, with the Mi Band I can get custom notifications to it from Xcode, you can also send a notification that will make it buzz until you acknowledge, very cool.  Just have to convert all the Xcode for pairing etc. to Arduino land.  More on that later, much later.

Onto the hardware.  The feather can serve as Central to the Mi Band (ie. masquerade as a phone) and as peripheral to the iPhone.  It can be a casual relationship with the iPhone, where the phone is just a front end for calibrations, everything else lives on the feather, no phone, no problem.

Tuesday, September 4, 2018

Battery Replacement

After many years, I've finally managed to replace the batteries in a G4 transmitter.
Dying batteries is what compelled me to figure out the RF protocol years ago.  At the time my transmitter died just after 6 months, so a replacement wasn't covered by insurance.  There never was a warning from the device.

Over the last few weeks I've watched the battery level run down to where it dipped from 212 to 210.  Allegedly the point at which a Dexcom receiver will tell you to order another.  Was still functioning at 212/210, but range seemed diminished and definitely noisier.  I finally pulled it when it gave me a reading that was half of reality (something like 90 for a 175).

Finished result.  Took allot to get here.  Used Devcon 5 minute epoxy and an epoxy thickener that I had around from some past boat repair.  The Devcon 2 barrel syringe works really well, I've tried other brands that just didn't mix well, and the epoxy never cured.

I use a rasp and a really small router bit in a Dremel to get the batteries out.  The batteries are spot welded on the top and bottom.  I like to grind through the battery so I can get a screwdriver in it and lever it up a bit, then push a screwdriver in from the bottom and carefully push the tab away.  Repeat for the top.




I followed the iFixit guide by Joern.  The tricky part for me was getting sufficient contact between the top tabs and the battery.  Super glue just doesn't work.  I also tried something called "Wire Glue", carbon powder in a paint like substance, conductive.  That also didn't do the trick.  Only thing that works for me is soldering the top tabs to the battery.  Use a faceshield, too much heat and the batteries explode, I ruined a few.  I put a couple of drops of superglue around the bottom edges of the battery, then use my drill press to gently press and hold it in place for 5 minutes.  I'm surprised it holds as well as it does, you don't need to wait 24 hours for full strength.

To date, I've soldered the battery after gluing it.  Might be better to solder it in place, pop it up, and then glue it.  My solder job on this is horrible, but it makes the connection.  I can do a beautiful job soldering CR2032's, but these tiny batteries, not so much.  Sand the top of the battery, carefully sand the tab the best you can, maybe try tinning the battery top before soldering the tab on.  Lastly, glue it.
Also, hold the tab against the top of the battery while soldering, something thin and metal works, too much metal will work as a heat sink though.

You can measure the voltage on the bottom of the transmitter using the two pins.  You should see something around 0.270 mv.  This will vary depending on what kind of voltmeter you have (cheap or legit...).  Ideally, measure the voltage before you take the transmitter apart so you know what to shoot for.  The iFixit guide was 0.09 mv.  

Initially I kept getting high 100's, indicating that only one battery was really connected.  Soldering did the trick.

The next issue is batteries.  I ordered SR1120's, the battery dexcom uses.  I had a pair of Maxell and I purchased a 5-pack of no brands off of Amazon.  These were way too cheap, but I didn't realize why at the time.  I promptly blew up the Maxell's trying to solder them, then moved onto the cheapies.  These worked.  But the battery level reported by the firmware was 198 (you want 215 216).  Surprisingly this worked fine, signal was a bit week, but it was accurate.  Turns out, I bought Alkaline not Silver Oxide.  Would have been lucky to get 3 months I think.

Finally, I replaced the batteries a second time with Energizer 390/389 batteries and got the 216 level that you'd expect from a new transmitter.  These are slightly larger, hopefully I'll get 15 months before I have to repeat this exercise.

Lastly, I used duck tape around the transmitter to make a "dam", then I poured the epoxy in.
Once that set, it was easy to sand it down to something that looks very close to original.




Tuesday, May 29, 2018

Another try with the VivoSmart




Resurrected my iPhone app, which hasn't seen a phone in 3 years, last used with iOS 8.3.
BLE works better, whatever version we're on now.  Lot's of cleanup, this was some of the nastiest code I've written, getting closer to looking like my Pebble app.  Still Xcode is foreign, and it took me almost as long to convince it I was a registered developer as it did to get it working again.

All this came about because I started messing around with all these $30 fitness trackers.  The information is out there to pair directly with one and send notifications to it (the Mii Fit anyway).
So, as a preliminary step, I wanted to get notifications working with the phone again and see if this was going to work.  Future may include a ble nano /cc2500 combo, direct to band.  Although I'd like to find something better than the nano, I really need a device that can do both central and peripheral.
Normally the device is Central to the Band, but it needs to be Peripheral to the iPhone for calibrations (or whenever I want a front end).

And down that rabbit hole.  None of the cheapies handle a basic notification.  With allot of work I can spoof a phone call and get the info to the Mii, but it'll take me days.
Knowing the VivoSmart worked well in the past, I bought the VivoSmart3.  I am having a real good time with it.  I can't prevent the Vivo from vibrating when it receives a notification, so that caused me to rethink what I was doing.

Tired of always looking at the numbers, I realized I could let the phone do all the work for me.  If BG is stable between 90 and 160, am I going to do anything?, No.  So, the new app, if BG is between 90 and 160 AND the slope of glucose change is less than 1.5, then just send Good, once.  Now I go hours with a wristband that's quiet.  When things get lousy, it starts sending me data, and the vibration is useful.  The vibration isn't nearly strong enough to wake me at night, the phone gets that task.

Also, and here's the bigger item, I'm playing around with just displaying the estimated glucose rather than what the Dex (if I had a Dex) would display.  See above example, real time glucose is 154, based on the slope of change, it's really 163 (ie. what it will be in 10 minutes).  I've been using this for years, but only to estimate how long until I'm at a critical value(countdown above), which is 80 or 180.  33 minutes until 180 in the above example.  I thought, why bother with that, and just show the value.

Cuts down on allot of thinking on my part.  I show estimated glucose and the countdown value.  If I'm already over 180 or under 80, I display the Rate.  It's like before this tech existed, I feel good and I can just ignore the disease until the device buzzes.

It's fun to have a fitness band that I can actually use the functionality on, as well as track glucose.  Battery life is a 3+  days.

Tuesday, December 12, 2017

Android Wear (Finally)



So, I left this project alone for a while, then started it up again yesterday, and now, it just works.
I'll attribute this to problems with knowing if the updated code actually makes it onto the watch.
Maybe a restart caused the new code to run.

I have it running both as a watchface and as a complication.  Downside to the complication is vibration alerts don't work.   Alerts are good.  Also, I can't see it if I look quickly.

The watchface design, leaves allot to be desired for now, but that's on me.

Again, not sure why this works now.  Maybe the watch OS got updated...
My last change was to shutdown the ble connection every few minutes and force the watch to reconnect.  I'm hoping this forces the app to stay "awake", which it appears to do.  It's good for about 12 hours, I can probably improve that by leaving the ble up longer, but who knows at what point the device will go to sleep...  Other downside to the watch, it's only good to about 35% of battery and it doesn't alert when the battery level is low, it just dies.

Also, I did away with the Sweetblue api's and wrote the bluetooth from scratch.  There was too much going on there that I couldn't follow.

12/29 update
Getting up to 15 hours of use now.  Have to remember to turn WIFI off, sometimes it defaults to on after a restart.  Works reliably for days.  Can also run the battery down closer to zero.
Currently, stopping and restarting the Service that holds my Bluetooth intent every 10 minutes(this is in the code).
Somewhere between 10 and 15 minutes is the tipping point, where Bluetooth becomes unusable after several hours.

2/25 update
Looks like watch firmware improved, no longer having WIFI turn on.  Battery life is 30+ hours(on the device, not the watch).

Friday, October 20, 2017

Android Wear Success ( or Not)


Here's what happens when you make a device without any programmer access...
Luckily, hot glue is reversible with alcohol.

To make everything work, I needed to reprogram my device to send out the isig every 5 minutes.  This way, another device (the watch) can listen for a notification.  I originally wrote this, years ago, to only send a response to a request, but this isn't really how BTLE wants to work.

Finally success with android wear.  The end result looks exactly like my last post.  Unfortunately, I can't really see those numbers without reading glasses, so I'm stuck with a custom watch face and bigger numbers.  I'll work on that, I'm still trying to figure out complications, they only work by accident now.

As to the android studio issues, here's what to do when it starts acting up.
To connect to the watch you do "adb connect {watch ip address}".  This should connect quickly.
Signs that you're screwed are the following:
- can't connect to the watch, and you get various meaningless errors
- studio hangs, windows crashes etc
- studio tells you it can't put the apk on the watch etc.
- you deploy code, but the debugger doesn't stay connected so no logging

First, toggle wifi off/on on the watch, then try the connect statement.  That generally fixes things.  If problems persist, restart everything.  Your PC, the watch and your router.  It will work for up to a week after that.  Also, you probably need to wake the watch up to program, otherwise Android Stuido will just sit there.  Not exactly user friendly.

I'm using the Sweet Blue bluetooth libraries.  That got me around allot of headaches.  One strange thing, the device name has to be LOWER case.  The device is programmed in UPPER case, and you can confirm that with a bluetooth scanner, but you need lower case for sweet blue.

Complications, aptly named, when developing this, I had no issue pushing a value to the complication and having the screen refresh immediately.  In practice, there is a delay, not enough that I care, the vibratory alerts happen real time, and you can tap the display to get the current value, but they can lag a few minutes.  Another issue on the programming side, if I update the code on the watch, the bluetooth doesn't always start up again, it binds the device, but no values show up.  Solution, restart the watch.

Well, that's it, I'll  update this post when I've figured out what the battery life is going to be.  The CC2500/RFduino device is good for 24 hours, I'm hoping the watch will hold out for a full day.
-----------
10 hours, and the battery indicator was at 50%...  I'll try again with WIFI off.
-----------
11/27... Basically, this is a failure.  Only works for a few hours at best, appear to be fighting with power management.  Most telling thing I've noticed, at some point when the watch has been untouched, the "Tick" event stops (every minute an event normally fires).

Monday, October 9, 2017

Android Wear... Sort of



What it should be. 

My Pebble round lasted 1.5 years.  The replacement 3 months.  Now I'm using a Pebble Time, which is working great, but for how long?

Saw a good price on the Moto 360, so I ordered one.  Turns out I was early to the party.  Waited around a month for the 2.0 update to finally show up.  2.0 being important since that allows watch to bluetooth device communication, and not just a phone.

Programming this thing is impossible.  The connection between Android Studio and the Watch is sketchy at best.  You have to connect from the Terminal using something like "adb connect 192.xxx.xxx.xxx".  But allot of the time, it won't connect.  Sometimes it seems like maybe it's the watch has gone to sleep.  Other times, you toggle wifi on the watch and then the connect will work.  Who knows.  Buggy.  I had one magical day where it sat in the charger and worked flawlessly.  Today, I might get the APK deployed, but then the watch disconnects, so no debug.

I was very surprised when I switched to a Kindle tablet.  Infinitely easier.  The device just shows up when you click run, imagine that. 

Oh, and bluetooth.  I have it working, but after reinstalling the app on the watch, I'm getting messages that I need to grant access to bluetooth.  You have to do this multiple places. 
1. In the manifest
2. After the program is deployed, there's a permissions section
3. And it appears, you need to answer the dialogs asking for access to bluetooth as well.

There's the rub.  This is running as a complication, there's nowhere to pop-up a dialog, so you are dead in the water, stupid.  You can see the issues "they" are having with security on Android.

At the moment I'm not sure how I had bluetooth working, and since I can't get a reliable debug(today)...  I know some of my tests I had a basic watchface, then I loaded the complication, and it all worked.  Thinking I got lucky, and the authorization I provided for one app bled over to another.

Going to implement this on the kindle first, just to work out the coding issues and then keep my fingers crossed that I can get something to work on the watch.

On the plus side, Apple announced that their watch will soon communicate directly with the G5, at least the manufacturers are getting the message that people don't want to be tied to a phone.  I may get an iWatch, as soon as that update hits, probably better long term possibilities there, sounds(and looks) like Android Wear is DOA.