The holiday season comes every year and there are hundreds of Christmas tree projects out there every year. So, we wanted to make our own version of an interactive Christmas tree. Today, as it is time to taken down our tree, we wanted to show how we made the tree work. So, here is a Christmas tree that beats along with your heart.
PPG, blood oxygen and heart rateThe heart-beat is derived optically from a sensor that senses your pulse. For pulse sensing, we used the ProtoCentral Pulse+ Pulse-Ox and Heart Rate sensor based on MAX30102, which provides a digital signal stream of the PPG (photo-plethysmogram) that is similar to the ECG (electro-cardiograph) signal, but instead of sticking electrodes on the body, this device optically measures the amount of blood pulsing through your blood vessels. Since this is not electrically connected to the body, this is safer and easier to use than ECG. The output from the ProtoCentral Pulse+ Pulse-Ox and Heart Rate sensor based on MAX30102 can be seen the following figure:
What you see above is our GUI running the receiving software for the Pulse sensor. When a finger is placed on the sensor, the red and IR LEDs on the device alternatively bounce signals off of your finger bone, while a photo-detector picks up the intensity of the reflected light. Some of it is absorbed by the blood and some it gets reflected back to the photo-detector on the device. The amount of light absorption by the blood corresponds to the amount of blood oxygen.
We hooked up one of our Pulse+ sensors to an Adafruit Flora through the two I2C lines for data transfer. The Flora is also connected through a single pin to a WS2812B-based addressable RGB LED strip, Neopixel compatible with 30 LEDs/meter. We used two strips connected in series, for a total of 60 LEDs. The strip itself is powered by a separate 5V, 5A power supply as the power from an Arduino's supply is not be enough to drive 60 LEDs. This strip is the one wrapped around the tree to light it up.
Connections are made as follows:
- Pulse+ sensor power and ground connected to the Flora's 3.3V and GND pins
- Pulse+ sensor SDA and SCL lines connected to the Flora's SDA (#2) and SCL pind (#3) respectively
- The WS2812B strip's data line is connected to pin number 5 on the Flora and GND is connected to the GND pin.
The chart below shows the absorption spectra of the two wavelengths in the blood. The absorption is just only because of the blood, but also the skin and is components. The amount of absorption of the RED wavelength (660 nm) is more by the de-oxygenated haemoglobin (that carries oxygen in the blood), hence is a lower amount of light reflected, while the Infra-RED wavelength (940 nm) is absorbed more by the Oxygenated Haemoglobin. For our application, since we were only interested in the amount of blood flowing, we chose only the RED absorption. If doing a complete pulse-oximetry measurement, both the RED and Infra-RED reflected intensities would be required.
In our code, we have used only the RED samples and map them directly to drive a WS2812 RGB LED strip. In addition, the heart-rate is also calculated by detecting the R-R peaks. The heart-rate is used to change the colour of the LEDs.
You can find the complete Arduino sketch attached in the sections below this article. The algorithm to calculate the heart rate is based on the example code provided by Maxim Integrated. The heart is calculated because the colour of the LEDs also changes with the current heart rate.
//take 25 sets of samples before calculating the heart rate.
for(i=75;i<100;i++)
{
un_prev_data=aun_red_buffer[i-1];
sensor.readSensor(); //read sensor
REDD=sensor.RED;
aun_red_buffer[i] = REDD;
//calculate the brightness of the LED
if(aun_red_buffer[i]>un_prev_data)
{
f_temp=aun_red_buffer[i]-un_prev_data;
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
f_temp=un_brightness-f_temp;
if(f_temp<0)
un_brightness=0;
else
un_brightness=(int)f_temp;
}
else
{
f_temp=un_prev_data-aun_red_buffer[i];
f_temp/=(un_max-un_min);
f_temp*=MAX_BRIGHTNESS;
un_brightness+=(int)f_temp;
if(un_brightness>MAX_BRIGHTNESS)
un_brightness=MAX_BRIGHTNESS;
}
The intensity of the signal is also directly mapped to the brightness of all LEDs in the WS2812 addressable RGB strip, by some simple divisor logic to bring the values into bounds of the Neopixel brightness levels.
for(int i=0;i<NUMPIXELS;i++)
{
LED.setPixelColor(i, 0, un_brightness/BRIGHTNESS_DIVISOR, 0);
LED.show();
}
The result is an LED strip whose brightness corresponds to the corrected intensity of the RED signal waveform from the MAX30102 sensor. Because this is also mapped continuously to the brightness, it causes a "fading-in" and "fading-out" effect on the lights, resulting in a sense of the tree pulsing along with your heart!
ResultsIt worked ! We got a nice effect of the pulsing of the tree along with our heartbeat. Check out the end results in the following video.
We even cross-checked this to make sure that the pulse duration is the same as the pulse duration obtained from R-R spacing in an ECG. So, we connected the same subject to a Welch-Allyn hospital patient monitor (borrowed from a hospital) to compare results from ECG taken simultaneously from two chest-worn electrodes. If you turn up the volume while watching the below video, you will notice the correlation between the "beeps" from the patient monitor and the pulsing Christmas tree. We found it to be quite accurate.
Thanks for reading and if you have any suggestions, or you want us to post more details, please let us know in the comments below.
Comments