BioSlam (2017 PPG version)

In this workshop we’ll use the Arduino Nano to build an ultra low-cost heart rate monitor. The signal we’ll actually be measuring is called the photoplethysmogram (PPG). This signal captures small changes in the volume of some part of the body caused by the variation in blood pressure that occurs when the heart beats. These changes are detected by shining light into the skin and measuring how much is reflected back and how much is absorbed. In our device, the light will come from a TCRT5000 infrared reflective sensor. The TCRT5000 contains two electronic components – an infrared LED, which will shine light into the finger, and an infrared phototransistor, which will measure how much is reflected back.

Circuit Construction

Begin by orienting your breadboard so that it appears as shown below, with row 1 on the left and row 30 on the right.

Insert the Arduino Nano as far to the right as possible, as shown below. Pin D12 (of the Arduino) should be in hole D30 (of the breadboard).

Power will be supplied to the circuit from the USB socket of a laptop, via the Arduino. Insert the power connections from the Arduino to the breadboard rails as shown below.

  1. A short red wire from J19 to the positive (red) rail beside it.
  2. A long red wire from J19 to the positive (red) rail on the opposite side of the breadboard.
  3. A short black wire from J17 to the negative (blue) rail beside it.
  4. A short black wire from A19 to the negative (blue) rail beside it.

Plug the TCRT5000 reflective infrared sensor into holes E1, E2, F1 and F2, as shown below.

Please ensure that the TCRT5000 is inserted the correct way around. The image below shows the correct orientation of the TCRT5000, viewed from a different angle. Note the letters “TCRT5000” are written on the side of the sensor closest to the end of the breadboard.

Add the power connections and resistors for the TCRT5000 sensor, as shown below.

  1. A short black wire from J1 to the negative (blue) rail beside it.
  2. A 1 kΩ resistor (BROWN, BLACK, RED, GOLD) between J2 and the positive (red) rail beside it.
  3. A short red wire from A2 to the positive (red) rail beside it.
  4. A 220 Ω resistor (RED, RED, BROWN, GOLD) between A1 and the negative (blue) rail beside it.

Insert three 100 kΩ resistors to form a voltage divider that will set the resting voltage of the PPG signal.

  1. A 100 kΩ resistor (BROWN, BLACK, YELLOW, GOLD) between J5 and the negative (blue) rail beside it.
  2. A 100 kΩ resistor (BROWN, BLACK, YELLOW, GOLD) between E5 and F5.
  3. A 100 kΩ resistor (BROWN, BLACK, YELLOW, GOLD) between A5 and the positive (red) rail beside it.

Insert the LM358 operational amplifier chip (the 8-pin microchip) and its power connections.

  1. Insert the LM358 chip so that pin 1 (one of the corner pins) is in E7 and pin 5 (the diagonally opposite corner) is in F10. There is a small semi-circular indentation at one end of the upper surface of the chip. This semi-circular indentation must be at row 7. If the chip is the wrong way around, the circuit will not work and the chip may get burned out.
  2. A short red wire between J7 and the positive (red) rail beside it.
  3. A short black wire between A10 and the negative (blue) rail beside it.

Insert the feedback network for the amplifier. This part of the circuit will control which frequencies are amplified and by how much.

  1. The 100 nF capacitor (the small blue component with two legs) between J11 and J13.
  2. A 100 kΩ resistor (BROWN, BLACK, YELLOW, GOLD) between I11 and I13.
  3. A short green wire between H9 and H13.
  4. A short green wire between E13 and F13.
  5. A 220 Ω resistor (RED, RED, BROWN, GOLD) between A12 and the negative (blue) rail beside it.
  6. A 220 μF capacitor (the cylindrical black component that stands on two short legs) with its negative leg in C12 and its positive leg in C13. Note that this capacitor is polarised, so it must be inserted the right way around.

To ensure that the capacitor has been inserted the right way around, check that it appears the same as the one below. Note the white stripe (with minus signs) on the same side of the capacitor as the negative leg.

We’re almost done. We just need to add connections between the different parts of the circuit so that the signal can flow through the circuit from the sensor, through the amplifier, to the Arduino.

Connect the sensor output to the voltage divider and onwards to the operational amplifier.

  1. A short yellow wire between F3 and G5.
  2. A short yellow wire between I5 and I10.
  3. A 220 μF capacitor (the cylindrical black component that stands on two short legs) with its positive leg in H2 and its negative leg in H3. As before, this capacitor is polarised, so it must be inserted the right way around.

To ensure that the capacitor has been inserted the right way around, check that it appears the same as the one below. Note the white stripe (with minus signs) on the same side of the capacitor as the negative leg.

Finally, we add wires to connect the output of the operational amplifier to the feedback network and the analog input of the Arduino.

  1. A short blue wire between G8 and G11.
  2. A long blue wire between J8 and J20.

The circuit is now ready to be connected to the laptop so that we can program the Arduino and display the PPG signal.

Connect the Arduino to the laptop using the mini USB cable, as shown below.

Arduino Code

Program the code shown below onto the Arduino. It will make the Arduino sample (or measure) the voltage on pin its analog input pin A7 approximately 100 times per second. Each time the voltage is measured by the Arduino, it is converted into a number between 0 (representing 0V) and 1023 (representing 5V), which is then transmitted to the PC via the USB cable.

//
// BioSlam Arduino Code - written by Ted Burke 10-5-2017
//

void setup()
{
// Open serial connection to send data to PC
Serial.begin(9600);
}

void loop()
{
int v;

// Read the analog voltage on pin A7
v = analogRead(A7);

// Send the measured voltage to the PC
Serial.println(v);

delay(20);
}

Processing Code

To display the PPG signal on the PC we will use a programming language called “Processing”, which provides a relatively easy way of receiving the stream of numbers transmitted by the Arduino and drawing graphics on the computer screen to visualise them as a waveform.

To launch the Processing development environment, open the folder “C:\RoboSlam\processing-3.3.3\” and double-click on “processing.exe”.

Paste the following code into Processing and click button with the right arrowhead symbol to run it. Hopefully a graph will appear displaying your waveform. When you place your fingertip on the sensor, it takes a minute for the amplifier to settle before it begins recording the signal, so be patient!

//
// BioSlam PPG plotting program
//
// Adapted by Ted Burke from Tom Igoe's example at:
// https://www.arduino.cc/en/tutorial/graph
//

import processing.serial.*;

int n;             // Serial port number
Serial port;       // Serial port object
int x, y;          // Present x,y position on the graph
int x_erase;       // x position of waveform eraser
float voltage = 0; // The voltage reported by the Arduino

void setup ()
{
size(400, 300); // set the window size

// Open highest available serial port number and tell it to only
// generate an event each time it receives a full line of text
n = Serial.list().length - 1;
port = new Serial(this, Serial.list()[n], 9600);
port.bufferUntil('\n');

x = 1; // start drawing at left side of graph
background(0); // wipe the background of the graph
}

void draw ()
{
// Add the current point to the waveform
stroke(0, 255, 0);     // Set line colour
line(x, height, x, y); // draw the line
//ellipse(x, y, 3, 3); // draw points as dots

// Erase the waveform a little ahead of current x
stroke(0, 0, 0);
x_erase = (x + 10) % width;
line(x_erase, 0, x_erase, height);

// Move forward one pixel at a time
x = x + 1;
if (x > width) x = 0;
}

void serialEvent (Serial port)
{
String line = port.readStringUntil('\n');    // read a line of text
if (line == null) return;                    // if line is blank just do nothing
line = trim(line);                           // trim off any whitespace:
voltage = float(line);                       // convert text to a number
y = height - int(height * voltage / 1023.0); // scale values to graph height
}