NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » Breathalyzer

April 07, 2013
by scootergarrett
scootergarrett's Avatar

I got a Alcohol Gas Sensor and got some results last night. It’s very easy to wire up and use. Here is the basic circuit and code. circuit diagram

circuit pic

Code:

// Analog Sensor.c
// for NerdKits with ATmega328p
// scootergarrett
// Outputs raw data 0000-1024 for most recient A/D conversion from port PC0

// PIN DEFINITIONS:
// PC0 -- Analog input

#define F_CPU 14745600

#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/io_328p.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

volatile uint8_t OverFlowFlag = 0;

uint16_t adc_read(int port)
{
    ADMUX = port;
    ADCSRA |= (1<<ADSC);
    while(ADCSRA&(1<<ADSC));
    return (ADCL+(ADCH<<8));
}

void uart_write16(uint16_t x)
{
    // wait for empty receive buffer //
    while ((UCSR0A & (1<<UDRE0))==0);
    // send LSBF //
    UDR0 = x;

    // wait for empty receive buffer //
    while ((UCSR0A & (1<<UDRE0))==0);
    // send MSBL //
    UDR0 = *((char*)&x + 1);

    return;
}

int main()
{
    DDRB |= (1<<PB1);               // Make PC3 an output for testing

    // start up the Analog to Digital Converter
    ADMUX = 0;
    ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
    ADCSRA |= (1<<ADSC);

    // start up the serial port
    uart_init();
    FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
    stdin = stdout = &uart_stream;

    //Interrupt setup stuff
    TCCR1B |= (1<<CS12) | (1<<CS10) | (1<<WGM12);
    TIMSK1 |= (1<<OCIE1A);
    OCR1A = 1440;             //Interrupt timming 14400 is 1 second   36 is 400Hz
    sei();

    while(1)
    {
        if(OverFlowFlag)
        {
            uart_write16(adc_read(0));
            PORTB  ^= (1<<PB1);

            uart_write(0xf);
            uart_write(0xf);

            OverFlowFlag = 0;
        }
    }

    return 0;
}

ISR(TIMER1_COMPA_vect)
{
    OverFlowFlag = 1;
    return;
}

This code just sends raw data to the computer so my C program can grab and plot it as discussed Serial interface with basic C program. The sensor apparently needs 48 hours of on time before it takes reliable measurements. But if you take a bottle of gin and blow across the top towards the sensor it defiantly responds. Takes a long time to settle back. response

Future work includes extensive testing (don’t know how to calibrate without a real breathalyzer).

Adding code so a max can be recorded (and reset) then displayed on the LCD so I don’t need my computer in the testing zone.

Adding a buzzer that changes frequency with sensor response

Post a Reply

Please log in to post a reply.

Did you know that the microcontroller's crystal oscillator can be used to keep accurate time? Learn more...