Introduction: The Talking Breathalyzer Mark II

About: Hi there! My name is Patrick, and I am an electronics engineering technician who works full time as a lab tech, and part time as an electronics engineer/salesman. I own an ebay store, and two websites, which …
Hi Folks!
Thanks for having a gander!  This is my second Breathalyzer project.  IT TALKS TO YOU, and gives you an idea of how much you've had to drink! I made it specifically for for this contest.  I hope you all like it.  From a block diagram point of view, it consists of a DC power regulator circuit, an analog alcohol sensor + driving circuit, an audio recording and playback circuit, and the brain, which is a single PIC18F1220 MCU.  If you have the time, go though my Instructable, and you will see how it works.  The program is relatively simple, the function is REALLY NIFTY, and the hardware is easy to assemble.  The original breathalyzer that I made about a year ago was perhaps more fun to play with, but required a lot more hardware, and was inferior in design.  This version is much simpler, and it would be relatively easy for someone to reproduce it, or something similar.  If you want to see the original, go here:
http://www.youtube.com/watch?v=MpKCxDtz5PE

Here is a video demonstration of this project:

A lot of the parts involved with this project can be found on www.electroniclessons.com or www.engineeringshock.com.  I will break this down into three areas of instruction:
1) Hardware and Assembly
2) Function
3) Software
4) Math and Conclusions

Of course, this won't all be done in only a few steps, but I think you will have a lot of fun learning as we go along!  Now, if you watch the video, you'll get a good idea as to how this is meant to function.

The idea is this: 
1) The MQ3 alcohol sensor has an analog output.  You when you blow on the sensor, the output voltage changes based on two variables. First, the amount of alcohol it detects, and second, the value of the pull-down resistor at the output.  If you have the proper value for the pull-down resistor, then you will get a good voltage range at the output.  Low voltage = Little booze / Higher voltage = Lotsa booze!
2) We want to take that analog voltage and read it digitally.  How?  The brain chip, or MCU: the PIC18F1220, has a 10-bit internal analog to digital converter (Set up in program to work as an 8-bit ADC) that takes the analog voltage from the MQ3, and changes it into an 8 bit binary number, that can be interpreted digitally by the PIC. 
3) On power on, you can program the audio recording IC on the board by pressing the record button.  Since it will be our audio indicator that it is time to blow on the sensor, it is only appropriate that we hold down the RECORD button and say something along the lines of  ":BLOW ON THE SENSOR", or perhaps something a little more humorous.  From there, we can press the PLAYBACK button to hear our message, to make sure it is what we want.  this audio message is stored in memory, and is not lost when the device is powered off.  The audio message can be up to 12 seconds.  We are going to use this sound byte later.
4) We've had a few beers to drink.  How is our drunkenness ranked?  Well, press the SAMPLE button (As seen in the video).  Assuming the output of the MQ3 is stable, the chip will not have to go through a calibration sequence.  It will order your audio recording IC to playback your sound byte "Blow!", at which point you will blow into the sensor.  The output LEDs (6 of them) will shift upwards 12 times (Just to pass some time while you blow into the sensor), at which point the PIC makes its calculation, and BOOM, the output LED that indicates your level of drunkenness.
5) The program resets. 
6) From there, if you want to take another reading, press the SAMPLE button again.  If the output is still unstable from the last reading, it will go through a calibration state before the audio byte sounds. 

Ready for Step#1? 

Step 1: Step#1 Hardware: the Full Schematic + Parts List

Okay, so now you can see each block! 

1) The upper right block of the schematic is the ISD1218 chip with all necessary passive components.  This bad boy is used to record an audio byte that will be played back when the PIC determines when it is time to take a reading.  For instance, if no calibration period is necessary, or when calibration is complete, the PIC will initiate playback of the audio byte; "BLOW into the sensor", or something to that end.

2) The upper left block shows off the very simple LM7805 regulator circuit.  since there will be no further explanation for this block, let's talk about it a little bit here.  There is an input terminal block for DC-In.  In order for the LM7805 chip to output a solid 5VDC, we have to make sure that there is at least 7VDC at the input (Pin#1) at all times, or else the circuit will not work properly.  A 9V battery is more than satisfactory, although it it suggested that you use an on/off switch (not seen here), and that you use a Duracell or Energizer battery, as the MQ3 sensor is a power sucker.  We will talk about that later.  So, we want 7VDC+ at the input pin (Pin#1), Input DC- (Ground)) at pin#2, and 5VDC (regulated) at pin#3.  This 5VDC line will power ALL of our blocks!  The 100uF capacitor at the input is used to smooth any ripple on the DC input. However, if you are using a battery, there is really not necessary, as there should be no ripple at all.  The 0.1uF capacitor at the output is merely to decouple the circuit, and dissipate any unlikely high frequency spikes.

3) In the lower left Block, we see the MQ3 alcohol sensor and driver circuit.  This sensor has an analog output.  The heater (middle two pins) is merely a 150mA coil (at 5v input voltage).  This makes this component a relatively high power pain in the butt =)  However, if you have an ON/OFF switch and a good battery, you're good for a few nights on the town!  We will talk more of this block function later on, as well as the required driver circuit.

4) Ah, the BRAIN!  Block#4!  The MCU is a PIC18F1220, 18-pin DIP IC, made by Microchip Technologies.  The code is a little long, as we are using assembly code, but I think that it is a very simple program.  There is a little basic math involved, but nothing a grade 7 student couldn't handle =)  I have done my very best to comment what each line of code does, and if you are interested, I will happily send you the .ASM code to you so that you can replicate it exactly, or perhaps modify it.  The PIC has several functions.  It takes instructions from the SAMPLE button, located at pin#7 (PORTA,RA3), instructs the ISD1218 record and playback IC to playback an audio byte when necessary (after the calibration period), takes the analog voltage from the MQ3 sensor, and changes it into an 8-bit binary number, does the math, adds wait-times (delays), and does the math.  When a conversion has been made, the LED that is relative to your intoxication lights up (LED#1 being little to no alcohol, and 6 being massively wasted).

We will talk about each of these blocks, minus the power supply, as well as the code in the following steps.  Here is the parts list:

1x 2-pronged terminal block
1x 100uF electrolytic capacitor
1x 0.1uf ceramic capacitor
1x 10uF electrolytic capacitor
1x 10k Ohm resistor
1x 1k Ohm multi-turn potentiometer
1x 10k Ohm resistor
6x 330-470 Ohm resistors
7x Red LEDs
1x LM7805 5v regulator
1x MQ3 Alcohol sensor
1x Mini 8-ohm speaker
1x ISD1218 record and playback IC (kit at www.electroniclessons.com)
3x Monetary push-buttons
1x 1N4401 Diode
1x Electret  condenser microphone
1x PIC18F1220

The MQ3 and the ISD1218 kit can be found at http://www.electroniclessons.com.  I can offer you a programmed PIC18F1220 if you'd like, as well.  Heck, maybe I could put this whole thing together as a kit.  That might be fun! =)  As well, my youtube channel can be found here:
http://www.youtube.com/user/patrickikis


Step 2: Step#2 Hardware Breakdown - MQ3 Sensor

The MQ3 is an easy to use analog alcohol sensor.  It has 6 pins:
1) A
2) H
3) B
4) A (2)
5) H (2)
6) B (2)

The two (A) pins are connected internally, so you have the option of using either of them.  The same goes for the (B) pins.  There are two Heater pins, and they are not polarized in any way, so you can connect 5V/GND from either left to right, or from right to left.  The resistance on the heater coil is 150 Ohms, so when you power it at 5V, it consumes 150mA on it's own.  This is why it is necessary to have an on/off switch, as the battery will drain if left on.    You can also apply 5v from (A) to (B) or from (B) to (A).  This sensor was built to be very versatile.. 

The basic idea is this:  When you blow onto the heater coil through the head of the sensor, the voltage at the output (In this case pin B) changes.  Some people say to use a 100k trim-pot between the output and ground, but I have never had a good result using such a high resistance.  Notice that the pull down trip pot is 1k Ohms.  I calibrated it to about 427-428 Ohms, so if you wanted to get a good voltage range at the output, I suggest using either a 420 Ohm resistor between your output and ground, or the trip,-pot.

When the sensor powers on, the output is slightly unstable, much like a PIR sensor.  However, it does not take long for the output to becomes usable.  When the output reads below 700mV, it is in the usable range, however, if left on, the output will likely go down to as low as 300mV, but that is of little consequence, as the program does not work with any voltage under 700mV.  

If you want to know more about this sensor, I found a great blog about it that can be found here:
http://sensorworkshop.blogspot.com/

The output voltage range is between roughly 300mV to about 3.70v.  However, if you legitimately blew an output reading of 3.5v or higher, you'd likely be on your way to the hospital =(  If you take a swig of hard liquor, then blow into the sensor, you're going to blow a 6 (Highest).  However, if you wait 5 minutes or so since your last drink, you will have a more legitimate idea of exactly how much alcohol you've had to drink.  

The output voltage is fed to the pin on the PIC18F1220 that I've assigned through programming to be the internal ADC.  When the PIC takes a reading, it will sample the analog voltage at PORTA,RA0 (Pin#1) and convert it into an 8-bit binary number. 

Step 3: Step#3 Hardware Breakdown - ISD1218 Record/Playback IC

There isn't too much to say here!  These kits can be found at http://www.electroniclessons.com
which brings you to our ebay store.  This ISD1218 record and playback IC is a very thin little board that has all of the required passive components already installed on it.  All you need is an LED (optional), a couple monetary push buttons (one for record, and one for playback), a 5VDC source, an 8 Ohm 2W speaker, and an electret microphone to work this chip.  The 1N4404 diode and the 10uF capacitor are not included in the kit, but they are used to aid the PIC in activating the playback function through program control. 

The 1N4004 diode is to protect the output of the PIC from when the user manually plays back a recorded message,  The diode blocks voltage from the PIC input (RA0) when the button is pushed.  There will be a small voltage drop along the diode when the PIC output goes high to activate playback, but the drop is not near enough to hinder activation.  The 10uF capacitor is to protect the ISD chip from being falsely activated upon power on, as the PIC is not software configured for a Power On Reset, as many register values would start in odd states.  it was just easier to add in this 10uF capacitor.  Works like a charm =) 

Upon power-on, the user can at any point in time record a new message, and play it back at any point in time using the two buttons.  Remember, the program uses the recorded audio byte to indicate to the user that it is time to blow into the sensor, so an audio byte along the lines of "BLOW!", or "Blow into the sensor!" would be appropriate.

Step 4: Step#4 Hardware Breakdown - PIC18F1220 + LEDs, Etc...

the PIC18F1220 is a wonderful MCU.  The slightly advanced Assembly code instruction set (compared to older PIC families) makes this project very easy to conquer.  There is no external oscillator necessary here, but you have that option.  It is not necessary here because timing is not an important factor in this project.  It is configured to use the internal oscillator.

We are using the PORTB RB0-RB5 I/O pins as outputs to power the LEDs, PORTA RA0 I/O pin as the output used to activate the ISD1218 IC set, RA1 as the analog input for the internal analog to digital converter, and RA3 as the sample input.  We have a 10k Ohm pull up resistor on this pin, which keeps the input held high until the sample button is pressed; bringing the input low, and activating the program sequence.  The resistors that are limiting current the LEDs can be any value between 200-600 Ohms.  The PIC requires a 5V VCC (OR VDD), and Ground (VSS). 

Step 5: Step#5 How We Want Our Breathalyzer to Function!

****Okay, let's go through the functional diagram***

1) SAMPLE? YES/NO
The PIC is scanning to see if the SAMPLE button is being pressed,  It will keep checking thousands of times a second to see if the sample button has been pressed.  If not, sample again.  If so, move onto next step.

2) SAMPLE ADC - STORE VALUE
The PIC takes a sample of the analog voltage given off by the MQ3 output and converts it into an 8-bit binary code (0-255).  Once this sample is taken, the binary value is stored in an 8-bit general register for safe keeping. 

3) OUTPUT STABLE?  YES/NO
Here, the PIC takes a comparison of the binary value of the MQ3 output.  If it below a certain binary number, it can progress.  If not, the sensor goes into a calibration mode, and waits for the sensor output to become stable.  See WAIT - ACTIVATE LED SEQUENCE Block
A) Turn all LEDs on
B) Delay
C Turn all LEDs off
D) Delay
E) Sample ADC and compare again
F) Repeat steps A-D until output of MQ3 is Stable  (See calculations and math in final step)

4) WAIT - ACTIVATE LED SEQUENCE
A) Turn all LEDs on
B) Delay
C Turn all LEDs off
D) Delay
E) Sample ADC and compare again
F) Repeat steps A-D until output of MQ3 is Stable  (See calculations and math in final step)

5) ACTIVATE ISD1218 + WAIT STATE
The MQ3 output is stable, and ready for the user to blow.  The PIC will now activate the ISD playback sequence; "BLOW INTO THE SENSOR".

6) *WAIT* ACTIVATE LED SEQUENCE
All LEDs will shift from 1-6 very quickly 12 times before the second last step.  This is a time waster that gives the user some time to blow into the sensor.  One this sequence is complete, we go to the second last step.

7) SAMPLE ADC - STORE
The PIC samples the ADC one more time.  The user should have been blowing into the sensor, and therefore changing the output voltage of the MQ3 depending on how much alcohol He/See has consumed.

8) CALCULATE RESPONSE + OUTPUT LED
The PIC takes the new value in the ADC, performs a set of 5 comparisons.  once the comparison is complete, the output inductor LED that matches the calculation will light up for a few seconds, so that the user has time to see.  At which point, the program resets.

END


Note:
Upon power on, there should be really no need for any start-up calibration sequence.  However, if the user has just taken a reading, and wants to take another right away, the output of the MQ3 may very well need time to become stable again, depending on how much alcohol had been consumed.





Step 6: The Program: PIC MCU ASM CODE (Assembly Code)

I have done my very best to comment the code to the best of my ability, but I am having problems with the word processor, so the commented software can be found here:
http://www.electroniclessons.com/talkingbreath.txt
I am placing it in the document as well, but the comments look messy.  Sorry that that =(

If any of you want the .ASM file, please don't to ask!    I used an ISD2 Programmer puck and MPLAB IDE software to program my PIC.  If any of you have any questions,  I am always happy to answer If you want to know more about this programmer, look here:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010046&part=DV164005

HERE IS THE CODE:

;    *** main code goes here ***
MOVLW 0X40            ; SET INTERNAL OSCILLATOR FREQUENCY
MOVWF OSCCON    ; INITIALIZE
MOVLW 0X00            ; SET UP PORTB TO BE ALL OUTPUTS   
MOVWF TRISB          ; INITIALIZE
CLRF PORTB            ; CLEAR PORTB OUTPUTS
MOVLW 0XFE             ; 00001110
MOVWF TRISA            ; SET UP PORTA TO BE ALL OUTPUTS EXCEPT FOR RA1/2/3
CLRF PORTA            ; CLEAR PORTA
MOVLW 0X05            ; SET UP ADC
MOVWF ADCON0     ; ENABLE ADC, BUT DO NOT START CONVERSION
MOVLW 0X7D            ; SET UP ADC
MOVWF ADCON1      ; AN0/RA0=ANALOG INPUT
MOVLW 0X0F              ; SET UP ADC
MOVWF ADCON2       ; SET UP TIMING FOR ADC CONVERSION  (SEE DATA SHEET FOR ;ADCON0/1/2 REGISTER FORMATION OPTIONS
;RA0=PLAYBACKOUT
;RA1=ADC-IN
;RA3=SAMPLE

STARTUP:
BTFSC PORTA,RA3     ;Pull up resistor keeps RA3 high until button is pressed. This instruction ;checks the status of RA3.  Skips next  instruction if low (button pressed).
GOTO STARTUP          ;If button has not been pressed, go back to start-up and check again.  ;LOOPS UNTIL BUTTON IS PRESSED.
MQ3CHECK:                  ;This routine acts to check the output of the MQ3 to determine when it has ;become stable enough for another measurement.
CALL RUNADC             ;By calling the RUNADC subroutine, we are going to take an 8-bit ;representation of the MQ3 output, and store it in memory
CALL LEDSIGNIFY      ;Call subroutine that indicates a wait-state to user using LEDs on PORTB
MOVLW 0x1E                ;Move predermined reference value into W (Working) register.
CPFSLT GEN5             ;Compare value in WREG to ADC value in GEN5.  SKIP if WREG contents ;is larger than ADC value.
GOTO MQ3CHECK         ;If MQ3 is not ready to take a reliable reading, take another sample
CALL VOICE                     ;Call voice recording routine
CALL LOOP1
CALL WAITSTATE           ;Call routine that indicates that device is reading sensor, and that the ;user should blow until the LEDs stop blinking.
CALL RUNADC               ;Run ADC again for a new reading
CALL DETERMINE        ;Run a determining subroutine that does the math

RUNADC:
BSF ADCON0,GO/DONE  ;Start the conversion - Set GO/DONE bit in register ADCON0
STEP2:
BTFSC ADCON0,GO/DONE    ;The GO/DONE bit in ADCON0 will stay high until conversion has ;been completed.  Check if bit is high, go back to STEP2. If not, continue.
GOTO STEP2
MOVFF ADRESH,GEN5      ;Safely move 8-bit contents of ADC register to GEN5 register for later.
RETURN                                ;End subroutine

LEDSIGNIFY:
SETF PORTB           ;Turn on all PORTB outputs (All LEDs on)
CALL LOOP1            ;Call Delay Loop subroutine to elapse some time
CLRF PORTB          ;Turn off all PORTB outputs (All LEDs off)
CALL LOOP1           ;Another delay
RETURN                  ;Return from sub-routine

VOICE:
BSF PORTA,RA0     ;Send signal to ISD1218 Device - Activate recording (Ready for alcohol reading)
CALL LOOP1            ;Delay used to make sure that ISD1218 chip is properly enabled
BCF PORTA,RA0     ;Turn disable signal to ISD1218
RETURN                   ;Return from subroutine

WAITSTATE:             ;Offer the user time to blow into the sensor
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL WAITSTATE2
CALL LOOP1
RETURN

WAITSTATE2:                   ;Blinks LED in order from 1-6
MOVLW 0X01
MOVWF PORTB
CALL LOOP3
MOVLW 0X02
MOVWF PORTB
CALL LOOP3
MOVLW 0X04
MOVWF PORTB
CALL LOOP3
MOVLW 0X08
MOVWF PORTB
CALL LOOP3
MOVLW 0X010
MOVWF PORTB
CALL LOOP3
MOVLW 0X20
MOVWF PORTB
CALL LOOP3
CLRF PORTB
RETURN

DETERMINE:
MOVLW 0x24              ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've ;found your alcohol level!
CALL LED1                 ;If not, light up LED #1 (No alcohol level detected).
MOVLW 0x3B              ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've found your alcohol level!
CALL LED2                 ;If not, light up LED #2 (A beer or two).
MOVLW 0x52              ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've ;found your alcohol level!
CALL LED3                 ;If not, light up LED #3 (Two or three in the past hour - Roughly.  Likely ;shouldn't drive).
MOVLW 0x69               ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've ;found your alcohol level!
CALL LED4                 ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've f;ound your alcohol level!
CALL LED5                 ;If not, light up LED #5 (Drunk.  Don't drive, or hit on people you know you shouldn't!!!).
MOVLW 0x95               ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG,skip next instruction, if not, you've found ;your alcohol level!
CALL LED5                     
CALL LED6
RETURN

LED1:
BSF PORTB,RB0          ;TURN ON LED1
CALL LONGDELAY      ;Call a long delay
RESET                            ;Result displayed - reset program

LED2:
BSF PORTB,RB1          ;TURN ON LED2
CALL LONGDELAY      ;Call a long delay
RESET                           ;Result displayed - reset program

LED3:
BSF PORTB,RB2          ;TURN ON LED3
CALL LONGDELAY      ;Call a long delay
RESET                           ;Result displayed - reset program

LED4:
BSF PORTB,RB3          ;TURN ON LED4
CALL LONGDELAY      ;Call a long delay
RESET                            ;Result displayed - reset program

LED5:
BSF PORTB,RB4          ;TURN ON LED5
CALL LONGDELAY      ;Call a long delay
RESET                            ;Result displayed - reset program

LED6:
BSF PORTB,RB5          ;TURN ON LED6
CALL LONGDELAY      ;Call a long delay
RESET                            ;Result displayed - reset program

LONGDELAY:
MOVLW 0X05                 ;Move a decimal value of 10 into WREG for reference
MOVWF GEN6               ;Store WREG value in GEN6
LONGDELAY2:
CALL LOOP1                  ;Call delay
DECFSZ GEN6               ;Decrement value in GEN6, skip if GEN6=0
GOTO LONGDELAY2    ;Repeat delay until value in GEN6 is zero
RETURN                          ;Return from subroutine 


LOOP1:                              ;Delay loop sub-routine that works with LOOP2 routine.  Enter values ;into 3 Registers in loop1 (See Loop2)
MOVLW 0X00
MOVWF GEN1
MOVLW 0XFF
MOVWF GEN2

LOOP2:            ;Countdown values from LOOP1 until 0
DECFSZ GEN1,1
GOTO LOOP2
DECFSZ GEN2,1
GOTO LOOP2
RETURN

LOOP3:            ;Alternate Delay timing subroutine
MOVLW 0X19
MOVWF GEN2
CALL LOOP2
RETURN

RETURN

;******************************************************************************
;End of program

Step 7: Final Step: the Math, and the Conclusions!

THE CONCLUSIONS:
This project was fun, and relatively simple to make.  However, it is a novelty item.  I would never suggest to anybody that it would be a good idea to saturate the sensor.  It is not healthy to get that drunk.  You don't want to end up like the guy int he urinal =)

In the future, I think I might make a breathalyzer that has a 0.00-0.13 blood alcohol level detection.  I have a real breathalyzer here to make comparisons to. 

If any of you have any questions, I am happy to help.  I hope you liked this instructable, and maybe had a laugh!
VISIT MY YOUTUBE CHANNEL HERE:
http://www.youtube.com/user/patrickikis
VISIT MY EBAY STORE HERE:
http://stores.ebay.com/hobbytronixstore

THE MATH:

There really is not too much math involved.  The internal ADC of the pic is using 5V and ground as references.  Since we've set up our program to the the 10-bit ADC data and ignore the least significant bits, we are using an 8-bit register.  An 8-bit register can hold binary numbers that are relative to decimal values.  For instance:
1111 1111 = 255 Decimal = FF HEX
0000 0000 = 0 Decimal = 00 HEX

Since we are using 5V as reference, lets break it down relative to what each bit is worth in voltage.  Here is an easy way to figure it out.
Each bit is worth:
5v(REF) / 255 = 0.0197V, or ***19.6mv***
So 0000 0001 = 19.6mv = 01 HEX  (Note that if you are lazy, you can find a decimal to Hex calculation by searching google.

Since the output of the sensor is "Stable' in my configuration when the output is 700mV or less.  So since we have to do a comparison in software, we have to figure out what the Hex value of 700mV is.

Here is how we find it:
Since we know that one bit is equal to 19.6mv (0.0196), all we have to do is divide 700mv, but this bit weight, and you have your answer! 700mv (0.7) divided by 19.6mv (0.0196)
700mV = roughly 36 bits.  
So 36 Decimal is equal to 24 Hex.  (0010 0100)

In the program, once we tell the device to take a sample, it does a calibration sequence:
1) LOAD W-REGISTER WITH 24H
2) COMPARE IT WITH VALUE FROM ADC
3) IS W-REGISTER VALUE LARGER THAN ADC VALUE (ADC value is less than 700mV)?
4)IF YES, PROCEED WITH PROGRAM
4) ELSE,  SAMPLE AGAIN AND REPEAT PROCESS UNTIL MQ3 OUTPUT IS STABLE

Since the high end of the voltage range of the MQ3 in this configuration is roughly 3.5VDC, and the stable voltage is 700mV or under, the PIC is programmed to take different values in between and do comparisons until it determines which level of drunkenness you are at. The following subroutine keeps moving values in the the W REGISTER and compares it to the ADC value that was sampled after the user blew into the sensor.  In the first step, If the Value of the ADC register (GEN5) is smaller than the value in WREG, then it will chose LED#1 (You are not drunk).  If the value in the ADC register is larger than the value in WREG, then you skip to the next comparison (For LED2). For the second comparison, we load a new number into WREG that equates to a higher voltage comparison.  If ADC Register is larger than contents of WREG, go to the next step (LED3 comparison),  If not, call the routine that lights up LED#2.

DETERMINE:
MOVLW 0x24              ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've ;found your alcohol level!
CALL LED1                 ;If not, light up LED #1 (No alcohol level detected).
MOVLW 0x3B              ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've found your alcohol level!
CALL LED2                 ;If not, light up LED #2 (A beer or two).
MOVLW 0x52              ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've ;found your alcohol level!
CALL LED3                 ;If not, light up LED #3 (Two or three in the past hour - Roughly.  Likely ;shouldn't drive).
MOVLW 0x69               ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've ;found your alcohol level!
CALL LED4                 ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG, skip next instruction, if not, you've f;ound your alcohol level!
CALL LED5                 ;If not, light up LED #5 (Drunk.  Don't drive, or hit on people you know you shouldn't!!!).
MOVLW 0x95               ;Move value into WREG for reference
CPFSGT GEN5          ;If ADC value is greater than WREG,skip next instruction, if not, you've found ;your alcohol level!
CALL LED5                     
CALL LED6
RETURN



Microcontroller Contest

Participated in the
Microcontroller Contest