Click here to Skip to main content
11,436,179 members (64,376 online)
Click here to Skip to main content

Drawing medical waveforms using a Windows Mobile 5.0 device

, 3 Jan 2008 CPOL
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)

Share

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 Pin
Member 87165251-May-12 14:48
memberMember 87165251-May-12 14:48 
Questionmicroprocessor integrated bluetooth for patient monitoring system Pin
roshield6-Oct-11 9:36
memberroshield6-Oct-11 9:36 
GeneralECG monitoring project help Please Pin
Gregory Chandran8-Oct-09 8:39
memberGregory Chandran8-Oct-09 8:39 
GeneralRe: ECG monitoring project help Please Pin
Radhakrishna Banavalikar8-Oct-09 11:52
memberRadhakrishna Banavalikar8-Oct-09 11:52 
GeneralAnalog Frontend Pin
Edumotion18-Mar-09 0:41
memberEdumotion18-Mar-09 0:41 
GeneralRe: Analog Frontend Pin
Radhakrishna Banavalikar18-Mar-09 1:01
memberRadhakrishna Banavalikar18-Mar-09 1:01 
GeneralRe: Analog Frontend Pin
Edumotion18-Mar-09 4:39
memberEdumotion18-Mar-09 4:39 
GeneralRe: Analog Frontend Pin
Radhakrishna Banavalikar18-Mar-09 4:50
memberRadhakrishna Banavalikar18-Mar-09 4:50 
GeneralRe: Analog Frontend Pin
Edumotion18-Mar-09 4:59
memberEdumotion18-Mar-09 4:59 
GeneralRegarding algorithm Pin
boris11115-Feb-09 6:01
memberboris11115-Feb-09 6:01 
GeneralRe: Regarding algorithm Pin
Radhakrishna Banavalikar15-Feb-09 23:04
memberRadhakrishna Banavalikar15-Feb-09 23:04 
GeneralRe: Regarding algorithm Pin
boris11116-Feb-09 6:58
memberboris11116-Feb-09 6:58 
GeneralRe: Regarding algorithm [modified] Pin
Radhakrishna Banavalikar16-Mar-09 2:37
memberRadhakrishna Banavalikar16-Mar-09 2:37 
GeneralMedical Devices with Windows Mobile 5 Pin
imaginaryplaymate16-Dec-08 1:11
memberimaginaryplaymate16-Dec-08 1:11 
GeneralRe: Medical Devices with Windows Mobile 5 Pin
Radhakrishna Banavalikar16-Dec-08 1:43
memberRadhakrishna Banavalikar16-Dec-08 1:43 
GeneralRe: Medical Devices with Windows Mobile 5 Pin
imaginaryplaymate18-Dec-08 2:29
memberimaginaryplaymate18-Dec-08 2:29 
GeneralDevice Pin
Stefano_Busolin3-Sep-08 6:59
memberStefano_Busolin3-Sep-08 6:59 
GeneralRe: Device Pin
Radhakrishna Banavalikar3-Sep-08 10:36
memberRadhakrishna Banavalikar3-Sep-08 10:36 
GeneralRe: Device Pin
Stefano_Busolin3-Sep-08 11:47
memberStefano_Busolin3-Sep-08 11:47 
GeneralRe: Device Pin
Radhakrishna Banavalikar4-Sep-08 6:14
memberRadhakrishna Banavalikar4-Sep-08 6:14 
GeneralRe: Device Pin
Stefano_Busolin29-Sep-08 6:31
memberStefano_Busolin29-Sep-08 6:31 
GeneralRe: Device Pin
Radhakrishna Banavalikar29-Sep-08 7:57
memberRadhakrishna Banavalikar29-Sep-08 7:57 
GeneralRe: Device Pin
Stefano_Busolin13-Oct-08 23:56
memberStefano_Busolin13-Oct-08 23:56 
GeneralRe: Device Pin
Edumotion18-Mar-09 0:31
memberEdumotion18-Mar-09 0:31 
QuestionAbout ECG data Pin
jayesch8-Oct-07 19:44
memberjayesch8-Oct-07 19:44 
AnswerRe: About ECG data Pin
Radhakrishna Banavalikar8-Oct-07 21:37
memberRadhakrishna Banavalikar8-Oct-07 21:37 
Questionhelp me, please ! Pin
Ali Moein9-Feb-07 4:03
memberAli Moein9-Feb-07 4:03 
GeneralThreading VS Timer Pin
Emanuele Zambrano19-Jun-06 2:29
memberEmanuele Zambrano19-Jun-06 2:29 
GeneralRe: Threading VS Timer Pin
Radhakrishna Banavalikar19-Jun-06 4:50
memberRadhakrishna Banavalikar19-Jun-06 4:50 
GeneralRe: Threading VS Timer Pin
Emanuele Zambrano19-Jun-06 6:11
memberEmanuele Zambrano19-Jun-06 6:11 
GeneralBluetooth Pin
Nilesh Deshpande9-Jun-06 16:55
memberNilesh Deshpande9-Jun-06 16:55 
GeneralRe: Bluetooth Pin
Radhakrishna Banavalikar9-Jun-06 17:06
memberRadhakrishna Banavalikar9-Jun-06 17:06 
GeneralRe: Bluetooth Pin
mixio19-Nov-07 22:44
membermixio19-Nov-07 22:44 
GeneralElucidate Pin
satanic_code4-Jun-06 2:06
membersatanic_code4-Jun-06 2:06 
GeneralRe: Elucidate Pin
Radhakrishna Banavalikar4-Jun-06 5:39
memberRadhakrishna Banavalikar4-Jun-06 5:39 
GeneralArticle content Pin
Smitha Vijayan2-Jun-06 12:51
staffSmitha Vijayan2-Jun-06 12:51 
GeneralRe: Article content Pin
Radhakrishna Banavalikar4-Jun-06 5:40
memberRadhakrishna Banavalikar4-Jun-06 5:40 

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 | Terms of Use | Mobile
Web01 | 2.8.150428.2 | Last Updated 3 Jan 2008
Article Copyright 2006 by Radhakrishna Banavalikar
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid