Upload
duongkien
View
225
Download
0
Embed Size (px)
Citation preview
Drowsiness Detection/Driver Safety System
EENG 491
Professors: Dr. Tao Zhang & Dr. Michael Colef
Spring 2014
Matthew Wolfe, Denzel McGue & Yiyang Ma
Table of Contents
Introduction & Motivation……………………………………………………………………....Page 3
Design………………………………………………………………………………………………….…..Page 4
Jobs………………………………………………………………………………………………………….Page 4
Arduino……………………..……………………………………………………………………….…...Page 5
Pulse Sensor…………………………………………………………………………………………..…Page 6
Motion Sensor……………….……………………………………………………………………...…Page 8
Temperature Sensor………………………………………….………………………………..….Page 10
Carbon Monoxide Sensor.…….….………………………………………………………..…..Page 12
Alcohol Sensor……………………………………………………………………………………..…Page 14
System Design……………………………………………………………………………………..…Page 17
Pulse Sensor Block Diagram……………………………………………………………….…..Page 18
Motion Sensor Block Diagram………………………………………………………….…….Page 19
Temperature Sensor Block Diagram……………………….….............................Page 19
Carbon Monoxide Sensor Block Diagram……….....……………………………….....Page 20
Alcohol Sensor Block Diagram………………………………………………………………..Page 21
Data Outputs……………………………………………………………………………………….…Page 21
Software Code………………………………………………………………………………………..Page 34
Future Plans……………………………………………………………………………………………Page 51
Conclusion……………………………………………..……………………………………………...Page 52
References & Citations……………………………..…………………………………………….Page 52
Project Members
Matthew Wolfe (Group Leader)
Denzel McGue
Yiying Ma
Motivation
Our design group became interested in this topic after so many recent crashes and deaths of
people falling asleep at the wheel. Driving a car can be considered one of the most dangerous things
millions of people do every single day and with people working long hours all day, they have a tendency
to fall asleep making an already dangerous situation even more riskier. According to the U.S National
Highway Traffic Safety Administration, drowsy driving causes more than 100,000 crashes per year. These
accidents result in an estimated 71,000 injuries, 1,550 deaths and $12.5 billion dollars in monetary loss.
In a recent study done by Virginia Tech, drivers were tested over the course of a year and they found
drowsy driving to be the cause of at least 20% of all accidents. Technology is out there that can detect
movement, vital signs and facial recognition that can be used in another way to detect if a driver is
drowsy or not. As engineers, we see an opportunity to take these technologies that already exist and
combine them together to develop a system to detect drowsiness and prevent these unfortunate
accidents. The true innovation is taking materials that we use on a daily basis and putting them together
for different uses. Developing something entirely new can be a very daunting task. As well as detecting
drowsiness, we also want to focus on providing a safe environment for all drivers including the detection
of alcohol and carbon monoxide. There are thousands of accidents due to drunk driving and hundreds of
deaths due to unintentional carbon monoxide poisoning that could all be prevented if the right
measures are taken.
Our group, (Matt, Denzel and Yiying) has designed a system for detecting drowsiness along with
driver safety, and the presence of alcohol and carbon monoxide by using sensors wired up to an Arduino
Mega. Our system has sensors to check if the vehicle is safe to operate. The Arduino board
communicates with the sensors displaying if the driver is alert enough to drive and if the vehicle is safe
to operate. Connected to the board are pulse sensors, alcohol sensors, carbon monoxide sensors,
temperature sensors and motion sensors. These sensors combined test the current conditions inside the
vehicle and detect if the driver is getting drowsy.
System Design
Our system design contains a variety of sensors testing for driver drowsiness and safety. After
doing extensive research, our group compiled a list of symptoms attributed to drowsy driving and
common driving hazards. Using pulse, motion, temperature, carbon monoxide and alcohol sensors, we
can test for these symptoms and conditions. These sensors are mounted around a mounted steering
wheel that read and analyze the conditions which produces feedback to alert the driver of any hazards.
All of the sensors are connected to a Karlsson Robotics Arduino Mega 2560.
Jobs
Matt: (Group Leader) Research, Report, PowerPoint, Software
Denzel: Research, PowerPoint, Designing/Wiring, Software
Yiying: Research, PowerPoint, Assisted with Wiring
Arduino
We chose the Arduino Mega 2560 because of its versatility and functionality. With a lot of
sensors, LEDs, wires and communication involved, this board supports all the input/output pins
necessary to have everything connected and powered. This board supports more input/outputs than a
basic Arduino Uno.
The top image is what the board actually looks like
and the bottom image is the schematic of the board layout with all of the pins and headers attached.
Pulse Sensor
When you fall asleep, your pulse decreases significantly as your body is required to perform less
physical and mental tasks. A pulse sensor can detect if a driver’s pulse drops significantly when they are
driving indicating that they are becoming less alert slowly beginning to fall asleep or are in fact sleeping.
In our design, we have placed a pulse sensor mounted on the steering wheel that clips onto a driver’s
index finger to test their pulse/beats per minute. We came together and all agreed on using the same
principal of how a heart rate device works on a piece of exercise equipment. On a treadmill or bike, a
user will place their hands or fingers over a sensor to get a reading of the heart rate or pulse. The driver
can place his or her hands on the steering wheel as they usually would while the pulse sensors pick up a
pulse from your fingers. Usually pulse sensors are large, bulky and take up too much space but after
researching we found small ones that connect to the tip of your finger. After finding some different
finger sensors, we found ones that were compatible with an Arduino board. All the driver has to do is
put their hands on the wheel and the sensor will begin taking a reading. The information will be sent
back to the board and it will interpret if the pulse is too low. If it is too low, it will interpret that the
driver may be falling asleep or is actually sleeping and will send an alert to the driver via an LED and a
buzzer. The pulse of the driver will also go in conjunction with the LEDs and the buzzer. The green LED
shows the pulse and the red LED shows the fade of the pulse. The buzzer will beep along with the pulse.
When the driver takes their finger off of the pulse sensor, the buzzer will play in a loop and the red LED
will light up and remain steady until the driver puts their finger back on the sensor.
Figure 1- This is the Pulse Sensor
The pulse sensor has one of the most complication schematics out of all our sensors. This sensor has all the above resistors, capacitors, op amps and diodes packed into the tiny casing.
Above is a schematic of how the pulse sensor is connected to the Arduino Mega with the buzzer, LEDs and resistor.
PIR Motion Sensor
When a driver falls asleep while driving, the driver has a tendency to take their hands off of the
wheel. Taking your hands off the wheel for an extended period of time whether you are awake or not is
not a good circumstance. Using a very effective principal that is used for exercise equipment, where if
the person who is exercising trips a sensor, the device will stop and send an alert to the user. In our
design, we took this same innovative principal and applied it to our system. After researching online, we
found quality proximity sensors that work through infrared that detect motion in a certain area. Our
motion sensor is attached to the top of the steering wheel to detect if there is motion or not from the
driver. We needed to make adjustments to our PIR motion sensor because at first it was too sensitive
and detected motion in any range. We calibrated our sensor with electrical tape to only detect motion in
our desired area which in our case was around the steering wheel. If the driver is beginning to fall asleep
or is actually sleeping, their hands can come off the wheel, have little to no motion at all or could cause
the steering wheel to move abruptly. Using this PIR motion sensor, we can detect if the driver has been
inactive for too long or has taken their hands off the wheel or has made a sharp turn. If any one of the
situations occurs above, the sensor will send information to the Arduino board which will send an alert
to the driver through the indication board. Under normal driving conditions, an alert driver will always
be moving their hands around the steering wheel. A drowsy driver will have less motion on long drives
so if no motion is detected for an extended period of time, the system will send an alert to the driver.
Driver alertness and normal range of motion will be indicated safe with a green LED and unsafe with a
red LED. The red LED will light up until motion is detected again.
Figure 2 – This is the PIR Motion Sensor
Above is the PIR Motion Sensor schematic which shows how it is connected to the Arduino Mega 2560
with the LEDs, pin outs and resistor.
Temperature Sensor
When you fall asleep your body’s temperature changes significantly. When you enter the second
stage of a sleep cycle, your body’s temperature begins to decrease as you are less active. The detection
of a dropping temperature from a driver can indicate that the driver is beginning to fall asleep or is in
fact sleeping. After researching how we could detect temperatures, we found small infrared
thermometers that can hook directly up to our Arduino board. These thermometers are very small and
affordable and provide very accurate body temperatures. The sensor has the ability to measure the
driver’s body temperature and if the temperature is too low, it will send an alert to the driver and
indicate on the panel with LEDS. A green LED will indicate a safe temperature and a red LED will indicate
a temperature that is too low or too high.
Figure 3 – This is the temperature sensor
Above is the temperature sensor schematic which shows how it is connected to the Arduino Mega 2560
with the LEDS, pinouts, resistors and capacitors.
Carbon Monoxide
Besides detecting if the driver is falling asleep or becoming drowsy while driving, there are other
conditions that can make driving unsafe. A silent killer that is odorless and that cannot be not easily
detected is carbon monoxide. Combustion engines produce a ton of toxins and chemicals but carbon
monoxide cannot be detected by smell, sight or taste like other substances. Everyday most people get
into their cars and drive without thinking about the toxic chemicals they are generating by their vehicle.
Sometimes due to part failure and accidents, these toxins can escape into the car via the circulation
system and through small cracks. When you breathe in too much carbon monoxide, it begins to replace
the oxygen in your body which causes cells to die and organs to work improperly. With a lack of oxygen
in your body, your body begins to shut down and die. Breathing in carbon monoxide can become deadly
very quickly and without being able to detect it as easily as other toxins, it becomes a very serious
situation. After researching online, we were able to find very sensitive and efficient carbon monoxide
sensors that can connect directly to our Arduino board and can detect this harmful toxin in your
surrounding area. If carbon monoxide is detected in a dangerous quantity in parts per million, an alert
will be sent to the driver informing them of the situation. A green LED will show a safe level to breathe
in and a red LED will indicate dangerous levels of carbon monoxide in the surrounding area. A buzzer will
also sound and play in a loop and the red LED with light up until the carbon monoxide levels in parts per
million decrease to a safe level. Sitting on top of this toxic breeding ground is a very serious risk that we
all take every day we get behind the wheel and having a carbon monoxide sensor inside your car will
make driving even safer.
Figure 4 – This is the carbon monoxide sensor
Above is the
carbon monoxide sensor schematic which shows how it is connected to the Arduino Mega 2560 with the
LEDS, pinouts, resistors and buzzer.
Alcohol Sensor
Another serious risk that arises when operating a vehicle is the use of alcohol with driving. There
are countless cases of people driving under the influence and no matter what laws are passed, people
are still committing this crime and causing thousands of accidents, injuries and deaths per year. There
are systems out there that detect alcohol on a driver’s breathe but the systems tend to be large and
bulky and are only installed into cars of repeat offenders. Through the use of this sensor, we have
implemented a small and simple system that tests the blood alcohol level of the driver before allowing
the driver to start their car. We found a very accurate and sensitive alcohol sensor that can detect
alcohol in small to large ranges. This sensor was integrated into our Arduino board. If an unsafe level of
alcohol is detected on the driver’s breathe, the sensor will send a signal to the car not to turn on,
preventing the intoxicated driver from ever driving. A green LED will indicate a safe level to operate the
vehicle and a red LED will indicate an unsafe level of alcohol detected. A buzzer will also sound and play
in a loop if an unsafe level of alcohol is detected and the red LED will light up until a safe level is
detected after some period of time. A great feature that this sensor has is that after a high level of
alcohol is detected, it needs time to recover before testing for alcohol again. Having this feature can buy
precious time that can save lives. Even if the driver tries to start the car after the first test, the sensor
will still prevent the car from starting for a period of time. Some people may be opposed to putting this
device in all of their cars but the implementation of such a device is worth it if it can prevent thousands
of accidents and reduce the risk of alcohol related deaths.
Figure 5 – This is the alcohol sensor
Above is the alcohol sensor schematic
which shows how it is connected to the Arduino Mega 2560 with the LEDS, pinouts, resistors and buzzer.
Having pulse sensors, temperature sensors, proximity sensors, carbon monoxide and alcohol
sensors integrated into our system provides an effective drowsiness detection system along with
ensuring safe operating conditions. These sensors are placed around the steering wheel and in the area
of where a driver usually is seated. The sensors are connected to an Arduino Mega and communicate
back and forth with the board determining if the conditions are safe enough to operate the vehicle.
There will be a display panel mounted near the steering wheel showing the status of all the sensors with
green and red LEDs. We designed this system because we wanted to prevent sleeping at the wheel while
driving because of the number of related accidents and deaths that are a direct result of it. If we can
prevent such a serious epidemic like this from happening by just implementing a few simple sensors and
some innovative ideas, our system will be a success. We also added in the alcohol and carbon monoxide
sensors to ensure safer driving conditions along with preventing other car related accidents.
Full System Design Overview
The above block diagram shows the communication between the Arduino, sensors and LEDs.
The code is downloaded and stored onto the Arduino Mega which controls each sensor. The sensors will
test the current conditions of the vehicle and send back the results to the Arduino board which will
interpret the results. Depending on what the board interprets the results to be, it will display green LEDs
for safe conditions or sound a buzzer along with red LEDs for unsafe conditions.
Block Diagrams for Sensors
We have assembled block diagrams for each one of our sensors and for the full system. These block
diagrams show how information is read, analyzed, transferred and how the results are output from the
system.
Pulse Sensor Block Diagram
In the above block diagram for the pulse sensor, the pulse sensor code is downloaded to the
Arduino board and the sensor is mounted on top of the steering wheel. The user places their finger into
the pulse sensor and the sensor reads the user’s pulse and sends the information to the Arduino board.
The board then displays the pulse with a green LED and the fade with a red LED. If the pulse is not
detected or is too low, the buzzer will sound.
PIR Motion Sensor Block Diagram
In the above block diagram for the motion sensor, the motion sensor code is downloaded to the
Arduino board and the sensor is mounted around the steering wheel. The user will have their hands
placed around the wheel when they are driving. The sensor will detect if there is movement or no
movement around the steering wheel. That data will be sent back to the Arduino board and if there it
motion or movement detected, it will display a green LED. If there is no motion detected, it will display a
red LED.
Temperature Sensor Block Diagram
In the above block diagram for the temperature sensor, the temperature sensor code is
downloaded to the Arduino board and the sensor is mounted around the steering wheel. The sensor will
read the user’s temperature and send data to the Arduino board for interpretation. If the sensor detects
a normal temperature, the Arduino board will display a green LED. If the sensor detects a temperature
that is lower than normal or higher than normal, the board will display a red LED.
Carbon Monoxide Sensor Block Diagram
In the above block diagram for the carbon monoxide sensor, the carbon monoxide sensor code
is downloaded to the Arduino board and the sensor is mounted around the steering wheel. The sensor
will test the ppm (parts per million) levels of carbon monoxide in the atmosphere in the vehicle. If the
sensor detects normal levels of carbon monoxide in the vehicle, the Arduino will display a green LED. If
the sensor detects toxic levels of carbon monoxide present in the vehicle, the Arduino will sound a
buzzer and display a red LED.
Alcohol Sensor Block Diagram
In the above block diagram for the alcohol sensor, the alcohol sensor code is downloaded to the
Arduino board and the sensor is mounted around the steering wheel. The sensor will test for the levels
of alcohol in the air in the vehicle. If the sensor detects levels of alcohol lower than the legal limit of .08,
the Arduino will display a green LED. If the sensor detects levels of alcohol higher than the legal limit
of .08, the Arduino will sound a buzzer and display a red LED.
Data Output
Each sensor reads and sends data differently. The way each sensor interprets data is based off of
graphs and research that has been compiled together. Data that the Arduino displays in the serial output
coincides with the equivalent real time numbers for what we are testing for. Below will show
documents, graphs and data analysis of how the Arduino interprets information.
Pulse Sensor Data
After researching and collecting data, we found that normal resting pulse rates differ from
person to person. Taking this information and combining it with normal averages, the average pulse of a
person sleeping is around 50 beats per minute and under. Since everyone has different resting/sleeping
pulses, a user can simply calibrate the pulse sensor to their own body’s actual rate. This functionality
makes product more marketable and user friendly as well as providing the user with accurate data
interpretation. With this information, we calibrated our code for the pulse sensor to analyze the pulse
input and determine what the user’s pulse is. In our group, everyone’s pulse was slightly different.
Denzel has a normal resting pulse of about 53 beats per minute while Matt has a normal resting pulse of
about 59 beats per minute. We decided upon calibrating our board to test for a normal resting pulse of
53 beats per minute. If the pulse is equal to or drops below 52, it will sound an alarm and turn on a red
LED.
Pulse Sensor Demonstration Connected to Steering Wheel:
This is the serial output of what the
Arduino is reading of Denzel’s normal resting heart rate. The pulse sensor analyzes the data collected,
sends that information back to the Arduino board and it then displays the heart rate. If this heart rate
pictured above drops any lower than this present heart rate, the buzzer will sound and the red LED will
turn on.
PIR Motion Sensor Data
The motion sensor analyzes current movement in a certain area through the use of infrared.
This sensor was originally too sensitive and would detect almost any movement even from distances far
away. We calibrated this sensor using black electrical tape to channel the sensor’s sensitivity to a certain
location. In our case this location was above our steering wheel for testing the movement. If movement
is detected, the sensor will send data back to the Arduino board and it will turn on a green LED. If no
movement or motion is detected, the sensor will send data back to the Arduino board and it will turn on
a red LED.
PIR Motion Sensor Demonstration Connected to Steering Wheel:
In this image you can
see that the red LED is illuminated showing that no motion is detected.
Serial Output of Motion Sensor:
This figure shows the serial output for the motion sensor.
Alcohol Sensor Data
The alcohol sensor analyzes the current alcohol levels in the air. Using generated graphs that
display the correlation between the analog inputs and BAC (Blood Alcohol Levels), we can determine
whether a driver is over or under the legal limit of 0.08. This graph depicts levels under the legal limit to
be around 950 units in analog with is equivalent to about 0.07 BAC. Anything higher than 950 units in
analog is over the legal limit of 0.08 BAC.
This image is a reference
from (http://nootropicdesign.com/projectlab/2010/09/17/arduino-breathalyzer/ ) which conducted
similar analysis as we did. It doesn’t show an exact straight line leading up to the 0.08 region but
realistically if the analog reading is above 950 and using this graph as reference, the driver is impaired to
say the least and is at or above the legal limit.
Alcohol Sensor Connected to the Steering Wheel:
This image shows the alcohol sensor mounted by the steering wheel.
Serial Output for Alcohol Sensor:
In this serial output, you can see hardly no alcohol
detected in the air and then a huge spike in the analog reading when alcohol is detected which
surpasses the legal limit which is between 950-960 analog units. Our chart shows our serial data and
how it is interpreted.
Temperature Sensor Data
The temperature sensor analyzes and reads the temperature of the driver. This information is
sent back to the Arduino and the board determines if the temperature is above normal, normal or too
low. Everyone is different so calibrating this sensor is just like the pulse sensor so the user will need to
personalize it to their normal body temperature. After research and putting together information, we
found that the average human body temperature drops by 1-2 degrees while they are asleep. If the
temperature is normal, the Arduino will turn on a green LED. If the temperature is below normal, it will
turn on the red LED.
Temperature Sensor Connected Around the Steering Wheel:
In this image the temperature being detected is room temperature
which has turned on the red LED. Once a safe temperature is read, the LED will turn green. If an unsafe
higher than normal temperature is read, the red LED will turn on.
Serial Output for Temperature Sensor:
In these images you can see the sensor reading the room temperature in the beginning of our trial. Once
the sensor goes above or equals the average human body temperature of (98.6 degrees Fahrenheit), the
green LED will turn on. If it is below 98.6, the red LED will turn on. We also have built in an additional
safety feature that will display the red LED if the temperature goes upwards of more than 101 degrees
Fahrenheit. So anything below normal and above normal has been accounted for which means the
green LED will only light up within a normal range. Our graph reflects the output of our images as it
spikes up from our low reading to our normal reading and then back down.
Carbon Monoxide Sensor Data
The carbon monoxide sensor analyzes the levels of carbon monoxide in the atmosphere in parts
per million and sends data to the Arduino board. The Arduino then determines if the atmosphere
contains toxic levels of carbon monoxide. If there are normal/safe levels of CO are detected in the air,
the green LED will be illuminated. If toxic/harmful levels of CO are detected in the air, the buzzer will
sound and the red LED will be illuminated. The complicated part about the carbon monoxide data is that
it needs to be analyzed very carefully because of the nature of the sensor. Temperature and humidity
affect how the sensor acts and reads current conditions so it needs to be calibrated for specific
surroundings. Additionally this specific sensor needs a certain warm up phase to be “broken in” which is
a minimum of 48 hours. Once calibrated, pulses of different voltages ranging from 1.5-5 volts have to be
input into the sensor. The way data is analyzed is also complicated because different loads need to be
applied to the sensor due to the surroundings (temperature/humidity).
This figure shows the
dependence of the CO Sensor on temperature and humidity and how it affects the output. R0 is sensor
resistance at 100ppm C0 in air (33%RH and 20 degree). RS is sensor resistance at 100ppm CO in different
temperature and humidity. This graph and information was taken from :
https://www.sparkfun.com/datasheets/Sensors/Biometric/MQ-7.pdf
To make use of the analog data received from our Arduino board and sensor, we created a test
environment that would allow for some manipulation and room for some error. Data collected without
the presence of CO was recorded and logged as normal conditions. Analog units from normal conditions
yielded between 380-430 which through conversion would be equivalent to a normal level of C0 in the
air. When exposed to C0, the data read from the sensor spiked to over 930 units in analog which is
equivalent to a toxic level of C0 which could cause severe headaches, dizziness, nausea, loss of
consciousness and can result in death.
Here is a chart showing the toxic levels of C0 concentration in parts per million. This chart was taken
from: http://www.nyad.com/pdf/carbon_monoxide_danger_levels.pdf
This chart shows what could possibly
happen after being exposed to C0 for long periods of time.
Carbon Monoxide Sensor Hooked up Around the Steering Wheel:
In this picture you can see the C0 sensor hooked up
on the bottom left.
Carbon Monoxide sensor hooked up by the exhaust of a car.
Serial Output Data for Carbon Monoxide Sensor:
In these graphs, you can see output data, and how the levels of CO detected spiked.
Communication and Coding
Through the implementation of some Programming C/C++, code can be assembled for the
Arduino to understand. The Arduino hardware/software is very flexible which is why so many people use
it. Most companies will provide some sample code to go along with certain products they manufacture
so users can customize the code to do exactly what they want it to do. In our project, most companies
provided sample codes so we adjusted them for certain calibrations. Some codes were simple to work
with in the use of the temperature, alcohol and motion sensors but the implementation of the pulse and
carbon monoxide were a little more complicated.
Pulse Sensor Code
The pulse sensor code was the most complicated code of all. This code has its own library that
creates a special display showing a colorful diagram of the pulse being detected by the sensor. The pulse
sensor code is divided up into three parts. The first part is the interrupt allows important functions to go
on in the background by default. These interrupts can slow the timing of the code down but in our
project it did not change significantly. Reference: http://arduino.cc/en/Reference/attachInterrupt. The
second part of our code has all the digital pins and the output which comes directly from the processing
code. In this section, we insert the “if else” statement for the buzzer and the LEDs. The third part of the
code is the processing point where the heart rate/pulse has its display generated showing the graphs.
The processing code consists of four codes which is the monitor display, keyboard/mouse code, scale
bar code, and serial event code. The pulse code and interrupt code has to be in one folder. Also, the
processing, keyboard/mouse, serial event, and scale bar codes are in one folder also. The pulse code can
be downloaded from: http://pulsesensor.myshopify.com/pages/pulse-sensor-amped-arduino-v1dot1.
Here is a flow chart for the Pulse Sensor:
Interrupt Code:
This sample code we received is from Joel Murphy and Yury Gitman who designed this sensor.
volatile int rate[10]; // used to hold last ten IBI valuesvolatile unsigned long sampleCounter = 0; // used to determine pulse timingvolatile unsigned long lastBeatTime = 0; // used to find the inter beat intervalvolatile int P =512; // used to find peak in pulse wavevolatile int T = 512; // used to find trough in pulse wavevolatile int thresh = 512; // used to find instant moment of heart beatvolatile int amp = 100; // used to hold amplitude of pulse waveformvolatile boolean firstBeat = true; // used to seed rate array so we startup with reasonable BPMvolatile boolean secondBeat = true; // used to seed rate array so we startup with reasonable BPM
void interruptSetup(){ // Initializes Timer2 to throw an interrupt every 2mS. TCCR2A = 0x02; // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE TCCR2B = 0x06; // DON'T FORCE COMPARE, 256 PRESCALER OCR2A = 0X7C; // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE TIMSK2 = 0x02; // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A sei(); // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED }
// THIS IS THE TIMER 2 INTERRUPT SERVICE ROUTINE.
// Timer 2 makes sure that we take a reading every 2 milisecondsISR(TIMER2_COMPA_vect){ // triggered when Timer2 counts to 124 cli(); // disable interrupts while we do this Signal = analogRead(pulsePin); // read the Pulse Sensor sampleCounter += 2; // keep track of the time in mS with this variable int N = sampleCounter - lastBeatTime; // monitor the time since the last beat to avoid noise
// find the peak and trough of the pulse wave if(Signal < thresh && N > (IBI/5)*3){ // avoid dichrotic noise by waiting 3/5 of last IBI if (Signal < T){ // T is the trough T = Signal; // keep track of lowest point in pulse wave } } if(Signal > thresh && Signal > P){ // thresh condition helps avoid noise P = Signal; // P is the peak } // keep track of highest point in pulse wave // NOW IT'S TIME TO LOOK FOR THE HEART BEAT // signal surges up in value every time there is a pulseif (N > 250){ // avoid high frequency noise if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ) { Pulse = true; // set the Pulse flag when we think there is a pulse digitalWrite(blinkPin,HIGH); // turn on pin 13 LED IBI = sampleCounter - lastBeatTime; // measure time between beats in mS lastBeatTime = sampleCounter; // keep track of time for next pulse if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE { firstBeat = false; // clear firstBeat flag return; // IBI value is unreliable so discard it } if(secondBeat) // if this is the second beat, if secondBeat == TRUE { secondBeat = false; // clear secondBeat flag for(int i=0; i<=9; i++){ // seed the running total to get a realisitic BPM at startup rate[i] = IBI; } } // keep a running total of the last 10 IBI values word runningTotal = 0; // clear the runningTotal variable
for(int i=0; i<=8; i++){ // shift data in the rate array rate[i] = rate[i+1]; // and drop the oldest IBI value runningTotal += rate[i]; // add up the 9 oldest IBI values }
rate[9] = IBI; // add the latest IBI to the rate array runningTotal += rate[9]; // add the latest IBI to runningTotal runningTotal /= 10; // average the last 10 IBI values BPM = 60000/runningTotal; // how many beats can fit into a minute? that's BPM! QS = true; // set Quantified Self flag // QS FLAG IS NOT CLEARED INSIDE THIS ISR } }
if (Signal < thresh && Pulse == true){ // when the values are going down, the beat is over digitalWrite(blinkPin,LOW); // turn off pin 13 LED Pulse = false; // reset the Pulse flag so we can do it again amp = P - T; // get amplitude of the pulse wave thresh = amp/2 + T; // set thresh at 50% of the amplitude P = thresh; // reset these for next time T = thresh; } if (N > 2500){ // if 2.5 seconds go by without a beat thresh = 512; // set thresh default P = 512; // set P default T = 512; // set T default lastBeatTime = sampleCounter; // bring the lastBeatTime up to date firstBeat = true; // set these to avoid noise secondBeat = true; // when we get the heartbeat back } sei(); // enable interrupts when youre done!}// end isr
Pulse code:
(comments are directly from the pulse sensor code)/*www.pulsesensor.com >>> Pulse Sensor purple wire goes to Analog Pin 0 <<<Pulse Sensor sample aquisition and processing happens in the background via Timer 2 interrupt. 2mS sample rate.PWM on pins 3 and 11 will not work when using this code, because we are using Timer 2!The following variables are automatically updated:Signal : int that holds the analog signal data straight from the sensor. updated every 2mS.IBI : int that holds the time interval between beats. 2mS resolution.BPM : int that holds the heart rate value, derived every beat, from averaging previous 10 IBI values.
QS : boolean that is made true whenever Pulse is found and BPM is updated. User must reset.Pulse : boolean that is true when a heartbeat is sensed then false in time with pin13 LED going out.
This code is designed with output serial data to Processing sketch "PulseSensorAmped_Processing-xx"The Processing sketch is a simple data visualizer. All the work to find the heartbeat and determine the heartrate happens in the code below.Pin 13 LED will blink with heartbeat.If you want to use pin 13 for something else, adjust the interrupt handlerIt will also fade an LED on pin fadePin with every beat. Put an LED and series resistor from fadePin to GND.*/
// VARIABLESint pulsePin = 0; // Pulse Sensor purple wire connected to analog pin 0int blinkPin = 13; // pin to blink led at each beatint fadePin = 5; // pin to do fancy classy fading blink at each beatint fadeRate = 0; // used to fade LED on with PWM on fadePinint buzzer = 7;
// these variables are volatile because they are used during the interrupt service routine!volatile int BPM; // used to hold the pulse ratevolatile int Signal; // holds the incoming raw datavolatile int IBI = 600; // holds the time between beats, the Inter-Beat Intervalvolatile boolean Pulse = false; // true when pulse wave is high, false when it's lowvolatile boolean QS = false; // becomes true when Arduoino finds a beat.
void setup(){ pinMode(blinkPin,OUTPUT); // pin that will blink to your heartbeat! pinMode(fadePin,OUTPUT); // pin that will fade to your heartbeat! pinMode(buzzer,OUTPUT); Serial.begin(115200); // we agree to talk fast! interruptSetup(); // sets up to read Pulse Sensor signal every 2mS // UN-COMMENT THE NEXT LINE IF YOU ARE POWERING The Pulse Sensor AT LOW VOLTAGE, // AND APPLY THAT VOLTAGE TO THE A-REF PIN //analogReference(EXTERNAL); }
void loop(){ sendDataToProcessing('S', Signal); // send Processing the raw Pulse Sensor data if (QS == true){ // Quantified Self flag is true when arduino finds a heartbeat fadeRate = 255; // Set 'fadeRate' Variable to 255 to fade LED with pulse sendDataToProcessing('B',BPM); // send heart rate with a 'B' prefix sendDataToProcessing('Q',IBI); // send time between beats with a 'Q' prefix QS = false; // reset the Quantified Self flag for next time
} //ledFadeToBeat(); if (BPM <= 52) digitalWrite (buzzer, HIGH); else digitalWrite (buzzer, LOW); delay (20); ledFadeToBeat(); delay(20); // take a break }void ledFadeToBeat(){ fadeRate -= 15; // set LED fade value fadeRate = constrain(fadeRate,0,255); // keep LED fade value from going into negative numbers! analogWrite(fadePin,fadeRate); // fade LED }
void sendDataToProcessing(char symbol, int data ){ Serial.print(symbol); // symbol prefix tells Processing what type of data is coming Serial.println(data); // the data to send culminating in a carriage return }
Processing Code:/*THIS PROGRAM WORKS WITH PulseSensorAmped_Arduino-xx ARDUINO CODETHE PULSE DATA WINDOW IS SCALEABLE WITH SCROLLBAR AT BOTTOM OF SCREENPRESS 'S' OR 's' KEY TO SAVE A PICTURE OF THE SCREEN IN SKETCH FOLDER (.jpg)MADE BY JOEL MURPHY AUGUST, 2012*/
import processing.serial.*;PFont font;Scrollbar scaleBar;
Serial port;
int Sensor; // HOLDS PULSE SENSOR DATA FROM ARDUINOint IBI; // HOLDS TIME BETWEN HEARTBEATS FROM ARDUINOint BPM; // HOLDS HEART RATE VALUE FROM ARDUINOint[] RawY; // HOLDS HEARTBEAT WAVEFORM DATA BEFORE SCALINGint[] ScaledY; // USED TO POSITION SCALED HEARTBEAT WAVEFORMint[] rate; // USED TO POSITION BPM DATA WAVEFORMfloat zoom; // USED WHEN SCALING PULSE WAVEFORM TO PULSE WINDOWfloat offset; // USED WHEN SCALING PULSE WAVEFORM TO PULSE WINDOW
color eggshell = color(255, 253, 248);int heart = 0; // This variable times the heart image 'pulse' on screen// THESE VARIABLES DETERMINE THE SIZE OF THE DATA WINDOWSint PulseWindowWidth = 490;int PulseWindowHeight = 512; int BPMWindowWidth = 180;int BPMWindowHeight = 340;boolean beat = false; // set when a heart beat is detected, then cleared when the BPM graph is advanced
void setup() { size(700, 600); // Stage size frameRate(100); font = loadFont("Arial-BoldMT-24.vlw"); textFont(font); textAlign(CENTER); rectMode(CENTER); ellipseMode(CENTER); // Scrollbar constructor inputs: x,y,width,height,minVal,maxVal scaleBar = new Scrollbar (400, 575, 180, 12, 0.5, 1.0); // set parameters for the scale bar RawY = new int[PulseWindowWidth]; // initialize raw pulse waveform array ScaledY = new int[PulseWindowWidth]; // initialize scaled pulse waveform array rate = new int [BPMWindowWidth]; // initialize BPM waveform array zoom = 0.75; // initialize scale of heartbeat window // set the visualizer lines to 0 for (int i=0; i<rate.length; i++){ rate[i] = 555; // Place BPM graph line at bottom of BPM Window } for (int i=0; i<RawY.length; i++){ RawY[i] = height/2; // initialize the pulse window data line to V/2 } // GO FIND THE ARDUINO println(Serial.list()); // print a list of available serial ports // choose the number between the [] that is connected to the Arduino port = new Serial(this, Serial.list()[0], 115200); // make sure Arduino is talking serial at this baud rate port.clear(); // flush buffer port.bufferUntil('\n'); // set buffer full flag on receipt of carriage return} void draw() { background(0); noStroke();// DRAW OUT THE PULSE WINDOW AND BPM WINDOW RECTANGLES fill(eggshell); // color for the window background rect(255,height/2,PulseWindowWidth,PulseWindowHeight);
rect(600,385,BPMWindowWidth,BPMWindowHeight); // DRAW THE PULSE WAVEFORM // prepare pulse data points RawY[RawY.length-1] = (1023 - Sensor) - 212; // place the new raw datapoint at the end of the array zoom = scaleBar.getPos(); // get current waveform scale value offset = map(zoom,0.5,1,150,0); // calculate the offset needed at this scale for (int i = 0; i < RawY.length-1; i++) { // move the pulse waveform by RawY[i] = RawY[i+1]; // shifting all raw datapoints one pixel left float dummy = RawY[i] * zoom + offset; // adjust the raw data to the selected scale ScaledY[i] = constrain(int(dummy),44,556); // transfer the raw data array to the scaled array } stroke(250,0,0); // red is a good color for the pulse waveform noFill(); beginShape(); // using beginShape() renders fast for (int x = 1; x < ScaledY.length-1; x++) { vertex(x+10, ScaledY[x]); //draw a line connecting the data points } endShape(); // DRAW THE BPM WAVE FORM// first, shift the BPM waveform over to fit then next data point only when a beat is found if (beat == true){ // move the heart rate line over one pixel every time the heart beats beat = false; // clear beat flag (beat flag waset in serialEvent tab) for (int i=0; i<rate.length-1; i++){ rate[i] = rate[i+1]; // shift the bpm Y coordinates over one pixel to the left }// then limit and scale the BPM value BPM = min(BPM,200); // limit the highest BPM value to 200 float dummy = map(BPM,0,200,555,215); // map it to the heart rate window Y rate[rate.length-1] = int(dummy); // set the rightmost pixel to the new data point value } // GRAPH THE HEART RATE WAVEFORM stroke(250,0,0); // color of heart rate graph strokeWeight(2); // thicker line is easier to read noFill(); beginShape(); for (int i=0; i < rate.length-1; i++){ // variable 'i' will take the place of pixel x position vertex(i+510, rate[i]); // display history of heart rate datapoints } endShape(); // DRAW THE HEART AND MAYBE MAKE IT BEAT fill(250,0,0); stroke(250,0,0); // the 'heart' variable is set in serialEvent when arduino sees a beat happen heart--; // heart is used to time how long the heart graphic swells when your heart beats heart = max(heart,0); // don't let the heart variable go into negative numbers
if (heart > 0){ // if a beat happened recently, strokeWeight(8); // make the heart big } smooth(); // draw the heart with two bezier curves bezier(width-100,50, width-20,-20, width,140, width-100,150); bezier(width-100,50, width-190,-20, width-200,140, width-100,150); strokeWeight(1); // reset the strokeWeight for next time
// PRINT THE DATA AND VARIABLE VALUES fill(eggshell); // get ready to print text text("Pulse Sensor Amped Visualizer 1.1",245,30); // tell them what you are text("IBI " + IBI + "mS",600,585); // print the time between heartbeats in mS text(BPM + " BPM",600,200); // print the Beats Per Minute text("Pulse Window Scale " + nf(zoom,1,2), 150, 585); // show the current scale of Pulse Window // DO THE SCROLLBAR THINGS scaleBar.update (mouseX, mouseY); scaleBar.display(); //
} //end of draw loop
Keyboard/mouse code:
void mousePressed(){ scaleBar.press(mouseX, mouseY);}
void mouseReleased(){ scaleBar.release();}
void keyPressed(){
switch(key){ case 's': // pressing 's' or 'S' will take a jpg of the processing window case 'S': saveFrame("heartLight-####.jpg"); // take a shot of that! break;
default: break; }}
Serial Event code:
void serialEvent(Serial port){ String inData = port.readStringUntil('\n'); inData = trim(inData); // cut off white space (carriage return) if (inData.charAt(0) == 'S'){ // leading 'S' for sensor data inData = inData.substring(1); // cut off the leading 'S' Sensor = int(inData); // convert the string to usable int } if (inData.charAt(0) == 'B'){ // leading 'B' for BPM data inData = inData.substring(1); // cut off the leading 'B' BPM = int(inData); // convert the string to usable int beat = true; // set beat flag to advance heart rate graph heart = 20; // begin heart image 'swell' timer } if (inData.charAt(0) == 'Q'){ // leading 'Q' means IBI data inData = inData.substring(1); // cut off the leading 'Q' IBI = int(inData); // convert the string to usable int }}
Scale Bar code:
/* THIS SCROLLBAR OBJECT IS BASED ON THE ONE FROM THE BOOK "Processing" by Reas and Fry*/
class Scrollbar{ int x,y; // the x and y coordinates float sw, sh; // width and height of scrollbar float pos; // position of thumb float posMin, posMax; // max and min values of thumb boolean rollover; // true when the mouse is over boolean locked; // true when it's the active scrollbar float minVal, maxVal; // min and max values for the thumb Scrollbar (int xp, int yp, int w, int h, float miv, float mav){ // values passed from the constructor x = xp; y = yp; sw = w; sh = h; minVal = miv; maxVal = mav; pos = x - sh/2; posMin = x-sw/2; posMax = x + sw/2; // - sh;
} // updates the 'over' boolean and position of thumb void update(int mx, int my) { if (over(mx, my) == true){ rollover = true; // when the mouse is over the scrollbar, rollover is true } else { rollover = false; } if (locked == true){ pos = constrain (mx, posMin, posMax); } }
// locks the thumb so the mouse can move off and still update void press(int mx, int my){ if (rollover == true){ locked = true; // when rollover is true, pressing the mouse button will lock the scrollbar on }else{ locked = false; } }
Motion Sensor Code
The motion sensor code is detecting if there is motion or not and this is achieved through if else
statements. Displaying a green LED means that there is motion detected and displaying a red LED means
that there is no motion detected. This code is pretty simple and is only contained in one file. First we
define the LED pins and then read the analog data generated from the PIR sensor. Finally we have an if
else statement for the green and red LEDs.
Here is a flow chart for the Motion Sensor:
int pirPin = 2; //digital pin 2int ledMotion=3; //digital pin 3int ledMotionRed=4; //digital pin 4void setup(){ Serial.begin(9600); // sets the serial port to 9600 pinMode(pirPin, INPUT); // motion sensor input pinMode(ledMotionRed, OUTPUT); //Red LED ouput pinMode(ledMotion, OUTPUT); //Green LED output}void loop(){ int pirVal = digitalRead(pirPin); //motion sensor analog is read through pin 2
if(pirVal == LOW){ // motion detected Serial.println("Motion Detected"); //prints the line motion detected digitalWrite(ledMotion,HIGH); //Green LED is on delay(1000); //wait 1000ms for next reading digitalWrite(ledMotion,LOW); //Green LED is off } else{ if(pirVal == HIGH){ //motion not detected Serial.println("Motion Not Detected"); //prints the line motion not detected digitalWrite(ledMotionRed,HIGH); //Red LED is on delay(1000); //wait 1000ms for next reading digitalWrite(ledMotionRed,LOW); //Red LED is off
} } }
We received sample code from http://bildr.org/2011/06/pir_arduino/ and we were able to
manipulate it to perform the actions we wanted our Arduino to execute.
Temperature Sensor Code
This code was somewhat challenging but after some manipulation we were able to achieve what
we planned for. We included a safety feature in our code so it will detect temperatures too low and too
high. The safe level is between temperatures above 98.6 and lower than 101 degrees Fahrenheit. Once
the temperature drops 1-2 degrees lower than normal or raises above two degrees higher than normal,
the red LED will be displayed. If the temperature remains normal, it will display the green LED. In this
code, we needed to include the I2c library to enable us to read and analyze temperatures correctly.
Here is a flow chart for the Temperature Sensor:
#include <i2cmaster.h>
void setup(){Serial.begin(9600); //sets the serial port to 9600Serial.println("Setup...");
i2c_init(); //Initialise the i2c busPORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
}
void loop(){ int dev = 0x5A<<1; int data_low = 0; int data_high = 0; int pec = 0; i2c_start_wait(dev+I2C_WRITE); i2c_write(0x07); // read i2c_rep_start(dev+I2C_READ); data_low = i2c_readAck(); //Read 1 byte and then send ack data_high = i2c_readAck(); //Read 1 byte and then send ack pec = i2c_readNak(); i2c_stop(); //This converts high and low bytes together and processes temperature, MSB is a error bit
and is ignored for temps double tempFactor = 0.02; // 0.02 degrees per LSB (measurement resolution of the
MLX90614) double tempData = 0x0000; // zero out the data int frac; // data past the decimal point // This masks off the error bit of the high byte, then moves it left 8 bits and adds the low
byte. tempData = (double)(((data_high & 0x007F) << 8) + data_low); tempData = (tempData * tempFactor)-0.01; float celcius = tempData - 273.15; // celcius formula float fahrenheit = (celcius*1.8) + 32; // fahrenheit formula
int greenLED=12; // green led in digital pin 12int redLED=11; // red led in digital pin 11 if (celcius >= 37.00) //98.6 fahrenheit { digitalWrite(greenLED, HIGH); //green led is on
digitalWrite(redLED, LOW); //red led is off } else { digitalWrite(greenLED, LOW); //green led is off digitalWrite(redLED, HIGH); //red led is on } if (celcius >= 38.33) //101 fahrenheit { digitalWrite(greenLED, LOW); digitalWrite(redLED, HIGH); } Serial.print("Celcius: "); //reads out celcius in serial monitor Serial.println(celcius);
Serial.print("Fahrenheit: "); //reads out fahrenheit in serial monitor Serial.println(fahrenheit);
delay(1600); // wait a second before printing again}
We received sample code from http://bildr.org/2011/02/mlx90614-arduino/ and revised it to
work with the LEDs and select the certain ranges of temperature.
Carbon Monoxide Sensor Code
This sensor was very complicated and involved putting different loads on the sensor and
inputting different voltages. The code for this sensor was identical to the alcohol sensor code because of
the parameters and pin outs. The only difference is that the sensor is calibrated to test for carbon
monoxide instead of alcohol. On top we have the pins for the red and green LEDs with the buzzer
followed by the analog read of data from the carbon monoxide sensor.
Here is a flow chart for the Carbon Monoxide Sensor:
int sensorValue;int ledCarbon=3; //GREEN LED DIGITAL PIN 3int ledCarbonRed=4; // RED LED DIGITAL PIN 4int buzzer=7; //digital pin 7
void setup(){ Serial.begin(9600); // sets the serial port to 9600 pinMode(ledCarbonRed, OUTPUT); //red led output pinMode(ledCarbon, OUTPUT); //green led output pinMode(buzzer, OUTPUT); //buzzer output}
void loop(){ sensorValue = analogRead(6); // read analog input pin 6 Serial.println(sensorValue, DEC); // prints the value readdelay(1200); // wait 1200ms for next reading if (sensorValue > 950) {digitalWrite(ledCarbonRed, HIGH); //red led is on digitalWrite(ledCarbon, LOW); // green led is off digitalWrite(buzzer, HIGH); //buzzer is on
} else if (sensorValue < 940) {digitalWrite(ledCarbonRed, LOW); //red led is off digitalWrite(ledCarbon, HIGH); //green led is on digitalWrite(buzzer, LOW); // buzzer is off
} }
We got sample code and design information from this site
http://wiring.org.co/learning/basics/airqualitymq135.html and then we implemented the use of LEDs
and buzzer just like the alcohol sensor for our safety system.
Alcohol Sensor Code
This sensor was pretty simple we have the pins for the green and red LEDs with the buzzer on
top and then have the code read the analog data from the sensor. The alcohol and carbon monoxide are
basically identical but are calibrated differently.
Here is a flow chart for the Alcohol Sensor:
int sensorValue; //analog pin for alcohol sensorint ledAlcohol=3; //digital pin 3 int ledAlcoholRed=4; //digital pin 4int buzzer=7; //digitin pin 7
void setup(){ Serial.begin(9600); // sets the serial port to 9600 pinMode(ledAlcoholRed, OUTPUT); //red led output pinMode(ledAlcohol, OUTPUT); //green led output pinMode(buzzer, OUTPUT); //buzzer output}
void loop(){ sensorValue = analogRead(0); // read analog input pin 0 Serial.println(sensorValue, DEC); // prints the value readdelay(1200); // wait 1200ms for next reading if (sensorValue > 950) // 950 is equivalent to ≈ .07 BAC level {digitalWrite(ledAlcoholRed, HIGH); //red led is on digitalWrite(ledAlcohol, LOW); // green led is off digitalWrite(buzzer, HIGH); //buzzer is on } else if (sensorValue < 900) {digitalWrite(ledAlcoholRed, LOW); //red led is off digitalWrite(ledAlcohol, HIGH); //green led is on digitalWrite(buzzer, LOW); //buzzer is off } }We got sample code from: http://bildr.org/2013/10/mq3-arduino/ and we implemented the LEDs and
the buzzer into our code for the safety system.
Future Plans
We want to integrate this Driver Drowsiness and Driver Safety System into vehicles as a
standard quality. We already have the components working so the next step would be learning how to
make use of them in car computer systems. Having a device can save lives is priceless and even though
we cannot eliminate all of the deadly statistics completely, we can still reduce the numbers dramatically
with the introduction of this system. As well as integrating this system, we might possibly combine this
project with another group who used software to detect drowsiness. Combining our hardware system
with their software system could be somewhat difficult but we both share the same interest in
preventing drowsiness and traffic related injuries. If we could lower the deadly statistics and prevent
drowsiness and traffic related injuries, then our project will be a success.
Conclusion
This project has been a great experience for our group as we are walking away with so much
knowledge from learning how to implement software and hardware. After a rough start from having a
delay in the delivery of our parts, we made the best of our time and assembled all our diagrams and
code. Since we developed our codes and diagrams while we did not have parts, we were able to start
building immediately. Unfortunately we did run into some problems and had little time to correct them
but in the end everything worked out. The feeling of finally getting the sensors properly calibrated and
seeing the proper data originally desired is priceless. Some sensors were difficult to calibrate and test
but after research and troubleshooting, we were able to get things to work. This project has tied all of
our previous classes together as we were challenged to use our skills from programming,
microprocessors, computer hardware/architecture, circuits and signal classes. It has been a pleasure
working on a project like this one
REFRENCES
Arduino Mega : Select Assembled option: http://www.karlssohttp://www.karlssonrobotics.com/cart/alcohol-gas-sensor-mq-3/nrobotics.com/cart/Arduino-Mega-Compatible-Board-With-FTDI/
USB Cable Hub: http://www.karlssonrobotics.com/cart/SparkFun-Cerberus-USB-Cable-6ft-CAB-12016/
LEDs Pack: http://www.karlssonrobotics.com/cart/led-assorted-26-pack/
Pulse Sensor: http://www.karlssonrobotics.com/cart/pulse-sensor/
Alcohol Sensor: http://www.karlssonrobotics.com/cart/alcohol-gas-sensor-mq-3/
Carbon Monoxide Sensor: http://www.karlssonrobotics.com/cart/carbon-monoxide-sensor-mq-7/
Temperature Sensor: http://www.karlssonrobotics.com/cart/infrared-thermometer-mlx90614/
Motion Sensors: http://www.karlssonrobotics.com/cart/pir-motion-sensor/
Steering Wheel (Yellow): http://www.amazon.com/gp/product/B000I1CH5M/ref=oh_details_o02_s00_i00?ie=UTF8&psc=1
Pulse Code: https://code.google.com/p/pulse-sensor/downloads/list
Alcohol Code: http://wiring.org.co/learning/basics/airqualitymq135.html
Carbon Monoxide Code: http://wiring.org.co/learning/basics/airqualitymq135.html
Motion Code: http://bildr.org/2011/06/pir_arduino/
Temperature Code: http://bildr.org/2011/02/mlx90614-arduino/
BAC vs Serial Output Graph: http://nootropicdesign.com/projectlab/2010/09/17/arduino-breathalyzer/
CO Sensor Chart: https://www.sparkfun.com/datasheets/Sensors/Biometric/MQ-7.pdf
CO Danger Levels: http://www.nyad.com/pdf/carbon_monoxide_danger_levels.pdf