- Joined
- Jun 27, 2006
- Messages
- 23,048
- Thread Author
- #1
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 Link Removed is an open source electronics platform based on a 32-bit microcontroller running the .NET Micro Framework. The Link Removed 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.
[h=3]Hardware Overview[/h]
Link Removed
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.
[h=4]RGB LED[/h]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.
[h=4]Alcohol Gas Sensor[/h]Link Removed
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 (V[SUB]C[/SUB] in the above diagram) will ensure that the output voltage (V[SUB]RL[/SUB]) doesn’t exceed the Netduino’s input limits.
The sensor and R[SUB]L[/SUB] act as a voltage divider. The datasheet for this sensor shows that the resistance across the sensor is between 2K-20K ohms, so an R[SUB]L[/SUB] value of 10K ohms will provide a wide voltage output range.
[h=4]Other Components[/h]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.
[h=3]Code[/h]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 Link Removed.
[h=4]Startup[/h]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.
[h=4]RGB LED[/h]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.
[h=4]NTP[/h]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:
NTP.UpdateTimeFromNTPServer(Config.NTPServer);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);[h=4]Measurements[/h]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:
Link Removed
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.
[h=4]Posting to Twitter[/h]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) return; 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"; else message = "x_x"; DateTime adjustedTime = DateTime.Now + new TimeSpan(Config.TimeOffset, 0, 0); message += " at " + adjustedTime.ToString("h:mm:ss tt"); try { twitterClient.SendTweet(message); } catch (Exception e) { Debug.Print(e.ToString()); } greenLED.Write(false); button.ClearInterrupt();}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.
Link Removed
[h=3]Conclusion[/h]The code for this project is included in the Samples folder of the MicroTweet library. Be sure to check out the Link Removed 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.
Link Removed
[h=3]About the Author[/h]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 Link Removed and can be followed on Twitter at Link Removed.
Link Removed
More...
The Link Removed is an open source electronics platform based on a 32-bit microcontroller running the .NET Micro Framework. The Link Removed 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.
[h=3]Hardware Overview[/h]
Link Removed
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.
[h=4]RGB LED[/h]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.
[h=4]Alcohol Gas Sensor[/h]Link Removed
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 (V[SUB]C[/SUB] in the above diagram) will ensure that the output voltage (V[SUB]RL[/SUB]) doesn’t exceed the Netduino’s input limits.
The sensor and R[SUB]L[/SUB] act as a voltage divider. The datasheet for this sensor shows that the resistance across the sensor is between 2K-20K ohms, so an R[SUB]L[/SUB] value of 10K ohms will provide a wide voltage output range.
[h=4]Other Components[/h]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.
[h=3]Code[/h]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 Link Removed.
[h=4]Startup[/h]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.
[h=4]RGB LED[/h]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.
[h=4]NTP[/h]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:
NTP.UpdateTimeFromNTPServer(Config.NTPServer);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);[h=4]Measurements[/h]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:
Link Removed
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.
[h=4]Posting to Twitter[/h]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) return; 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"; else message = "x_x"; DateTime adjustedTime = DateTime.Now + new TimeSpan(Config.TimeOffset, 0, 0); message += " at " + adjustedTime.ToString("h:mm:ss tt"); try { twitterClient.SendTweet(message); } catch (Exception e) { Debug.Print(e.ToString()); } greenLED.Write(false); button.ClearInterrupt();}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.
Link Removed
[h=3]Conclusion[/h]The code for this project is included in the Samples folder of the MicroTweet library. Be sure to check out the Link Removed 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.
Link Removed
[h=3]About the Author[/h]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 Link Removed and can be followed on Twitter at Link Removed.
Link Removed
More...