The personal website of Scott W Harden
April 15th, 2013

Fixing Slow Matplotlib in Python(x,y)

I recently migrated to Python(x,y) and noticed my matplotlib graphs are resizing unacceptably slowly when I use the pan/zoom button. I'm quite a fan of numpy, scipy, matplotlib, the python imaging library (PIL), and GUI platforms like Tk/TkInter, pyGTK, and pyQT, but getting them all to play nicely is a sometimes pain. I'm considering migrating entirely to Python(x,y) because, as a single distribution, it's designed to install all these libraries (and many more) in a compatible way out of the box. However, when I did, I noticed matplotlib graphs would resize, rescale, and drag around the axes very slowly. After a lot of digging on the interweb, I figured out what was going wrong. I'll show you by plotting 20 random data points the slow way (left) then the fast way (right).

THE PROBLEM: See the difference between the two plots? The one on the left (SLOW!) uses the Qt4Agg backend, which renders the matplotlib plot on a QT4 canvas. This is slower than the one on the right, which uses the more traditional TkAgg backend to draw the plot on a Tk canvas with tkinter (FASTER!). Check out matplotlib's official description of what a backend is and which ones you can use. When you just install Python and matplotlib, Tk is used by default.

import numpy
import matplotlib
matplotlib.use('TkAgg') # <-- THIS MAKES IT FAST!
import pylab
pylab.plot(numpy.random.random_integers(0,100,20))
pylab.title("USING: "+matplotlib.get_backend())
pylab.show()

THE FIX: Tell matplotlib to stop using QT to draw the plot, and let it plot with Tk. This can be done immediately after importing matplotlib, but must be done before importing pylab using the line matplotlib.use('TkAgg'). Here's the full example I used to generate the demonstration plots above. Change TkAgg to Qt4Agg (or comment-out the 'use' line if you're using PythonXY) and you will see performance go down the tube. Alternatively, make a change to the matplotlib rc file to customize default behavior when the package is loaded.

Markdown source code last modified on January 18th, 2021
---
title: Fixing Slow Matplotlib in Python(x,y)
date: 2013-04-15 11:55:27
tags: python, old
---

# Fixing Slow Matplotlib in Python(x,y)

__I recently migrated to [Python(x,y)](https://code.google.com/p/pythonxy/) and noticed my matplotlib graphs are resizing unacceptably slowly when I use the pan/zoom button.__ I'm quite a fan of [numpy](http://www.scipy.org/Download), [scipy](http://www.scipy.org/Download), [matplotlib](http://matplotlib.org), the [python imaging library (PIL)](http://www.pythonware.com/products/pil/), and GUI platforms like [Tk/TkInter](http://wiki.python.org/moin/TkInter), [pyGTK](http://www.pygtk.org/), and [pyQT](http://www.riverbankcomputing.com/software/pyqt/intro), but getting them all to play nicely is a sometimes pain. I'm considering migrating entirely to [Python(x,y)](https://code.google.com/p/pythonxy/) because, as a single distribution, it's designed to install all [these libraries (and many more)](https://code.google.com/p/pythonxy/wiki/StandardPlugins) in a compatible way out of the box. However, when I did, I noticed matplotlib graphs would resize, rescale, and drag around the axes very slowly. After a lot of digging on the interweb, I figured out what was going wrong. I'll show you by plotting 20 random data points the slow way (left) then the fast way (right).

<div class="text-center img-small">

[![](matplotlib-qt4agg_thumb.jpg)](matplotlib-qt4agg.jpg)
[![](matplotlib-tkagg_thumb.jpg)](matplotlib-tkagg.jpg)

</div>

__THE PROBLEM:__ See the difference between the two plots? The one on the left (SLOW!) uses the Qt4Agg backend, which renders the matplotlib plot on a QT4 canvas. This is slower than the one on the right, which uses the more traditional TkAgg backend to draw the plot on a Tk canvas with tkinter (FASTER!).  Check out [matplotlib's official description of what a backend is](http://matplotlib.org/faq/usage_faq.html#what-is-a-backend) and which ones you can use. When you just install Python and matplotlib, Tk is used by default.

```python
import numpy
import matplotlib
matplotlib.use('TkAgg') # <-- THIS MAKES IT FAST!
import pylab
pylab.plot(numpy.random.random_integers(0,100,20))
pylab.title("USING: "+matplotlib.get_backend())
pylab.show()
```

__THE FIX:__ Tell matplotlib to stop using QT to draw the plot, and let it plot with Tk. This can be done immediately after importing matplotlib, but must be done before importing pylab using the line `` matplotlib.use('TkAgg') ``. Here's the full example I used to generate the demonstration plots above. Change TkAgg to Qt4Agg (or comment-out the 'use' line if you're using PythonXY) and you will see performance go down the tube. Alternatively, [make a change to the matplotlib rc file](http://matplotlib.org/users/customizing.html) to customize default behavior when the package is loaded.
April 14th, 2013

Simple DIY ECG + Pulse Oximeter (version 2)

⚠️ Check out my newer ECG designs:

Of the hundreds of projects I've shared over the years, none has attracted more attention than my DIY ECG machine on the cheap posted almost 4 years ago. This weekend I re-visited the project and made something I'm excited to share! The original project was immensely popular, my first featured article on Hack-A-Day, and today "ECG" still represents the second most searched term by people who land on my site. My gmail account also has had 194 incoming emails from people asking details about the project. A lot of it was by frustrated students trying to recreate the project running into trouble because it was somewhat poorly documented. Clearly, it's a project that a wide range of people are interested in, and I'm happy to revisit it bringing new knowledge and insight to the project. I will do my best to document it thoroughly so anyone can recreate it!

The goal of this project is to collect heartbeat information on a computer with minimal cost and minimal complexity. I accomplished this with fewer than a dozen components (all of which can be purchased at RadioShack). It serves both as a light-based heartbeat monitor (similar to a pulse oximeter, though it's not designed to quantitatively measure blood oxygen saturation), and an electrocardiogram (ECG) to visualize electrical activity generated by heart while it contracts. Let's jump right to the good part - this is what comes out of the machine:

That's my actual heartbeat. Cool, right? Before I go into how the circuit works, let's touch on how we measure heartbeat with ECG vs. light (like a pulse oximeter). To form a heartbeat, the pacemaker region of the heart (called the SA node, which is near the upper right of the heart) begins to fire and the atria (the two top chambers of the heart) contract. The SA node generates a little electrical shock which stimulated a synchronized contraction. This is exactly what defibrillators do when a heart has stopped beating. When a heart attack is occurring and a patient is undergoing ventricular fibrillation, it means that heart muscle cells are contracting randomly and not in unison, so the heart quivers instead of pumping as an organ. Defibrillators synchronize the heart beat with a sudden rush of current over the heart to reset all of the cells to begin firing at the same time (thanks Ron for requesting a more technical description). If a current is run over the muscle, the cells (cardiomyocytes) all contract at the same time, and blood moves. The AV node (closer to the center of the heart) in combination with a slow conducting pathway (called the bundle of His) control contraction of the ventricles (the really large chambers at the bottom of the heart), which produce the really large spikes we see on an ECG. To measure ECG, optimally we'd place electrodes on the surface of the heart. Since that would be painful, we do the best we can by measuring voltage changes (often in the mV range) on the surface of the skin. If we amplify it enough, we can visualize it. Depending on where the pads are placed, we can see different regions of the heart contract by their unique electrophysiological signature. ECG requires sticky pads on your chest and is extremely sensitive to small fluctuations in voltage. Alternatively, a pulse oximeter measures blood oxygenation and can monitor heartbeat by clipping onto a finger tip. It does this by shining light through your finger and measuring how much light is absorbed. This goes up and down as blood is pumped through your finger. If you look at the relationship between absorbency in the red vs. infrared wavelengths, you can infer the oxygenation state of the blood. I'm not doing that today because I'm mostly interested in detecting heart beats.

For operation as a pulse oximeter-type optical heartbeat detector (a photoplethysmograph which produces a photoplethysmogram), I use a bright red LED to shine light through my finger and be detected by a phototransistor (bottom left of the diagram). I talk about how this works in more detail in a previous post. Basically the phototransistor acts like a variable resistor which conducts different amounts of current depending on how much light it sees. This changes the voltage above it in a way that changes with heartbeats. If this small signal is used as the input, this device acts like a pulse oximeter.

For operation as an electrocardiograph (ECG), I attach the (in) directly to a lead on my chest. One of them is grounded (it doesn't matter which for this circuit - if they're switched the ECG just looks upside down), and the other is recording. In my original article, I used pennies with wires soldered to them taped to my chest as leads. Today, I'm using fancier sticky pads which are a little more conductive. In either case, one lead goes in the center of your chest, and the other goes to your left side under your arm pit. I like these sticky pads because they stick to my skin better than pennies taped on with electrical tape. I got 100 Nikomed Nikotabs EKG Electrodes 0315 on eBay for $5.51 with free shipping (score!). Just gator clip to them and you're good to go!

In both cases, I need to build a device to amplify small signals. This is accomplished with the following circuit. The core of the circuit is an LM324 quad operational amplifier. These chips are everywhere, and extremely cheap. It looks like Thai Shine sells 10 for $2.86 (with free shipping). That's about a quarter each. Nice! A lot of ECG projects use instrumentation amplifiers like the AD620 (which I have used with fantastic results), but these are expensive (about $5.00 each). The main difference is that instrumentation amplifiers amplify the difference between two points (which reduces noise and probably makes for a better ECG machine), but for today an operational amplifier will do a good enough job amplifying a small signal with respect to ground. I get around the noise issue by some simple filtering techniques. Let's take a look at the circuit.

This project utilizes one of the op-amps as a virtual ground. One complaint of using op-amps in simple projects is that they often need + and - voltages. Yeah, this could be done with two 9V batteries to generate +9V and -9V, but I think it's easier to use a single power source (+ and GND). A way to get around that is to use one of the op-amps as a current source and feed it half of the power supply voltage (VCC), and use the output as a virtual ground (allowing VCC to be your + and 0V GND to be your -). For a good description of how to do this intelligently, read the single supply op amps web page. The caveat is that your signals should remain around VCC/2, which can be done if it is decoupled by feeding it through a series capacitor. The project works at 12V or 5V, but was designed for (and has much better output) at 12V. The remaining 3 op-amps of the LM324 serve three unique functions:

STAGE 1: High gain amplifier. The input signals from either the ECG or pulse oximeter are fed into a chain of 3 opamp stages. The first is a preamplifier. The output is decoupled through a series capacitor to place it near VCC/2, and amplified greatly thanks to the 1.8Mohm negative feedback resistor. Changing this value changes initial gain.

STAGE 2: active low-pass filter. The 10kOhm variable resistor lets you adjust the frequency cutoff. The opamp serves as a unity gain current source / voltage follower that has high input impedance when measuring the output f the low-pass filter and reproduces its voltage with a low impedance output. There's some more information about active filtering on this page. It's best to look at the output of this stage and adjust the potentiometer until the 60Hz noise (caused by the AC wiring in the walls) is most reduced while the lower-frequency component of your heartbeat is retained. With the oximeter, virtually no noise gets through. Because the ECG signal is much smaller, this filter has to be less aggressive, and this noise is filtered-out by software (more on this later).

STAGE 3: final amplifier with low-pass filter. It has a gain of ~20 (determined by the ratio of the 1.8kOhm to 100Ohm resistors) and lowpass filtering components are provided by the 22uF capacitor across the negative feedback resistor. If you try to run this circuit at 5V and want more gain (more voltage swing), consider increasing the value of the 1.8kOhm resistor (wit the capacitor removed). Once you have a good gain, add different capacitor values until your signal is left but the noise reduced. For 12V, these values work fine. Let's see it in action!

Now for the second half - getting it into the computer. The cheapest and easiest way to do this is to simply feed the output into a sound card! A sound card is an analog-to-digital converter (ADC) that everybody has and can sample up to 48 thousand samples a second! (overkill for this application) The first thing you should do is add an output potentiometer to allow you to drop the voltage down if it's too big for the sound card (in the case of the oximeter) but but also allow full-volume in the case of sensitive measurements (like ECG). Then open-up sound editing software (I like GoldWave for Windows or Audacity for Linux, both of which are free) and record the input. You can do filtering (low-pass filter at 40Hz with a sharp cutoff) to further eliminate any noise that may have sneaked through. Re-sample at 1,000 Hz (1kHz) and save the output as a text file and you're ready to graph it! Check it out.

Here are the results of some actual data recorded and processed with the method shown in the video. let's look at the pulse oximeter first.

That looks pretty good, certainly enough for heartbeat detection. There's obvious room for improvement, but as a proof of concept it's clearly working. Let's switch gears and look at the ECG. It's much more challenging because it's signal is a couple orders of magnitude smaller than the pulse oximeter, so a lot more noise gets through. Filtering it out offers dramatic improvements!

Here's the code I used to generate the graphs from the text files that GoldWave saves. It requires Python, Matplotlib (pylab), and Numpy. In my case, I'm using 32-bit 2.6 versions of everything.

# DIY Sound Card ECG/Pulse Oximeter
# by Scott Harden (2013) http://www.SWHarden.com

import pylab
import numpy

f=open("light.txt")
raw=f.readlines()[1:]
f.close()

data = numpy.array(raw,dtype=float)
data = data-min(data) #make all points positive
data = data/max(data)*100.0 #normalize
times = numpy.array(range(len(data)))/1000.0
pylab.figure(figsize=(15,5))
pylab.plot(times,data)
pylab.xlabel("Time Elapsed (seconds)")
pylab.ylabel("Amplitude (% max)")
pylab.title("Pulse Oximeter - filtered")
pylab.subplots_adjust(left=.05,right=.98)
pylab.show()

Future directions involve several projects I hope to work on soon. First, it would be cool to miniaturize everything with surface mount technology (SMT) to bring these things down to the size of a postage stamp. Second, improved finger, toe, or ear clips (or even taped-on sensors) over long duration would provide a pretty interesting way to analyze heart rate variability or modulation in response to stress, sleep apnea, etc. Instead of feeding the signal into a computer, one could send it to a micro-controller for processing. I've made some darn-good progress making multi-channel cross-platform USB option for getting physiology data into a computer, but have some work still to do. Alternatively, this data could be graphed on a graphical LCD for an all-in-one little device that doesn't require a computer. Yep, lots of possible projects can use this as a starting point.

Notes about safety: If you're worried about electrical shock, or unsure of your ability to make a safe device, don't attempt to build an ECG machine. For an ECG to work, you have to make good electrical contact with your skin near your heart, and some people feel this is potentially dangerous. Actually, some people like to argue about how dangerous it actually is, as seen on Hack-A-Day comments and my previous post comments. Some people have suggested the danger is negligible and pointed-out that it's similar to inserting ear-bud headphones into your ears. Others have suggested that it's dangerous and pointed-out that milliamps can kill a person. Others contest that pulses of current are far more dangerous than a continuous applied current. Realists speculate that virtually no current would be delivered by this circuit if it is wired properly. Rational, cautionary people worried about it reduce risk of accidental current by applying bidirectional diodes at the level of the chest leads, which short any current (above 0.7V) similar to that shown here. Electrically-savvy folks would design an optically decoupled solution. Intelligent folks who abstain from arguing on the internet would probably consult the datasheets regarding ECG input protection. In all cases, don't attach electrical devices to your body unless you are confident in their safety. As a catch-all, I present the ECG circuit for educational purposes only, and state that it may not be safe and should not be replicated There, will that cover me in court in case someone tapes wires to their chest and plugs them in the wall socket?

LET ME KNOW WHAT YOU THINK! If you make this, I'm especially interested to see how it came out. Take pictures of your projects and send them my way! If you make improvements, or take this project further, I'd be happy to link to it on this page. I hope this page describes the project well enough that anyone can recreate it, regardless of electronics experience. Finally, I hope that people are inspired by the cool things that can be done with surprisingly simple electronics. Get out there, be creative, and go build something cool!

Markdown source code last modified on January 18th, 2021
---
title: Simple DIY ECG + Pulse Oximeter (version 2)
date: 2013-04-14 16:00:14
tags: diyECG, microcontroller, old
---

# Simple DIY ECG + Pulse Oximeter (version 2)

> **⚠️ Check out my newer ECG designs:** 
* [**Sound Card ECG with AD8232**](https://swharden.com/blog/2019-03-15-sound-card-ecg-with-ad8232/)
* [**Single op-amp ECG**](https://swharden.com/blog/2016-08-08-diy-ecg-with-1-op-amp/)

__Of the hundreds of projects I've shared over the years, none has attracted more attention than my [DIY ECG machine on the cheap](http://www.swharden.com/blog/2009-08-14-diy-ecg-machine-on-the-cheap/) posted almost 4 years ago. This weekend I re-visited the project and made something I'm excited to share!__  The original project was immensely popular, my [first featured article on Hack-A-Day](http://hackaday.com/2009/08/22/collect-and-analyze-ecg-data/), and today "ECG" still represents the second most searched term by people who land on my site. My gmail account also has had 194 incoming emails from people asking details about the project. A lot of it was by frustrated students trying to recreate the project running into trouble because it was somewhat poorly documented. Clearly, it's a project that a wide range of people are interested in, and I'm happy to revisit it bringing new knowledge and insight to the project. I will do my best to document it thoroughly so anyone can recreate it!

<div class="text-center img-border">

[![](diy-ecg-pulse-oximeter-lm324-opamp-sound-card_thumb.jpg)](diy-ecg-pulse-oximeter-lm324-opamp-sound-card.jpg)

</div>

__The goal of this project is to collect heartbeat information on a computer with minimal cost and minimal complexity.__  I accomplished this with fewer than a dozen components (all of which can be purchased at RadioShack). It serves both as a light-based heartbeat monitor (similar to a pulse oximeter, though it's not designed to quantitatively measure blood oxygen saturation), and an electrocardiogram (ECG) to visualize electrical activity generated by heart while it contracts. Let's jump right to the good part - this is what comes out of the machine:

<div class="text-center">

[![](pulse-ecg-filtered-a_thumb.jpg)](pulse-ecg-filtered-a.png)

</div>

<strong>That's <em>my</em> actual heartbeat. Cool, right? Before I go into how the circuit works, let's touch on how we measure heartbeat with ECG vs. light (like a pulse oximeter).</strong>  To form a heartbeat, the pacemaker region of the heart (called the SA node, which is near the upper right of the heart) begins to fire and the atria (the two top chambers of the heart) contract. The SA node generates a little electrical shock which stimulated a synchronized contraction. <span style="text-decoration: line-through;">This is exactly what defibrillators do when a heart has stopped beating.</span> When a heart attack is occurring and a patient is undergoing ventricular fibrillation, it means that heart muscle cells are contracting randomly and not in unison, so the heart quivers instead of pumping as an organ. Defibrillators synchronize the heart beat with a sudden rush of current over the heart to reset all of the cells to begin firing at the same time (thanks Ron for requesting a more technical description).  If a current is run over the muscle, the cells (cardiomyocytes) all contract at the same time, and blood moves. The AV node (closer to the center of the heart) in combination with a slow conducting pathway (called the bundle of His) control contraction of the ventricles (the really large chambers at the bottom of the heart), which produce the really large spikes we see on an ECG.  <strong>To measure ECG</strong>, optimally we'd place electrodes on the surface of the heart. Since that would be painful, we do the best we can by measuring voltage changes (often in the mV range) on the surface of the skin. If we amplify it enough, we can visualize it. Depending on where the pads are placed, we can see different regions of the heart contract by their unique electrophysiological signature. ECG requires sticky pads on your chest and is extremely sensitive to small fluctuations in voltage. Alternatively, <strong>a pulse oximeter measures blood oxygenation and can monitor heartbeat by clipping onto a finger tip</strong>. It does this by shining light through your finger and measuring how much light is absorbed. This goes up and down as blood is pumped through your finger. If you look at the relationship between absorbency in the red vs. infrared wavelengths, you can infer the oxygenation state of the blood. I'm not doing that today because I'm mostly interested in detecting heart beats.

<strong>For operation as a pulse oximeter-type optical heartbeat detector (a <em>photoplethysmograph</em> which produces a <a href="http://en.wikipedia.org/wiki/Photoplethysmogram"><em>photoplethysmogram</em></a>),</strong> I use a bright red LED to shine light through my finger and be detected by a phototransistor (bottom left of the diagram). I talk about how this works in more detail <a href="http://www.swharden.com/blog/2012-12-06-single-wavelength-pulse-oximeter/">in a previous post</a>. Basically the phototransistor acts like a variable resistor which conducts different amounts of current depending on how much light it sees. This changes the voltage above it in a way that changes with heartbeats. If this small signal is used as the input, this device acts like a pulse oximeter.

<div class="text-center img-border">

[![](2013-04-14-11.36.39_thumb.jpg)](2013-04-14-11.36.39.jpg)

</div>

<strong>For operation as an electrocardiograph (ECG)</strong>, I attach the (in) directly to a lead on my chest. One of them is grounded (it doesn't matter which for this circuit - if they're switched the ECG just looks upside down), and the other is recording. In my <a href="http://www.swharden.com/blog/2009-08-14-diy-ecg-machine-on-the-cheap/">original article</a>, I used pennies with wires soldered to them taped to my chest as leads. Today, I'm using fancier sticky pads which are a little more conductive. In either case, one lead goes in the center of your chest, and the other goes to your left side under your arm pit. I like these sticky pads because they stick to my skin better than pennies taped on with electrical tape. I got <a href="http://www.ebay.com/sch/i.html?_trksid=m570.l3201&_nkw=100+NIKOMED+NIKOTABS+EKG+ELECTRODES+0315&_sacat=0">100 Nikomed Nikotabs EKG Electrodes 0315</a> on eBay for $5.51 with free shipping (score!). Just gator clip to them and you're good to go!

<div class="text-center img-border">

[![](2013-04-14-15.06.20_thumb.jpg)](2013-04-14-15.06.20.jpg)

</div>

__In both cases, I need to build a device to amplify small signals__. This is accomplished with the following circuit. The core of the circuit is an [LM324 quad operational amplifier](http://www.ti.com/lit/ds/symlink/lm124-n.pdf).  These chips are everywhere, and extremely cheap. It looks like [Thai Shine sells 10 for $2.86](http://www.thaishine.com/servlet/the-910/10-x-LM324N-LM324/Detail) (with free shipping). That's about a quarter each. Nice!  A lot of ECG projects use instrumentation amplifiers like the AD620 (which I have used with [fantastic results](http://www.swharden.com/blog/2012-06-14-multichannel-usb-analog-sensor-with-atmega48/)), but these are expensive (about $5.00 each). The main difference is that instrumentation amplifiers amplify the difference between two points (which reduces noise and probably makes for a better ECG machine), but for today an operational amplifier will do a good enough job amplifying a small signal with respect to ground. I get around the noise issue by some simple filtering techniques. Let's take a look at the circuit.

<div class="text-center img-border">

[![](lm324-opamp-pulse-oximeter-ecg-schematic_thumb.jpg)](lm324-opamp-pulse-oximeter-ecg-schematic.jpg)

</div>

<strong>This project utilizes one of the op-amps as a <a href="http://en.wikipedia.org/wiki/Virtual_ground">virtual ground</a>.</strong> One complaint of using op-amps in simple projects is that they often need + and - voltages. Yeah, this <a href="http://cdn.head-fi.org/8/80/801b6a4a_principle.gif">could be done with two 9V batteries</a> to generate +9V and -9V, but I think it's easier to use a single power source (+ and GND). A way to get around that is to use one of the op-amps as a current source and feed it half of the power supply voltage (VCC), and use the output as a virtual ground (allowing VCC to be your + and 0V GND to be your -). For a good description of how to do this intelligently, read the <a href="http://www.swarthmore.edu/NatSci/echeeve1/Ref/SingleSupply/SingleSupply.html">single supply op amps web page</a>. The caveat is that your signals should remain around VCC/2, which can be done if it is decoupled by feeding it through a series capacitor. The project works at 12V or 5V, but was designed for (and has much better output) at 12V. The remaining 3 op-amps of the LM324 serve three unique functions:

<strong>STAGE 1: High gain amplifier.</strong> The input signals from either the ECG or pulse oximeter are fed into a chain of 3 opamp stages. The first is a preamplifier. The output is decoupled through a series capacitor to place it near VCC/2, and amplified greatly thanks to the 1.8Mohm negative feedback resistor. Changing this value changes initial gain.

<strong>STAGE 2: active low-pass filter.</strong> The 10kOhm variable resistor lets you adjust the frequency cutoff. The opamp serves as a unity gain current source / voltage follower that has high input impedance when measuring the output f the low-pass filter and reproduces its voltage with a low impedance output. There's some <a href="http://www.electronics-tutorials.ws/filter/filter_5.html">more information about active filtering on this page</a>. It's best to look at the output of this stage and adjust the potentiometer until the 60Hz noise (caused by the AC wiring in the walls) is most reduced while the lower-frequency component of your heartbeat is retained. With the oximeter, virtually no noise gets through. Because the ECG signal is much smaller, this filter has to be less aggressive, and this noise is filtered-out by software (more on this later).

<strong>STAGE 3: final amplifier with low-pass filter.</strong> It has a gain of ~20 (determined by the ratio of the 1.8kOhm to 100Ohm resistors) and lowpass filtering components are provided by the 22uF capacitor across the negative feedback resistor. If you try to run this circuit at 5V and want more gain (more voltage swing), consider increasing the value of the 1.8kOhm resistor (wit the capacitor removed). Once you have a good gain, add different capacitor values until your signal is left but the noise reduced. For 12V, these values work fine. Let's see it in action!

<iframe frameborder="0" height="360" src="http://www.youtube.com/embed/bKAJsZJvMI0?list=UUs3-qUELPY-2AOHa7Q_db5w" width="640"></iframe>

<strong>Now for the second half - getting it into the computer.</strong> The cheapest and easiest way to do this is to simply feed the output into a sound card! A sound card is an analog-to-digital converter (ADC) that <em>everybody</em> has and can sample up to 48 thousand samples a second! (overkill for this application) The first thing you should do is add an output potentiometer to allow you to drop the voltage down if it's too big for the sound card (in the case of the oximeter) but but also allow full-volume in the case of sensitive measurements (like ECG). Then open-up sound editing software (I like <a href="http://www.goldwave.com/">GoldWave</a> for Windows or <a href="http://audacity.sourceforge.net/">Audacity</a> for Linux, both of which are free) and record the input. You can do filtering (low-pass filter at 40Hz with a sharp cutoff) to further eliminate any noise that may have sneaked through. Re-sample at 1,000 Hz (1kHz) and save the output as a text file and you're ready to graph it! Check it out.

<iframe frameborder="0" height="360" src="http://www.youtube.com/embed/9BFS9D3x_sY?list=UUs3-qUELPY-2AOHa7Q_db5w" width="640"></iframe>

__Here are the results__ of some actual data recorded and processed with the method shown in the video. let's look at the pulse oximeter first.

<div class="text-center">

[![](pulse-ecg-filtered-a_thumb.jpg)](pulse-ecg-filtered-a.png)

</div>

<strong>That looks pretty good, certainly enough for heartbeat detection.</strong> There's obvious room for improvement, but as a proof of concept it's clearly working. Let's switch gears and look at the ECG. It's much more challenging because it's signal is a couple orders of magnitude smaller than the pulse oximeter, so a lot more noise gets through. Filtering it out offers dramatic improvements!

<div class="text-center">

[![](pulse-oximeter-a_thumb.jpg)](pulse-oximeter-a.png)
[![](pulse-oximeter-b_thumb.jpg)](pulse-oximeter-b.png)

</div>

<strong>Here's the code</strong> I used to generate the graphs from the text files that GoldWave saves. It requires <a href="http://www.Python.org">Python</a>, <a href="http://matplotlib.org/">Matplotlib (pylab)</a>, and <a href="http://www.scipy.org/Download">Numpy</a>. In my case, I'm using 32-bit 2.6 versions of everything.

```python
# DIY Sound Card ECG/Pulse Oximeter
# by Scott Harden (2013) http://www.SWHarden.com

import pylab
import numpy

f=open("light.txt")
raw=f.readlines()[1:]
f.close()

data = numpy.array(raw,dtype=float)
data = data-min(data) #make all points positive
data = data/max(data)*100.0 #normalize
times = numpy.array(range(len(data)))/1000.0
pylab.figure(figsize=(15,5))
pylab.plot(times,data)
pylab.xlabel("Time Elapsed (seconds)")
pylab.ylabel("Amplitude (% max)")
pylab.title("Pulse Oximeter - filtered")
pylab.subplots_adjust(left=.05,right=.98)
pylab.show()
```

<strong>Future directions involve several projects</strong> I hope to work on soon. First, it would be cool to miniaturize everything with surface mount technology (SMT) to bring these things down to the size of a postage stamp. Second, improved finger, toe, or ear clips (or even taped-on sensors) over long duration would provide a pretty interesting way to analyze heart rate variability or modulation in response to stress, sleep apnea, etc. Instead of feeding the signal into a computer, one could send it to a micro-controller for processing. I've made some <a href="http://www.swharden.com/blog/2012-06-14-multichannel-usb-analog-sensor-with-atmega48/">darn-good progress making multi-channel cross-platform USB option for getting physiology data into a computer</a>, but have some work still to do. Alternatively, this data could be graphed on a <a href="http://learn.adafruit.com/system/assets/assets/000/000/899/medium800/graphiclcd.jpg?1342115751">graphical LCD</a> for an all-in-one little device that doesn't require a computer. Yep, lots of possible projects can use this as a starting point.

<strong>Notes about safety:</strong> If you're worried about electrical shock, or unsure of your ability to make a safe device, don't attempt to build an ECG machine. For an ECG to work, you have to make good electrical contact with your skin near your heart, and some people feel this is potentially dangerous. Actually, some people like to argue about how dangerous it actually is, as seen on <a href="http://hackaday.com/2009/08/22/collect-and-analyze-ecg-data/#comments">Hack-A-Day comments</a> and my <a href="http://www.swharden.com/blog/2009-08-14-diy-ecg-machine-on-the-cheap/#comments">previous post comments</a>. Some people have suggested the danger is negligible and pointed-out that it's similar to inserting ear-bud headphones into your ears. Others have suggested that it's dangerous and pointed-out that <a href="http://hypertextbook.com/facts/2000/JackHsu.shtml">milliamps can kill a person</a>. Others contest that pulses of current are far more dangerous than a continuous applied current. Realists speculate that virtually no current would be delivered by this circuit if it is wired properly. Rational, cautionary people worried about it reduce risk of accidental current by applying bidirectional diodes at the level of the chest leads, which short any current (above 0.7V) similar to <a href="http://www.extremecircuits.net/2010/07/ecg-amplifier-by-tlc274.html">that shown here</a>. Electrically-savvy folks would design an optically decoupled solution. Intelligent folks who abstain from arguing on the internet would probably consult the <a href="http://www.analog.com/static/imported-files/tech_articles/MS-2160.pdf">datasheets regarding ECG input protection</a>. In all cases, don't attach electrical devices to your body unless you are confident in their safety. As a catch-all, I present the ECG circuit for educational purposes only, and state that it may not be safe and should not be replicated  There, will that cover me in court in case someone tapes wires to their chest and plugs them in the wall socket?

<strong>LET ME KNOW WHAT YOU THINK!</strong> If you make this, I'm especially interested to see how it came out. Take pictures of your projects and send them my way! If you make improvements, or take this project further, I'd be happy to link to it on this page. I hope this page describes the project well enough that anyone can recreate it, regardless of electronics experience. Finally, I hope that people are inspired by the cool things that can be done with surprisingly simple electronics. Get out there, be creative, and go build something cool!
January 6th, 2013

AVR Programming in Linux

It is not difficult to program ATMEL AVR microcontrollers with linux, and I almost exclusively do this because various unofficial (inexpensive) USB AVR programmers are incompatible with modern versions of windows (namely Windows Vista and Windows 7). I am just now setting-up a new computer station in my electronics room (running Ubuntu Linux 12.04), and to make it easy for myself in the future I will document everything I do when I set-up a Linux computer to program microcontrollers.

Install necessary software

sudo apt-get install gcc-avr avr-libc uisp avrdude

Connect the AVR programmer

This should be intuitive for anyone who has programmed AVRs before. Visit the datasheet of your MCU, identify pins for VCC (+), GND (-), MOSI, MISO, SCK, and RESET, then connect them to the appropriate pins of your programmer.

Write a simple program in C

I made a file "main.c" and put the following inside. It's the simplest-case code necessary to make every pin on PORTD (PD0, PD1, ..., PD7) turn on and off repeatedly, sufficient to blink an LED.

#include <avr/io.h>
#include <util/delay.h>

int main (void)
{
 DDRD = 255; // MAKE ALL PORT D PINS OUTPUTS

 while(1) {
  PORTD = 255;_delay_ms(100); // LED ON
  PORTD = 0;  _delay_ms(100); // LED OFF
 }

 return 0;
}

Compile the code (generate a HEX file)

avr-gcc -w -Os -DF_CPU=2000000UL -mmcu=atmega8 -c -o main.o main.c
avr-gcc -w -mmcu=atmega8 main.o -o main
avr-objcopy -O ihex -R .eeprom main main.hex

note that the arguments define CPU speed and chip model - this will need to be customized for your application

Program the HEX firmware onto the AVR

sudo avrdude -F -V -c avrispmkII -p ATmega8 -P usb -U flash:w:main.hex

note that this line us customized based on my connection (-P flag, USB in my case) and programmer type (-c flag, AVR ISP mkII in my case)

When this is run, you will see something like this:

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9307
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: input file main.hex auto detected as Intel Hex
avrdude: writing flash (94 bytes):

Writing | ################################################## | 100% 0.04s

avrdude: 94 bytes of flash written

Your Program should now be loaded!

Sit back and watch your LED blink.

  • TIP 1: I'm using a clone AVRISP mkII from Fun4DIY.com which is only $11 (shipped!). I glued it to a perf-board with a socket so I can jumper its control pins to any DIP AVR (80 pins or less). I also glued a breadboard for my convenience, and added LEDs (with ground on one of their pins) for easy jumpering to test programs. You can also build your own USB AVR ISP (free schematics and source code) from the USBtinyISP project website.

  • TIP 2: Make a shell script to run your compiling / flashing commands with a single command. Name them according to architecture. i.e., "build-m8" or "build-t2313". Make the first line delete all .hex files in the directory, so it stalls before it loads old .hex files if the compile is unsuccessful. Make similar shell scripts to program fuses. i.e., "fuse-m8-IntClock-8mhz", "fuse-m8-IntClock-1mhz", "fuse-m8-ExtCrystal".

  • TIP 3: Use a nice text editor well suited for programming. I love Geany.

Markdown source code last modified on January 18th, 2021
---
title: AVR Programming in Linux
date: 2013-01-06 14:51:19
tags: microcontroller, old
---

# AVR Programming in Linux

__It is not difficult to program ATMEL AVR microcontrollers with linux, and I almost exclusively do this because various unofficial (inexpensive) USB AVR programmers are incompatible with modern versions of windows (namely Windows Vista and Windows 7).__ I am just now setting-up a new computer station in my electronics room (running Ubuntu Linux 12.04), and to make it easy for myself in the future I will document everything I do when I set-up a Linux computer to program microcontrollers.

<div class="text-center img-border">

[![](mcu-programmer-far_thumb.jpg)](mcu-programmer-far.jpg)

</div>

### Install necessary software

```bash
sudo apt-get install gcc-avr avr-libc uisp avrdude
```

### Connect the AVR programmer

This should be intuitive for anyone who has programmed AVRs before. Visit the datasheet of your MCU, identify pins for VCC (+), GND (-), MOSI, MISO, SCK, and RESET, then connect them to the appropriate pins of your programmer.

### Write a simple program in C

I made a file "main.c" and put the following inside. It's the simplest-case code necessary to make every pin on PORTD (PD0, PD1, ..., PD7) turn on and off repeatedly, sufficient to blink an LED.

```c
#include <avr/io.h>
#include <util/delay.h>

int main (void)
{
 DDRD = 255; // MAKE ALL PORT D PINS OUTPUTS

 while(1) {
  PORTD = 255;_delay_ms(100); // LED ON
  PORTD = 0;  _delay_ms(100); // LED OFF
 }

 return 0;
}
```

### Compile the code (generate a HEX file)

```bash
avr-gcc -w -Os -DF_CPU=2000000UL -mmcu=atmega8 -c -o main.o main.c
avr-gcc -w -mmcu=atmega8 main.o -o main
avr-objcopy -O ihex -R .eeprom main main.hex
```

_note that the arguments define CPU speed and chip model - this will need to be customized for your application_

### Program the HEX firmware onto the AVR

```bash
sudo avrdude -F -V -c avrispmkII -p ATmega8 -P usb -U flash:w:main.hex
```

_note that this line us customized based on my connection (-P flag, USB in my case) and programmer type (-c flag, AVR ISP mkII in my case)_

When this is run, you will see something like this:

```
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9307
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: input file main.hex auto detected as Intel Hex
avrdude: writing flash (94 bytes):

Writing | ################################################## | 100% 0.04s

avrdude: 94 bytes of flash written
```

### Your Program should now be loaded!

Sit back and watch your LED blink.

<div class="text-center img-border">

[![](mcu-programmer-close_thumb.jpg)](mcu-programmer-close.jpg)

</div>

* __TIP 1:__ I'm using a clone AVRISP mkII from [Fun4DIY.com](http://fun4diy.com/AVRISP_mkII.htm) which is only $11 (shipped!). I glued it to a perf-board with a socket so I can jumper its control pins to any DIP AVR (80 pins or less). I also glued a breadboard for my convenience, and added LEDs (with ground on one of their pins) for easy jumpering to test programs. You can also build your own USB AVR ISP (free schematics and source code) from the [USBtinyISP](http://www.ladyada.net/make/usbtinyisp/) project website.

* __TIP 2:__ Make a shell script to run your compiling / flashing commands with a single command. Name them according to architecture. i.e., "build-m8" or "build-t2313". Make the first line delete all .hex files in the directory, so it stalls before it loads old .hex files if the compile is unsuccessful.  Make similar shell scripts to program fuses. i.e., "fuse-m8-IntClock-8mhz", "fuse-m8-IntClock-1mhz", "fuse-m8-ExtCrystal".

* __TIP 3:__ Use a nice text editor well suited for programming. I love [Geany](http://www.geany.org/).
December 18th, 2012

My DIY Bench Power Supply

Another thing everybody needs (and has probably built) is a simple laboratory bench power supply. A lot of people use things like modified PC power supplies but I wasn't in favor of this because I wanted something smaller, lower current, and cleaner (from an RF perspective). My needs are nothing particularly high power, just something to provide a few common voltages for digital logic and small RF circuits. This is what I came up with!

In the image above you can see an ordinary LED being powered directly from the a 5V hook-up. There is no current limiting resistor, so a lot of current is travelling through the LED, burning it up as I photographed it. The ammeter (blue number) shows it's drawing 410 mA - whoa! The layout is pretty simple. Each red banana plug hook-up supplies a voltage (5, 5, 12, and variable respectively). Black hook-ups are ground. The black hook-up on the top left is a current-sensing ground, and current travelling through it will be displayed on the blue dial. The right dial shows the voltage of the variable voltage supply, and can go from about 3.5 - 30.5 V depending on where the potentiometer is set. All voltage outputs are designed to put-out approximately 1A of current.

I built this using a lot of (eBay) components I had on hand. I often save money where I can by stocking my workbench with components I buy in bulk. Here's what I used:

  • 4.5-3.0V DC volt meter - $2.08 (shipped) eBay
  • 0-9.99 A ampere meter - $4.44 (shipped) eBay
  • L7805 5V voltage regulator - 10 for $3.51 ($.35 ea) (shipped) eBay
  • L7812 12V voltage regulator - 20 for $3.87 ($.19 ea) (shipped) eBay
  • LM317 variable voltage regulator - 20 for $6.15 ($0.30 ea) (shipped) eBay
  • 10k linear potentiometer - 10 for 4.00 ($.40 ea) (shipped) eBay
  • banana plug hook-ups - 20 for $3.98 ($.20 ea) (shipped) eBay
  • aluminum enclosure - $3.49 (radioshack)

TOTAL: $13.60

Does the variable voltage actually work? Is the voltmeter accurate? Let's check it out.

I'd say it's working nicely! I now have a new took on my workbench.

A note about the yellow color: The enclosure I got was originally silver aluminum. I sanded it (to roughen the surface), then sprayed it with a yellow rustoleum spray paint. I figured it was intended to go on metal, so I might as well give it a shot. I sprayed it once, then gave it a second coat 20 minutes later, then let it dry overnight. In the future I think I would try a lacquer finish, because it's a bit easy to scratch off. However, it looks pretty cool, and I'm going to have to start spray-painting more of my enclosures in the future.

A note about smoothing capacitors. Virtually all diagrams of linear voltage regulators like the LM7805 show decoupling capacitors before and after the regulator. I added a few different values of capacitors on the input (you can see them in the circuit), but I intentionally did not include smoothing capacitors on the output. The reason was that I always put smoothing capacitors in my breadboards and in my projects, closer to the actual circuitry. If I included (and relied) on output capacitors at the level of the power supply, I would be picking-up 60Hz (and other garbage) RF noise in the cables coming from the power supply to my board. In short, no capacitors on the output, so good design must always be employed and decoupling capacitors added to whatever circuits are being built.

The input of this circuit is a 48V printer power supply from an archaic inkjet printer. It's been attached to an RCA jack to allow easy plugging and unplugging.

Markdown source code last modified on January 18th, 2021
---
title: My DIY Bench Power Supply
date: 2012-12-18 11:30:27
tags: circuit
---

# My DIY Bench Power Supply

__Another thing everybody needs (and has probably built) is a simple laboratory bench power supply.__ A lot of people use things like [modified PC power supplies](http://web2.murraystate.edu/andy.batts/ps/powersupply.htm) but I wasn't in favor of this because I wanted something smaller, lower current, and cleaner (from an RF perspective).  My needs are nothing particularly high power, just something to provide a few common voltages for digital logic and small RF circuits.  This is what I came up with!

<div class="text-center img-border">

[![](5_thumb.jpg)](5.jpg)

</div>

In the image above you can see an ordinary LED being powered directly from the a 5V hook-up.  There is no current limiting resistor, so a lot of current is travelling through the LED, burning it up as I photographed it. The ammeter (blue number) shows it's drawing 410 mA - whoa!  The layout is pretty simple. Each red banana plug hook-up supplies a voltage (5, 5, 12, and variable respectively). Black hook-ups are ground. The black hook-up on the top left is a current-sensing ground, and current travelling through it will be displayed on the blue dial.  The right dial shows the voltage of the variable voltage supply, and can go from about 3.5 - 30.5 V depending on where the potentiometer is set. All voltage outputs are designed to put-out approximately 1A of current.

<div class="text-center img-border">

[![](1_thumb.jpg)](1.jpg)

</div>

__I built this using a lot of (eBay) components I had on hand.__ I often save money where I can by stocking my workbench with components I buy in bulk. Here's what I used:

*   4.5-3.0V DC volt meter - $2.08 (shipped) eBay
*   0-9.99 A ampere meter - $4.44 (shipped) eBay
*   L7805 5V voltage regulator - 10 for $3.51 ($.35 ea) (shipped) eBay
*   L7812 12V voltage regulator - 20 for $3.87 ($.19 ea) (shipped) eBay
*   LM317 variable voltage regulator - 20 for $6.15 ($0.30 ea) (shipped) eBay
*   10k linear potentiometer - 10 for 4.00 ($.40 ea) (shipped) eBay
*   banana plug hook-ups - 20 for $3.98 ($.20 ea) (shipped) eBay
*   aluminum enclosure - $3.49 (radioshack)

TOTAL: $13.60

<div class="text-center">

![](LM317.gif)

</div>

Does the variable voltage actually work? Is the voltmeter accurate? Let's check it out.

<div class="text-center img-border">

[![](4_thumb.jpg)](4.jpg)

</div>

I'd say it's working nicely!  I now have a new took on my workbench.

<div class="text-center img-border">

[![](6_thumb.jpg)](6.jpg)

</div>

__A note about the yellow color:__ The enclosure I got was originally silver aluminum. I sanded it (to roughen the surface), then sprayed it with a yellow rustoleum spray paint. I figured it was intended to go on metal, so I might as well give it a shot. I sprayed it once, then gave it a second coat 20 minutes later, then let it dry overnight. In the future I think I would try a lacquer finish, because it's a bit easy to scratch off.  However, it looks pretty cool, and I'm going to have to start spray-painting more of my enclosures in the future.

<div class="text-center">

![](rust.jpg)

</div>

__A note about smoothing capacitors.__ Virtually all diagrams of linear voltage regulators like the LM7805 show decoupling capacitors before and after the regulator. I added a few different values of capacitors on the input (you can see them in the circuit), but I intentionally did _not_ include smoothing capacitors on the output. The reason was that I always put smoothing capacitors in my breadboards and in my projects, closer to the actual circuitry. If I included (and relied) on output capacitors at the level of the power supply, I would be picking-up 60Hz (and other garbage) RF noise in the cables coming from the power supply to my board. In short, no capacitors on the output, so good design must always be employed and decoupling capacitors added to whatever circuits are being built.

__The input__ of this circuit is a 48V printer power supply from an archaic inkjet printer. It's been attached to an RCA jack to allow easy plugging and unplugging.
December 6th, 2012

Single Wavelength Pulse Oximeter

⚠️ Check out my newer ECG designs:

I want to create a microcontroller application which will utilize information obtained from a home-brew pulse oximeter. Everybody and their cousin seems to have their own slant how to make DIY pulse detectors, but I might as well share my experience. Traditionally, pulse oximeters calculate blood oxygen saturation by comparing absorbance of blood to different wavelengths of light. In the graph below (from Dildy et al., 1996 that deoxygenated blood (dark line) absorbs light differently than oxygenated blood (thin line), especially at 660nm (red) and 920nm (infrared). Therefore, the ratio of the difference of absorption at 660nm vs 920nm is an indication of blood oxygenation. Fancy (or at least well-designed) pulse oximeters continuously look at the ratio of these two wavelengths. Analog devices has a nice pulse oximeter design using an ADuC7024 microconverter. A more hackerish version was made and described on this non-english forum. A fail-at-the-end page of a simpler project is also shown here, but not well documented IMO.

That's not how mine works. I only use a single illumination source (~660nm) and watch it change with respect to time. Variability is due to a recombination effect of blood volume changes and blood oxygen saturation changes as blood pulses through my finger. Although it's not quite as good, it's a bit simpler, and it definitely works. Embedded-lab has a similar project but the output is only a pulsing LED (not what I want) and a voltage output that only varies by a few mV (not what I want).

Here's what the device looks like assembled in a breadboard:

I made a sensor by drilling appropriately-sized holes in a clothespin for the emitter (LED) and sensor (phototransistor). I had to bend the metal spring to make it more comfortable to wear. Light pressure is better than firm pressure, not only because it doesn't hurt as much, but because a firm pinch restricts blood flow considerably.

An obvious next step is microcontroller + LCD (or computer) digitization, but for now all you can do is check it out on my old-school analog oscilloscope. Vertical squares represent 1V (nice!). You can see the pulse provides a solid 2V spike.

Here's some video of it in action:

I'm holding-back the circuit diagram until I work through it a little more. I don't want to mislead people by having them re-create ill-conceived ideas on how to create analog amplifiers. I'll post more as I develop it.

Markdown source code last modified on January 18th, 2021
---
title: Single Wavelength Pulse Oximeter
date: 2012-12-06 08:13:41
tags: circuit, diyECG, old
---

# Single Wavelength Pulse Oximeter

> **⚠️ Check out my newer ECG designs:** 
* [**Sound Card ECG with AD8232**](https://swharden.com/blog/2019-03-15-sound-card-ecg-with-ad8232/)
* [**Single op-amp ECG**](https://swharden.com/blog/2016-08-08-diy-ecg-with-1-op-amp/)

__I want to create a microcontroller application__ which will utilize information obtained from a home-brew pulse oximeter. Everybody and their cousin seems to have their own slant how to make DIY pulse detectors, but I might as well share my experience. Traditionally, pulse oximeters calculate blood oxygen saturation by comparing absorbance of blood to different wavelengths of light. In the graph below (from [Dildy et al., 1996](http://www.ncbi.nlm.nih.gov/pubmed/8694032) that deoxygenated blood (dark line) absorbs light differently than oxygenated blood (thin line), especially at 660nm (red) and 920nm (infrared). Therefore, the ratio of the difference of absorption at 660nm vs 920nm is an indication of blood oxygenation. Fancy (or at least well-designed) pulse oximeters continuously look at the ratio of these two wavelengths. Analog devices has a [nice pulse oximeter design using an ADuC7024 microconverter](http://www.analog.com/library/analogDialogue/archives/41-01/pulse_oximeter.html). A more hackerish version was made and described [on this non-english forum](http://www.elektroda.pl/rtvforum/viewtopic.php?p=8025042). A fail-at-the-end page of a simpler project is also shown [here](http://blog.energymicro.com/2012/11/21/create-a-simple-pulse-oximeter-with-tiny-gecko/), but not well documented IMO.

<div class="text-center">

![](pulse-oximeter-wavelength.jpg)

</div>

That's not how mine works. I only use a single illumination source (~660nm) and watch it change with respect to time. Variability is due to a recombination effect of blood volume changes and blood oxygen saturation changes as blood pulses through my finger. Although it's not quite as good, it's a bit simpler, and it definitely works. [Embedded-lab has a similar project](http://embedded-lab.com/blog/?p=5508) but the output is only a pulsing LED (not what I want) and a voltage output that only varies by a few mV (not what I want).

__Here's what the device looks like assembled in a breadboard:__


<div class="text-center img-border img-medium">

[![](IMG_5919_thumb.jpg)](IMG_5919.jpg)

</div>

__I made a sensor__ by drilling appropriately-sized holes in a clothespin for the emitter (LED) and sensor (phototransistor). I had to bend the metal spring to make it more comfortable to wear. Light pressure is better than firm pressure, not only because it doesn't hurt as much, but because a firm pinch restricts blood flow considerably.

<div class="text-center img-border img-small">

[![](IMG_5920_thumb.jpg)](IMG_5920.jpg)
[![](IMG_5924_thumb.jpg)](IMG_5924.jpg)

</div>

__An obvious next step__ is microcontroller + LCD (or computer) digitization, but for now all you can do is check it out on my old-school analog oscilloscope. Vertical squares represent 1V (nice!). You can see the pulse provides a solid 2V spike.

<div class="text-center img-border img-medium">

![](pulse-scope.jpg)

</div>

__Here's some video of it in action:__

![](https://www.youtube.com/embed/MwkR_Vv0wMA)

I'm holding-back the circuit diagram until I work through it a little more. I don't want to mislead people by having them re-create ill-conceived ideas on how to create analog amplifiers. I'll post more as I develop it.
Pages