A Tweeting .NET Micro Framework breathalyzer

Sign in to queue


This project shows how you can use the Netduino Plus to make a tweeting breathalyzer—a standalone breathalyzer that can post messages about the detected alcohol level to Twitter, using an inexpensive alcohol gas sensor.

The Netduino is an open source electronics platform based on a 32-bit microcontroller running the .NET Micro Framework. The Netduino Plus is similar to the original Netduino, but adds a built-in Ethernet controller and MicroSD slot. Since the Netduino Plus can connect directly to a network, it can independently communicate with Twitter’s API without being connected to a computer.

Hardware Overview



The MakerShield is a simple prototyping shield that is compatible with the standard Arduino and Netduino boards.

In this configuration, the MQ-3 alcohol gas sensor will output an analog voltage between 0 and 3.3V to indicate the amount of alcohol detected. This output will be connected to one of the Netduino’s analog input pins and read by its ADC.

While it would possible to convert the sensor’s output to a numeric BAC level, this would require careful calibration and would be prone to error. For this project, I will use approximate value ranges to determine which of several messages should be posted to Twitter. An approximate reading will be displayed on an RGB LED.


The RGB LED is the primary status indicator. During normal operation, it shows the level of alcohol, represented by colors ranging from green to red.

Three transistors are used to provide power to the RGB LED. The microcontroller used on the Netduino has a relatively low current limit per IO pin (around 8 mA for most pins) so it is generally not advised to drive LEDs (which can require 20-30 mA) directly from these pins. Using a transistor (or another LED driver) helps ensure that enough power will be made available to each LED without damaging the Netduino.

This page shows some common transistor circuits, including a few "transistor as a switch" circuits. Since the RGB LED I am using has a common cathode (low side) lead, I am using PNP transistors to switch the anode (high side) of each color.

Alcohol Gas Sensor


The MQ-3 essentially has two components: a heater and an alcohol gas sensor. The heater literally applies heat to the sensor in order to provide more accurate measurements and requires a constant 5V power source. The alcohol sensor acts as a variable resistor, where the resistance decreases as the level of alcohol increases.

While the heating element requires 5V, the alcohol sensor can actually operate at a different voltage. Applying 3.3V to the sensor (VC in the above diagram) will ensure that the output voltage (VRL) doesn’t exceed the Netduino’s input limits.

The sensor and RL act as a voltage divider. The datasheet for this sensor shows that the resistance across the sensor is between 2K-20K ohms, so an RL value of 10K ohms will provide a wide voltage output range.

Other Components

The MakerShield has two LEDs that I am using to display some additional status information. The red LED indicates whether the device is ready to post to Twitter, and the Green LED indicates that a post is in progress.

I am also using the button on the MakerShield to trigger the Netduino to post a message on Twitter. You could also write code to automatically post based on level peak detection, but for simplicity I decided to just use the button as a trigger.


Pin configuration, Twitter API keys, the NTP server address, and other settings are stored in a Config class (Config.cs in the project root). If you download the source code for this project from CodePlex, make sure you copy the Config.sample.cs to Config.cs and take a look through the file to confirm all the settings:

public static class Config
    // NTP Server
    public const string NTPServer = "time-a.nist.gov";
    public const int TimeOffset = -7;    // MakerShield LEDs
    public const Cpu.Pin RedLEDPin = Pins.GPIO_PIN_A5;
    public const Cpu.Pin GreenLEDPin = Pins.GPIO_PIN_A4;    // RGB LED
    public const Cpu.Pin RGBRedPin = Pins.GPIO_PIN_D10;
    public const Cpu.Pin RGBGreenPin = Pins.GPIO_PIN_D6;
    public const Cpu.Pin RGBBluePin = Pins.GPIO_PIN_D9;
    public const bool RGBInverted = true;    // Button
    public const Cpu.Pin ButtonPin = Pins.GPIO_PIN_A3;    // Alcohol Gas Sensor
    public const Cpu.Pin SensorPin = Pins.GPIO_PIN_A0;
    // The Netduino's 10-bit ADC has a maximum value of 1023, but the sensor may not reach the highest possible voltage.
    // Input values >= the SensorMaxValue will be treated as 100%.
    public const int SensorMaxValue = 900;    // Twitter
    public const string ConsumerKey = "YourConsumerKey";
    public const string ConsumerSecret = "YourConsumerSecret";
    public const string UserToken = "YourUserToken";
    public const string UserTokenSecret = "YourUserTokenSecret";

In order to post messages on Twitter, it is necessary to register an application through Twitter’s developer portal. Instructions for this can be found on the MicroTweet CodePlex Page.


When the Netduino first powers on it will wait for a few moments to let the alcohol gas sensor heat up and establish a baseline reading. The sensor’s datasheet recommends a preheat time of 24-48 hours, but the readings typically stabilize after a few minutes. During this time the RGB LED will slowly fade from blue to red to indicate that the sensor is heating up.


A simple RGB LED helper class is included to help make controlling the color and output of the LED easier. The class must be instantiated with three Cpu.Pin addresses, one for each color:

protected static RGBLED rgbLed = new RGBLED(Config.RGBRedPin, Config.RGBGreenPin, Config.RGBBluePin, Config.RGBInverted);

In the sample code, these pins are pulled from the Config class. The last parameter for the RGBLED constructor, invertOutput, is used to determine whether a logical high output value turns the LED on or off.


Next, the Netduino will attempt to update the system time from an NTP server. This is necessary for communication with Twitter’s OAuth API because all requests must contain an accurate timestamp. If the NTP server is unreachable, the Twitter functionality will be disabled, but it will still be possible to see the alcohol level on the RGB LED.

The code to communicate with an NTP server is included with the MicroTweet library. The UpdateTimeFromNTPServer method will contact the specified NTP server and update the Netduino’s time:


If the time is updated successfully, a new instance of the TwitterClient class is created:

twitterClient = new TwitterClient(Config.ConsumerKey, Config.ConsumerSecret, Config.UserToken, Config.UserTokenSecret);


Measurements from the alcohol sensor are repeatedly taken within the main program loop. The 10-bit ADC will return a value between 0 and 1023, but these values don’t necessarily correspond to the minimum/maximum readings from the alcohol sensor so some calculations are performed to convert the ADC value to a number between 0 and 100:

protected static AnalogInput SensorInput = new AnalogInput(Config.SensorPin);// ...public static int GetSensorValue()
    int rawValue;
    lock (SensorInput)
        rawValue = SensorInput.Read();
    int adjustedValue = (rawValue - SensorMinValue) * 100;
    int result = adjustedValue / (Config.SensorMaxValue - SensorMinValue);
    return result;

SensorMinValue is the baseline measurement established when the program was starting up. Config.SensorMaxValue is the configured "maximum" value that indicates the highest detectable alcohol level. Depending on your sensor, this maximum value may need to be adjusted.

It’s also worth noting that it can take about 30 seconds for the sensor to return to its baseline value after a measurement. This screenshot shows the sensor’s output before and after taking a reading:


In this test, the baseline measurement (with no alcohol applied to the sensor) was about 1V. When alcohol was applied to the sensor the output quickly peaked at just under 3V, and then slowly decreased once the alcohol was removed.

Posting to Twitter

Sending a tweet from a TwitterClient instance is simple:

twitterClient.SendTweet("Hello, world!");

In this project, the MakerShield’s button is used to trigger the Netduino to post a message on Twitter. This button is monitored by an instance of the InterruptPort class, which fires a C# event when the input changes on the selected pin:

protected static InterruptPort button = new InterruptPort(Config.ButtonPin, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLevelLow);// ...static void button_OnInterrupt(uint data1, uint data2, DateTime time)
    if (twitterClient == null)
    greenLED.Write(true);    int sensorValue = GetSensorValue();    string message;
    if (sensorValue < 20)
        message = "No alcohol detected";
    else if (sensorValue < 40)
        message = "Tipsy";
    else if (sensorValue < 60)
        message = "Drunk";
    else if (sensorValue < 80)
        message = "Whoa! #WINNING";
        message = "x_x";    DateTime adjustedTime = DateTime.Now + new TimeSpan(Config.TimeOffset, 0, 0);    message += " at " + adjustedTime.ToString("h:mm:ss tt");    try
    catch (Exception e)
    }    greenLED.Write(false);

The button event handler code in this project is relatively simple: the current level from the alcohol sensor is read, a message is generated, and it attempts to post the message to Twitter. The current time is appended to the end of the message to avoid issues with multiple identical tweets.




The code for this project is included in the Samples folder of the MicroTweet library. Be sure to check out the MicroTweet project page on CodePlex for the source code and more information.

MicroTweet is released under the Apache 2.0 license, so it can be freely used in your own projects with attribution.


About the Author

Matt Isenhower is a desktop and mobile application developer who primarily works with the .NET Framework. His company, Komodex Systems, is currently focused on building new and exciting apps for Windows Phone 7 and other platforms. He also has a blog and can be followed on Twitter at @mattisenhower.

The Discussion

  • User profile image
    Chris Walker

    Very cool, Matt. Do you have a parts list and a schematic for this? I'd love to build one.


  • User profile image

    @Chris Walker: part list is upper right Smiley

  • User profile image

    , Clint wrote

    @Chris Walker: part list is upper right Smiley

    [sheepish look] 

    I see it now.  Love the new standardized format...  Thanks Clint!

  • User profile image
    Ben C

    Wow, very cool indeed! I look forward to building one!

    What did you use as your oscilloscope (to make the picture scope[2].png)?

  • User profile image

    @Ben C: I have a slightly older GW Instek GDS-1022 oscilloscope (and I just added some annotations to the screen shot from my computer).  At this point it's probably better to get the Rigol DS1052E, which is in a similar price range with some additional features.

  • User profile image

    The #WINNING hashtag in your sample code implies that you believe more alcohol in your bloodstream is better, and that you are envisaging some kind of drunken tweet-off as to who can drink themselves to a certain level.

    Don't you think that's rather childish (not to mention irresponsible)?

  • User profile image

    The previous post implies a poster who is not familiar with Charlie Sheen and his antics.

  • User profile image

    @piers7: As commenter Orlando mentioned it's a reference to Charlie Sheen's Twitter antics and obviously not meant as any sort of a "goal."  While Charlie may think he's winning, the rest of us can take a more practical and accurate view of the situation  Smiley

  • User profile image

    Just what I always wanted, a reason for the state police to follow me on twitter. Now if I can just get my phone to automatically tweet my location and velocity...

  • User profile image

    Hi chris,

    Just what I always wanted, a reason for the state police to follow me on twitter. Now if I can just get my phone to automatically tweet my location and velocity...

    You could add a GPS sensor to the tweeting breathalyzer using the serial interface on digital pins 0 and 1 (or send GPS coordinates from your Windows Phone to your Netduino).  You could even log readings to a MicroSD card if you wanted to create a convenient location/velocity/sobriety history.

    [That is of course all in jest--although it could make for a cool remix of this project.]


  • User profile image

    This is an awesome project. I didn't see the usual legal statement about the use of this device for performing actual alcohol sensing of humans.
    This is an example of a great device to solve a social need.

  • User profile image

    I find it an brilliant invention, but the fact that it tweets your alcohol level, it's only designed for those teenagers who still find pride in getting floored. It would make it way cooler if it were just for personal view.

Add Your 2 Cents