Monday, May 17, 2010

How to make an Ambulatory Blood Pressure Monitor (ABPM) for just €20 ($25)


Fig 1: Modified HL168Y wrist cuff blood pressure monitor.
Summary: this post explains how to convert a Health & Life Co. HL168Y blood pressure monitor (sold by Maplin for €17) into an ambulatory blood pressure monitor using nothing but a few components costing no more than €3. Basic knowledge of electronics, simple tools and a PIC microcontroller programmer are required. The modification was successfully tested and a chart of the data is presented at the bottom of this post.

Blood pressure (BP) is notoriously difficult to measure. A single reading at a doctor’s surgery can be misleading as BP varies throughout the day and is often biased due to anxiety ("white coat hypertension"). For a better picture an ambulatory blood pressure monitor (ABPM) is used. This is an unobtrusive device that automatically takes readings at fixed intervals, usually 20 minute intervals during the day and 1 hour intervals at night. The data is stored on the device and is transferred to a computer at the end of the measuring period.

ABPMs are generally made for the medical profession and cost in excess of €1K. As far as I tell there are just a few key features that differentiate ABPMs from the cheap consumer models that can cost as little as €17:
  1. Automatically take measurements
  2. Transfer data to computer
  3. Unobtrusive and robust
  4. Calibrated and certified
So I started thinking: how easy would it be to modify a cheap consumer BP monitor to have ABPM functionality? Maplin sell a HL168Y cuff device for €17. At that price I thought it was worth a shot. The worst that can happen is I’m left with €17 of e-junk.
Disclaimer: Do not try this with a BP monitor that you need for medical purposes. Modifications will almost certainly void your warranty and may affect the accuracy and performance of the device. If you want to tinker with your BP monitor I recommend buying one specifically for this purpose. Also do not use the data obtained for any serious medical decisions: it's of unknown quality.



Fig 2: Innards of the HL168Y BPM
Most electronic BPMs use oscillometric measurement. A cuff which is wrapped around the arm (at wrist or upper arm level) is inflated to about 200mmHg (26kPa) pressure. At this pressure the cuff is sufficiently constrictive to block blood circulation to the arm. A pressure sensor monitors the pressure in the cuff. In addition to measuring the absolute pressure in the cuff, this sensor sufficiently sensitive to ‘hear’ the characteristic pulsations of the heart (which are manifested as small variations in pressure).

At 200mmHg blood flow is constricted -- no heart beat will be detected. The cuff is slowly deflated. At the systolic pressure (around 120mmHg for most people) the heart will be able to overcome the cuff pressure. The microcontroller will be able to detect a small pulsing variations in the cuff pressure. The cuff continues to deflate until a point is reached where no heart beat is detected. This is the diastolic pressure.

It is a very simple device essentially comprising a cuff, air pump, pressure sensor. A microcontroller  coordinates these components, make the calculations and display the result. As the Maplin device has a 40 reading memory, at its simplest all that is required is a means of pressing the button automatically every 20 minutes. The readings will have to be manually transcribed into a spreadsheet or other analysis tool. In theory, this could be done mechanically (using a solenoid actuator) but would would involve a cumbersome attachment to the front face of the device – not very practical. Fortunately simulating a button press electrically is trivial.

The HL168Y device has 4 buttons: Start/Stop, Mode, Set and Memory. These are standard rubber buttons. When depressed, a conductive rubber foot on the underside of the button squeezes against interleaved copper contacts on the PCB.

On the reverse of the PCB are test pads which provide a convenient way to test or tap into important points in the device. TP4 corresponds to the Start/Stop button. Pulling this line to ground (0V) simulates pressing the button.

A microcontroller unit (MCU) like a PIC from Microchip Technology Inc. is perfect for the task. PICs are small, cheap and operate at voltages down to 2V. The HL168Y uses 3V (2 x AAA cells) so the PIC can draw power from the same battery.

My first choice was a tiny 8 pin 12F675. I figured this was small enough to fit in the spare space inside the device housing. Unfortunately I ran into some programming problems so opted for a larger 18 pin 16F627.

The Hardware


Fig 3: schematic of modification
Three points need to be tapped into:
  • Red: Battery + terminal (3V)
  • Black: Battery - terminal (0V)
  • Orange: testpad TP4 (the Start/Stop button)

Solder three wires to the above points. I strongly recommend that the wires are restrained using tape (otherwise it’s all to easy to damage the PCB by accidental tugging on the wires). These three wires connect to pins on the PIC (see fig 4).



Fig 4: The 16F627 PIC MCU mounted on an IC socket. Also underneath (not in view) 2K2 resistor linking Vdd to MCLR pin.

To facilitate easy reprogramming of the PIC I soldered a IC socket into some veroboard. The PIC can be easily mounted and removed as needed.

The red wire is connected to Vdd (pin 14), black to Vss (pin 5) and orange to PB0 (pin 6). I found that unless the master clear pin MCLR (pin 4) is tied high the device is unstable. Therefore under the board (not visible in the photo) is a 2K2 resistor linking pin 4 to pin 14 (any value 1K  - 10K will do).

Test by powering up. If all goes well the BPM should automatically start taking a reading in 5 minutes (enough time to reset the clock).  Tape the attachment to the side of the device using duct tape.  Ensure there are no lose wires that can be snagged on something as you go about your day.



The Software

The requirements for the first iteration of my modification is quite simple: Simulate "Start" being pressed sleep for 20 minutes and repeat.

Delays are often achieved by a tight loop or using internal counters. As this is a battery operated device minimizing power consumption is vital. Delays using loops or timers would push current consumption into the mA region, depleting the battery in days.

Fortunately there is a low power alternative: the PIC SLEEP instruction which puts the chip into a deep hibernate mode. The device can be woken from sleep by interrupt (eg button press) or using the device Watchdog Timer. Using the SLEEP instruction I’ve been able to reduce average power consumption into the micro-amp region.

For the first iteration of this project I've decided to use the C compiler that comes with Microchip's free MPLAB IDE. The free C compiler does not produce the most compact code, but as it's such a short program it is not a problem.

The C program below is compiled with MPLAB and the resulting HEX file uploaded onto the 16F627 chip using a Velleman K8048 PIC programmer.

#include <htc.h>

__CONFIG(INTIO & WDTEN & PWRTDIS & BORDIS & LVPEN  & UNPROTECT);

// Internal crystal frequency 4Mhz
#define _XTAL_FREQ 4000000

int loopDelay (unsigned char n);
int pauseSeconds (unsigned char n);
int pauseMinutes (unsigned char n);

void init(void) {
 PORTB = 0x00000001; // set RB0 on latch high before making pin output
 TRISB = 0b11111110; // set RB0 as output (1=input, 0=output)
}

void main(void) {
 init();
 while (1) {
  pauseMinues (5);

  // Press start button twice (once to wake, once to start)
  pressStartButton(); 
  pauseSeconds(2);
  pressStartButton();

  pauseMinutes(15);
 }
}

/** 
 * Simulate the pressing of the Start button
 */
int pressStartButton () {
 PORTB = 0b0;
 loopDelay(128);
 PORTB = 0b1;
}


 
/** 
 * Seep for one whole cycle of the watchdog timer (about 2s in 16F627)
 */
int wdtSleep () {
 CLRWDT();
 SLEEP();
}

/**
 * Sleep for 'n' seconds by calling wdtSleep() in a loop
 */
int pauseSeconds (unsigned char n) {
 int j;
 n /= 2;
 for (j = 0; j < n; j++) {
  wdtSleep();
 }
}

/**
 * Sleep for 'n' minutes by calling wdtSleep() in a loop
 */
int pauseMinutes (unsigned char n) {
 int i,j;
 for (j = 0; j < n; j++) {
  // about 1 minute
  for (i = 0; i < 30; i++) {
   wdtSleep();
  }
 }
}

/**
 * Cause a delay by looping. Useful for short delays, but uses considerably
 * more power than using SLEEP
 */
int loopDelay (unsigned char n) {
        unsigned char i,j;
        for (i = 0; i < n; i++) {
                CLRWDT();
                for (j = 0; j < 127; j++) {
                        NOP();
                }
        }
}

The Data

I tested this device on myself for a 30 hour continuous stretch over the weekend. It's like wearing a big heavy watch and generally was not a problem. For good readings it is necessary hold still and keep the device at heart level during the 30 seconds or so it takes to measure. It can be easily removed at any time if necessary. I was able to sleep with it (although I think it did affect the quality of my sleep).

The following is a chart of that run. It shows the expected day/night difference, with a noticeable dip during the peak of the sleep cycle at about 04:00.


Limitations

The main problem with this that it starts automatically and continues to trigger a measurement every 20 minutes while batteries are in the device. The only way to turn it off is to remove the battery (which by the way also erases the clock and memory). Also we have to manually key the data from the screen into our spreadsheet / analysis software. This is a major pain point for which I no solution yet. I would also very much like to be able to fit this modification inside the original housing.

Finally a wrist cuff device is not the best for ABPM because readings should be taken while the wrist is at heart height. Any higher or lower will bias the reading. An upper arm cuff is far more preferable as it's always (approx) at heart level and is more comfortable to wear. It may be possible to modify this device into such a configuration, although it will involve tearing it apart.

Phase 2 will attempt to address some of these shortcomings.

11 comments:

Adrian said...

Wow, I need somthing like this.
Did you continue your work? You should come up with some professional device.

Please let me know.

jdesbonnet said...

Work is ongoing in the few free hours I have. I just got a upper arm cuff device which is more suited for 24 hour monitoring. I hope to have an update in Feb 2011.

It's one thing doing this in a hobby capacity. A commercial product of this nature opens a huge can of worms in terms of certification, product liability insurance and potential patent infringement. If anyone is interested in working with me to develope a commercial product do let me know. There may be a niche for an "open hardware" BP monitor.

life2628 said...

How do you handle the abnormal SYS & DIA & PULSE RATE measured data while you are walking or talking ?

Do you know how do the professional ABPM handle this ?

Can u develop some algorithm to filter the above noise ?

jdesbonnet said...

Good question re measuring BP while moving. Right now I just rely on the devices own algorithm built into its proprietary controller. As cheap consumer units I would imagine they don't handle that situation well.

However I recall when I wore a 'proper' ABPM for a day (a SpaceLabs model I think), I was told by the nurse to try to be as still as possible during the measurements -- so I'm not sure that even the expensive models can do a good job of handling excessive motion well during measurements.

But you raise a good point. The next thing I want to do here (when I get time) is to eliminate the proprietary controller and see if I can implement the whole process with my own (open source!) firmware on my own MCU.

Andrew Luxner said...

Hello Joe,

I want to hack a blood pressure monitor for a school project; tap into readings and transmit them for other use. Since you started this project have you found any other models of BP monitors that are particularly easy to access? I have a lot of programming experience but I'm very green when it comes to working with electronics - can you offer any tips on getting started?

jdesbonnet said...

Andrew, It turns that all the low cost models I've seen for sale locally are rebadged "Health and Life Company" (Taiwan) models. I think most of them share the same basic design and I suspect the EEPROM storage schema (documented in my blog posts) will be the same for all models. An alternative approach is buy a cheap monitor, rip out the controller board and replace with your own (eg an Arduino or Raspberry Pi). You will likely need a little bit of analog signal conditioning for the pressure sensor prior to feeding it to an ADC. Otherwise it's just IO lines driving the pump and release valve. There are many application notes by semiconductor manufacturers on how to implement a BP monitor (eg google "Freescale AN4328"). Most of the real work will be in software... signal processing the pressure sensor to listen for the systolic and diastolic pressure points. Btw: this is where a beefier board like a Beagle Bone or Raspberry Pi would have the edge on the Arduino). If you have any specific questions please feel to post here, or email me jdesbonnet at gmail dot com.

mrwolf said...

Hi there Jdes, was wondering if your still working on this project?

I would like to discuss a project with you

sphygmo said...

Hi Joe,

Where were you able to purchase the Health & Life wrist BP monitor? We were not able to find it on the web.

Thanks!

sphygmo said...

Hi Joe,

Where did you purchase the Health and Life HL168 Wrist BP Monitor? Could you please provide us with a link. We weren't able to find it on the web.

Thanks!

jdesbonnet said...

I got the first model in Maplin (a UK/Ireland chain of stores similar to Radioshack in the US). Later I found models under the brand 'Sanitas' in Lidl which was also a rebranded Health and Life machine. It seems many of the cheap BP monitors are produced by just a few manufacturers and are rebranded.

Andrew Luxner said...

I found one on Amazon in the US. Search for "Wristech". You should find several results from North American Healthcare. I got one that cost $24.99, and so far it's worked as Joe has described, with the test pads and everything.