Click here to Skip to main content
Click here to Skip to main content

Drawing medical waveforms using a Windows Mobile 5.0 device

, 3 Jan 2008
Rate this:
Please Sign up or sign in to vote.
This project gives a basic idea of how to develop patient monitoring systems based on a Windows Mobile device.

Sample Image - imate ECG.JPG

Introduction

Sometime back, I developed a prototype real-time monitoring console for medical monitoring. This article explains my work.

Definitions

  • ECG means electrocardiograph, a graph that indicates electrical activity of heart tissues.
  • SPO2 means Oxyhemoglobin saturation, or simply the percentage of Oxygen in blood. For a normal adult at rest, this could be around 95 to 99.
  • Respiration means one inspiration and one expiration. For a normal adult at rest, this could be around 16 and 20 per minute.

Application and scope

Biomedical monitors are used in critical care applications where patients are continuously monitored for any changes in the function of their vital organs. If such a monitor streams data to handheld devices like Windows Mobile phone, we can implement an anywhere, anytime monitoring device. This can help medical specialists to monitor any patient instantly, without leaving their seat.

The current demo takes values from static integer arrays. But, I will soon move it to Bluetooth to plot really real-time data. I have tested the code myself on an i-mate K-JAM device that runs Windows Mobile 5.0. However, this code should run on any PPC 2003 compatible device.

The application's working is quite simple, as described below:

public partial class Form1 : Form
{   
    //create variables for storing current and previous points
    int x, p, q, r, y, px, pp, pq, pr, py = 0; 

     //create colored pens for drawing 
 
    Pen yelgpen = new Pen(Color.YellowGreen);
    Pen redpen = new Pen(Color.Red);
    Pen graypen = new Pen(Color.Gray);
    Pen blackpen = new Pen(Color.Black);
 

    //fill the points to be plotted in integer arrays 
 
    int[] ECGArray = new int[]   
    { -5, -14, -10, -8, -9, -7, 0, 121, 108, -24, -34, -18, -19, -16, -19, -17, 
    -11, -11, -10, -1, 13, 33, 45, 47, 46, 37, 12, -12, -24, -23, -25, -21, -20, 
    -17, -19, -14, -12, -13, -12, -13, -8, -9, -5, -8, 10, 21, 19, 4, -10, 
    -11, -11, -12, -8, -12, 0, 121, 108, -24, -23, -18, -21, -16, -15, -14,  
    -10, -12, -7, 5, 26, 43, 46, 46, 41, 21, -1, -18, -24, -19, -22, -21,  
    -18, -18, -16, -13, -10, -12, -11, -8, -10, -8, -7, 0, 18, 24, 9, -7,  
    -13, -11, -9, -8, -10, 0, 121, 108, -24, -33, -17, -20, -19, -17, -14, 
    -13, -11, -8, 2, 19, 35, 47, 50, 43, 29, 7, -15, -29, -22, -25, -20,  
    -16, -19, -17, -16, -12, -11, -11, -10, -11, -9, -6, 0, 13, 23, 15, -2,  
    -11, -10, -10, -8, -7, -15, 0, 121, 108, -24, -20, -19, -20, -16, -12,  
    -14, -15, -11, -2, 12, 30, 41, 48, 44, 34, 16, -5, -21, -22, -21, -20,  
    -20, -13, -15, -15, -17, -14, -13, -9, -10, -10, -11, -8, 5, 23, 22, 4,  
    -9, -10, -12, -10, -10, -11, 0, 121, 108, -24, -28, -18, -19, -16, -16,  
    -16, -15, -13, -8, 4, 21, 39, 44, 46, 38, 45, 24, -1, -23, -28, -27, -25,  
    -20, -21, -18, -18, -14, -14, -13, -8, -9, -11, -9, 0, 16, 21, 11, -9,  
    -11, -9, -8, -9, -9, 0, 121, 108, -24, -32, -17, -21, -19, -16, -18, -13,  
    -10, -12 };
 
    int[] SPO2Array = new int[]  
    { 10, 9, 9, 9, 9, 9, 9, 10, 12, 16, 20, 25, 31, 37, 41, 45, 47, 47,  
    46, 42, 38, 33, 27, 23, 20, 17, 15, 15, 16, 16, 18, 18, 19, 19, 18, 18, 17,  
    16, 15, 13, 13, 11, 11, 11, 10, 10, 9, 9, 9, 9, 9, 9, 10, 12, 16, 20, 25,  
    31, 37, 41, 45, 47, 47, 46, 42, 38, 33, 27, 23, 20, 17, 15, 15, 16, 16, 18,  
    18, 19, 19, 18, 18, 17, 16, 15, 13, 13, 11, 11, 11, 10, 10, 9, 9, 9, 9, 9,  
    9, 10, 12, 16, 20, 25, 31, 37, 41, 45, 47, 47, 46, 42, 38, 33, 27, 23, 20,  
    17, 15, 15, 16, 16, 18, 18, 19, 19, 18, 18, 17, 16, 15, 13, 13, 11, 11, 11,  
    10, 10, 9, 9, 9, 9, 9, 9, 10, 12, 16, 20, 25, 31, 37, 41, 45, 47, 47, 46,  
    42, 38, 33, 27, 23, 20, 17, 15, 15, 16, 16, 18, 18, 19, 19, 18, 18, 17, 16,  
    15, 13, 13, 11, 11, 11, 10, 10, 9, 9, 9, 9, 9, 9, 10, 12, 16, 20, 25, 31,  
    37, 41, 45, 47, 47, 46, 42, 38, 33, 27, 23, 20, 17, 15, 15, 16, 16, 18, 18,  
    19, 19, 18, 18, 17, 16, 15, 13, 13, 11, 11, 11, 10, 10, 9, 9, 9, 9, 9, 9,  
    10, 12, 16, 20, 25, 31, 37, 41, 45, 47, 47, 46, 42, 38, 33, 27, 23, 20, 17,  
    15, 15, 16, 16, 16};
 
    int[] respArray = new int[] { 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52,  
    53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56,  
    56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58,  
    58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 57,  
    57, 57, 57, 57, 57, 57, 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 55,  
    54, 54, 54, 54, 54, 53, 53, 53, 52, 52, 51, 51, 51, 50, 50, 50, 49,  
    49, 49, 48, 48, 47, 47, 47, 46, 46, 46, 45, 45, 45, 45, 44, 44, 44,  
    43, 43, 42, 42, 41, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37, 37,  
    36, 36, 36, 36, 35, 35, 35, 35, 34, 34, 34, 34, 34, 33, 33, 33, 33,  
    33, 32, 32, 32, 32, 32, 32, 32, 32, 31, 31, 31, 31, 31, 31, 31, 31,  
    31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 34,  
    34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 39, 39, 40, 40,  
    40, 41, 41, 42, 42, 42, 43, 43, 44, 44, 45, 45, 45, 45, 46, 46, 46,  
    46, 47, 47, 47, 47, 48, 48, 49, 49, 49, 49, 49, 49, 48, 48, 47, 47,  
    47, 46, 46, 46, 45, 45, 45, 45, 44, 44, 44, 43, 43, 42, 42, 41, 41,  
    41, 40, 40, 39, 39, 38, 38 };

Now, use a timer to get the graph moving:

private void timer1_Tick(object sender, EventArgs e)
{ 
    
    //we are drawing on the form itself
    Graphics g = this.CreateGraphics();

    //traverse through the points one by one to get moving graphs
    for (int i = 0; i < ECGArray.Length; i++)
    {
        //e.Graphics.DrawLine(pen, 10, 10, 100, 100);
        if (x > this.Width - 100) x = 0;
        x += 1;
               
        //draw ECG
        p = 70 - (ECGArray[i] / 6 + 50);
        g.DrawLine(yelgpen, px, pp, x, p);
        g.DrawLine(yelgpen, px, pp + 30, x, p + 30);
        g.DrawLine(yelgpen, px, pp + 60, x, p + 60);
        //draw SPO2
        q = ((SPO2Array[i] * -1) / 2 + 120);
        g.DrawLine(graypen, px, pq, x, q);
        //draw respiration
        r = (respArray[i] / 2 + 120);
        g.DrawLine(redpen, px, pr, x, r);
        //draw erasebar to erase previous content at current location
        g.DrawRectangle(blackpen, 0, 0, x+1, this.Height);
        //store current point as previous point
        pp = p;
        pq = q;
        pr = r;
        px = x;
    }

Do not forget to keep the timer enabled. I have set the timer interval to around 800ms to get a good sweep speed. Lesser the timer interval, faster will be the sweep speed.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Radhakrishna Banavalikar
Architect
United Kingdom United Kingdom
Radhakrishna is a Microsoft Certified Technology Specialist and works for top Fortune 100 and government clients as a consultant across the United Kingdom. Converting ideas into real-world applications is his passion. He has worked on a mixed brew of technologies from Microsoft with recent concentration on .Net based architecture designs using Windows Mobile, Entity framework, AJAX, Webservices, JSON and JQuery. He is an ardent answerer on Microsoft asp.net forums. Especially the Ajax networking and web services chapter.
 
When not working, Radhakrishna likes listening to music, going places and photography.

Comments and Discussions

 
GeneralMy vote of 4 PinmemberMember 87165251-May-12 13:48 
Questionmicroprocessor integrated bluetooth for patient monitoring system Pinmemberroshield6-Oct-11 8:36 
GeneralECG monitoring project help Please PinmemberGregory Chandran8-Oct-09 7:39 
GeneralRe: ECG monitoring project help Please PinmemberRadhakrishna Banavalikar8-Oct-09 10:52 
GeneralAnalog Frontend PinmemberEdumotion17-Mar-09 23:41 
GeneralRe: Analog Frontend PinmemberRadhakrishna Banavalikar18-Mar-09 0:01 
GeneralRe: Analog Frontend PinmemberEdumotion18-Mar-09 3:39 
GeneralRe: Analog Frontend PinmemberRadhakrishna Banavalikar18-Mar-09 3:50 
GeneralRe: Analog Frontend PinmemberEdumotion18-Mar-09 3:59 
GeneralRegarding algorithm Pinmemberboris11115-Feb-09 5:01 
GeneralRe: Regarding algorithm PinmemberRadhakrishna Banavalikar15-Feb-09 22:04 
GeneralRe: Regarding algorithm Pinmemberboris11116-Feb-09 5:58 
GeneralRe: Regarding algorithm [modified] PinmemberRadhakrishna Banavalikar16-Mar-09 1:37 
GeneralMedical Devices with Windows Mobile 5 Pinmemberimaginaryplaymate16-Dec-08 0:11 
GeneralRe: Medical Devices with Windows Mobile 5 PinmemberRadhakrishna Banavalikar16-Dec-08 0:43 
GeneralRe: Medical Devices with Windows Mobile 5 Pinmemberimaginaryplaymate18-Dec-08 1:29 
GeneralDevice PinmemberStefano_Busolin3-Sep-08 5:59 
GeneralRe: Device PinmemberRadhakrishna Banavalikar3-Sep-08 9:36 
GeneralRe: Device PinmemberStefano_Busolin3-Sep-08 10:47 
GeneralRe: Device PinmemberRadhakrishna Banavalikar4-Sep-08 5:14 
GeneralRe: Device PinmemberStefano_Busolin29-Sep-08 5:31 
GeneralRe: Device PinmemberRadhakrishna Banavalikar29-Sep-08 6:57 
GeneralRe: Device PinmemberStefano_Busolin13-Oct-08 22:56 
GeneralRe: Device PinmemberEdumotion17-Mar-09 23:31 
QuestionAbout ECG data Pinmemberjayesch8-Oct-07 18:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 3 Jan 2008
Article Copyright 2006 by Radhakrishna Banavalikar
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid