So I've put some time into looking for parts and methods for more making this handheld. Ordered some bits, and I'll update more on that once those parts come in. But the more immediate and all important challenge, is continuing to iterate on the over all implementation of the circuits and software that turn this into a Breathalyzer.
Accuracy is important if this project is going to be successful. There are limitations to the MQ3 sensor, but I want to get the most out of it. So after increasing the accuracy 4.5x last week, we tested again. (All these tests occur when my friends come over to watch The Walking Dead on Friday's). The first test we saw values ranging between 0 to 6. (Remember these values are just voltage readings from an Analog to Digital [A2D] converter provided on the Arduino). Now that wasn't good, over 10 beers, the values only increased 6 points. That's not nearly enough resolution in the signal to be useful. My second attempt after the 4.5x bump in resolution, produced values between 11 and 23. (Note the oddity there of nothing below 11. In my next post I'll go into my testing procedures, and why there are oddities in these readings, as well as almost certainly in commercial breathalyzers used by authorities.)
[warning: technical details ahead!]
The general idea here is that the MQ3 is essentially a variable resistor. When no alcohol is applied, it is entirely resistive, letting no electricity through. As you apply more and more alcohol gas to the sensor, it's resistance drops, letting larger and larger amounts of electricity through. That current is piped into one of the Arduino's A2D pins, where it converts it to a digital number that I can then use in my code.
The A2D takes a signal between 0V and xV and converts it to a number between 0 and 1023. Where xV is the Analog Reference Value: a voltage that the Arduino uses as the top end. By default 5V is used. There for if you put 5V into the A2D you get a reading of 1023. If you put in 2.5V, you get 512, and so on.
The problem with "resolution" as I've called it here, is that even with what our bodies consider to be very large amounts of alcohol (like deadly levels) they are still relatively low levels to the sensor. Example: after 10 beers, my BAC is ~0.104%, aka: pretty darn tipsy. But the resistor is still only letting through 0.029V out of 5V.
The solution? Shrink the range that the A2D is using for conversion. My first attempt at this used a built in function of the Arduino, to change the top end Analog Reference Voltage from 5V t0 1.1V. This is what gave me the roughly 4.5x improvement in resolution. But it still wasn't quite enough. So I began looking further into how to reduce the top end so the range has a closer fit to the values we are actually producing.
I found a feature of the Arduino that allows you to supply a voltage to a special pin (AREF), and what ever that voltage is, will be used as the Analog Reference Voltage by the A2Ds. So the next step was to find the correct voltage and reliably produce it!
I turned to voltage dividers.
Very simple circuits, you just do some math based on the input voltage and the target voltage to determine what resistors to use in it. And it will always output the desired voltage. I calculated from my previous tests that the desired top end, for maximum resolution, would be ~0.24V. Maybe a little more to pad for outliers. In practice however this ran into real world problems. And I ended up hooking in my 10kOhm potentiometer to find the lowest voltage I could use.
So far it looks like 0.5V is the lowest I can reliably use. Which is still pretty good. That will give me about half of the A2D value as usable range. Between 0 and 512. Which is a bit more than a 2x improvement on top of my first attempt.
With that determined, I can begin working out the actual BAC calculations based on my readings which should finally be of sufficient resolution.