Introduction: BME 3300 BAC Meter

We are Biomedical Engineering Undergraduates at Vanderbilt University working on a final project in Biomedical Instrumentation. We have designed a Blood Alcohol Content Meter, or breathalyzer, to demonstrate concepts learned in the course.

As alcohol is consumed, the amount of alcohol in the individual's blood increases. This can be detected by monitoring the amount of alcohol exhaled in the individual's breath. Alcohol is measured using an MQ-3B Alcohol Sensor which will be further described later in this instructable.

Our device can measure BACs ranging from 0.02 to 0.24 with a resolution of 0.00045%. We focused on optimizing the circuit to determine whether one is above or below the legal limit of 0.08; however, a person should not rely on this device or assume that their driving abilities are sufficient as alcohol hinders one's ability to function properly.

Step 1: Gather Your Tools

Materials we used:

  • MQ-3B Alcohol Sensor (Unit Price = $4.95)
  • LCD Screen LEDs (1 Red and 1 Green)
  • Container
  • Jumper Wires
  • Protoboard
  • 9 V battery
  • Battery adaptor
  • Electrical Tape
  • Scotch Tape
  • Deck of cards (not necessary, used for support)
  • Mouthwash
  • Arduino UNO Board
  • Tubing to encase transducer
  • 220 Ω (2) and 1465 Ω Resistors
  • Exacto knife

Step 2: Summary of Operation

As an individual consumes alcohol, it travels through their bloodstream where it remains for some time. As they breathe, some of the dissolved alcohol is diluted in their breath. This can be measured by utilizing the transducer to determine the concentration of ethanol in one's breath and converting this to the concentration of alcohol in the blood using a standard conversion (0.21 BAC = BrAC). This gives a BAC which can be correlated to the side effects one is experiencing due to alcohol consumption.

Step 3: Circuit Diagram

We utilized a voltage divider to calculate the BAC by monitoring the change in voltage across the load resistor and using the transfer function to calculate the changing resistance of the transducer. As the resistance of the transducer decreased, the voltage across the load resistor increased. The block diagram shows that the subject blows on the transducer which is incorporated into the voltage divider. The voltage divider is then connected to an analog to digital converter before producing the output BAC.

Since our goal was to optimize sensitivity at the legal limit of 0.08, we chose a load resistor with a resistance value equal to the resistance of the transducer at that alcohol concentration. We also added a green LED that lights up when BAC is less than 0.08 and a red LED that lights up when BAC is greater than 0.08. These LEDs are connected to the output of the Arduino (discussed later) and are placed in series with a 220 ohm resistor to limit the current through them.

Step 4: MQ-3B Alcohol Sensor

The MQ-3B Alcohol Sensor was purchased through SparkFun and has 6 pins. Pins 2 and 5, the middle pins on either side, correspond to the internal heating element of the sensor. Pins 1 and 3 connect to the load resistor while pins 4 and 6 connect to the input voltage. We used 5 V DC to power both the circuit and the internal heating element. This sensor can detect gas concentrations between 50 and 500 ppm in air which corresponds to BACs between 0.02 and 0.24.

How it works: As the gas concentration increases, the sensing resistance decreases linearly. The sensitive material that comprises the sensing resistor is Tin (II) Oxide. This material has a conductivity that changes with the purity of the air to which it is exposed. In clean air the Tin (II) Oxide has a low conductivity, and consequently a high resistance. As the alcohol concentration in the air increases, the air is less pure and the conductivity of the Tin (II) Oxide increases, which leads to a decrease in the internal sensing resistance of the transducer. Due to the configuration of this sensor, the MQ-3B should be connected to the heating voltage for 48 hours before use to ensure proper function and stability.

The sensor holds on to some of the ethanol gas after a test, and thus there is some refractory period before the device resets and can be used again reliably. This wait time is typically a couple of minutes.

Step 5: Sensor Calibration

The datasheet provides the shown calibration curve which can be used to correlate the ethanol gas concentration to the resistance of the sensor. The curve supplied by the datasheet displays a linear relationship that can be exploited to perform the calibration. The sensor is left turned on for at least 48 hours in clean air, and then the resistance value of the senor is determined. This was taken to correspond to the maximum sensing resistance that occurs at an ethanol gas concentration of 50 ppm or less. Then, the sensor is saturated by placing it in a concentrated solution of ethanol gas (we used Listerine mouth wash with 21.6% alcohol). Similarly, the sensing resistance is taken at that point to be the minimum possible resistance value which corresponds to a gas concentration of 500 ppm. Using these two data points the equation of the line can be found. This equation is then used to calculate the ethanol gas concentration based on the sensing resistance during tests.

Step 6: Arduino

The Arduino UNO micro-controller board is used as a 10-bit Analog-to-Digital Converter in this design. This Arduino board also acts as the power supply for the circuit (while it receives its power from a 9 Volt battery). We connected an LCD screen on top of the Arduino so that text could be displayed to the user throughout the operation of the device. There are several different approaches to accomplish the main goal of this task - the one that we pursued is merely one example.

We first display a home screen with both of our names while the device waits for the subject to press the "LEFT" front push button in order to begin. This push button creates a voltage at one of the Arduino's analog pins that satisfies an if statement that then displays another screen. This next screen prompts the user to press the button again to begin the test. After the button is pressed for the second time the user is prompted to blow into the tube protruding from the container for approximately three seconds. While this is happening the subject's BAC is being updated in real time on the LCD screen. At the end of the test the Arduino averages the middle third of the BAC data points to determine the final BAC value that is then displayed on the LCD screen. If the BAC is below 0.08 then an analog pin supplies enough voltage to the green LED to cause it to light up. Similarly, if the BAC is above 0.08 then a different analog pin supplies enough voltage to the red LED to cause it to light up. After about ten seconds the program resets and the home screen is displayed.

Step 7: Software

We have pasted our sample code below. This code assumes that the voltage divider is connected to pin A0, the green LED is connected to the Digital I/O Pin 2, and the red LED is connected to the Digital I/O Pin 3.

//Names

//Arduino Code for Final Project

// include the library code:

#include

// initialize the library with the numbers of the interface pins

LiquidCrystal lcd(8,9,4,5,6,7);

//set input pin to be pin A0

const int analogInPin = A0; // Analog input pin that the potentiometer is attached to

int sensorValue = 0; // value read from the circuit

int loadResistor = 1465; // value of the load resistor that we have decided to use (BAC of 0.08 corresponds to R of 1440 so used close resistance value to maximize sensitivity at this point)

int greenLEDPin = 2; // digital IO pin where our green LED is attached

int redLEDPin = 3; // digital IO pin where red LED is attached

//initialize all variables for calculating BAC

float actualVoltage;

float transducerResistance;

float gasConcentration;

float bloodConcentration;

float BAC;

float BACvalues[50];

float finalBAC;

float sum;

void setup() {

// set up the LCD's number of columns and rows:

lcd.begin(16, 2);

// initialize serial communications at 9600 bps:

Serial.begin(9600);

//set the pins where LEDs are attached to OUTPUT

pinMode(greenLEDPin,OUTPUT);

pinMode(redLEDPin,OUTPUT);

}

void loop() {

//when the breathalyzer is first plugged in (intro)

//print our names and the class name

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Names");

lcd.setCursor(0,1);

lcd.print("BME 3300L");

//make sure the LEDs start turned off and the sum starts at 0

digitalWrite(greenLEDPin,LOW);

digitalWrite(redLEDPin,LOW);

sum = 0;

// read the analog in value:

sensorValue = analogRead(analogInPin);

//convert the sensor value to the actual input voltage

actualVoltage = float(sensorValue)*5/1024;

//here say if button is pushed, go to breathalyzer start screen (pre test)

if (actualVoltage>=0 && actualVoltage<=2.00){

//print out instructions for the test

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Blow (3 seconds)");

lcd.setCursor(0,1);

lcd.print("Push to start");

delay(1000);

// read the analog in value:

sensorValue = analogRead(analogInPin);

//convert the sensor value to the actual input voltage

actualVoltage = float(sensorValue)*5/1024;

//as long as the button is not pushed, keep showing the instructions for the test

while (actualVoltage>=2.00 || actualVoltage<=0){

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Blow (3 seconds)");

lcd.setCursor(0,1);

lcd.print("Push to start");

delay(1000);

// read the analog in value:

sensorValue = analogRead(analogInPin);

//convert the sensor value to the actual input voltage

actualVoltage = float(sensorValue)*5/1024;

}

//this is after the button is pushed (b/c no longer in the while loop)

//start running the test

//tell them to blow, print out the BAC at each point

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Blow now");

lcd.setCursor(0,1);

lcd.print("BAC = ");

delay(1000);

//loop through and record BAC over the testing time

for (int ii = 0; ii<50; ii++){

//this is the code to actually calculate BAC from the circuit

// read the analog in value:

sensorValue = analogRead(analogInPin);

//convert the sensor value to the actual input voltage

actualVoltage = float(sensorValue)*5/1024;

//calculate the resistance of the transducer

transducerResistance = 5*loadResistor/actualVoltage - loadResistor;

//use the resistance of the transducer and the transducer sensitivity to determine the gas concentration

//since we can only sense > 50ppm, based on calibration set BAC to 0 when resistance is greater than 1900

if (transducerResistance <1900){

gasConcentration = -0.257*transducerResistance + 538.55;

}

else{

gasConcentration = 0;

}

//use the gas concentration to calculate the concentration in blood

bloodConcentration = gasConcentration/0.21;

//use the blood concentration to output the BAC

BAC = bloodConcentration/10000;

// print the results to the serial monitor:

//this is useful for us during the testing phase to track what is happening

Serial.print("sensor = " );

Serial.print(sensorValue);

Serial.print("\t voltage = " );

Serial.print(actualVoltage);

Serial.print("\t resistance = " );

Serial.print(transducerResistance);

Serial.print("\t gas concentration = " );

Serial.print(gasConcentration);

Serial.print("\t blood concentration = " );

Serial.print(bloodConcentration);

Serial.print("\t BAC = " );

Serial.println(BAC);

// print the results to the LCD:

// during test, print each data point while saying to blow

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Blow now");

lcd.setCursor(0,1);

lcd.print("BAC = ");

lcd.print(BAC);

BACvalues[ii] = BAC;

}

//calculate the final BAC to display by averaging the values over the middle time points

//excluded the end points because they may not be blowing at the very start or end

//didn't find the need to filter because results were very stable

for (int kk = 15; kk<35; kk ++){

sum = sum + BACvalues[kk];

}

//get the final BAC to display by averaging over the relevant time frame

finalBAC = sum/20;

//code to turn on the LEDs

//if the BAC is below the legal limit, turn on the green LED

if(BAC<0.08){

digitalWrite(greenLEDPin,HIGH);

digitalWrite(redLEDPin,LOW);

}

//if the BAC is not below the legal limit, turn on the red LED

else{

digitalWrite(greenLEDPin,LOW);

digitalWrite(redLEDPin,HIGH);

}

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Test Completed");

lcd.setCursor(0,1);

lcd.print("BAC = ");

lcd.print(finalBAC);

delay(10000);

Serial.print("final BAC = ");

Serial.println(finalBAC);

}

delay(1000);

}

Step 8: Finalized Product

The device can now be used to monitor a person's BAC as long as it is between 0.02 and 0.24. If it is lower than this range the device will output a value of 0 and if it is higher than this range the device will output a value of 0.24. Most notably - this device alerts the user as to whether they are above of below the legal limit of intoxication for operating a motor vehicle. It can now be tested in a few of ways:

1. Test the device in clean air. Make sure that it reads a value of 0 when the senor has not been exposed to any ethanol gas. If this is not the case, the calibration should be performed again after first allowing the device to be plugged in for a longer amount of time.

2. Test the device as it was designed to be used. If you are over the age of 21, you can have a couple of drinks in order to make sure that your BAC is above 0.02 and see what the device gives you as an output. Obviously this will vary based upon the user and the type of alcohol consumed.

3. Test the device using mouthwash. If you are below the age of 21, or if you simply do not desire to consume alcohol, use Listerine (or some other brand of) mouthwash and then use the device. Be sure that the mouthwash being used actually contains alcohol. If the test is performed immediately after the use of mouthwash, you will likely blow above the legal limit.

Disclaimer: the output of this device should not be taken in and of itself as confirmation that one is able to properly operate a motor vehicle. Please don't drink and drive.