tag:blogger.com,1999:blog-62384547574218094522024-03-18T13:47:41.449-04:00The Raspberry Pi HobbyistConnecting the Raspberry Pi to the real worldTed B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.comBlogger60125tag:blogger.com,1999:blog-6238454757421809452.post-70825604287247666112016-09-27T17:15:00.001-04:002016-09-27T17:15:42.822-04:00Raspberry Pi vs ArduinoOh My! It has been over 4 months since my last post and some readers may be thinking that I have fallen off the planet. Not quite, but I have been very involved otherwise. Real life is intruding a lot lately and most of my hobby time has been absorbed in supporting the local maker group with teaching robotics to kids.<br />
<br />
The robotics has gotten me very involved using Arduino systems which I had little experience with previously. That got me to thinking that a comparison of Arduino to Raspberry Pi would be good at this point.<br />
<br />
<b>Microcontroller vs General Purpose Computer</b><br />
<br />
This is the big difference in the two. The Pi is a fully fledged general purpose computer capable of performing most of the tasks that a PC performs. It has a complete operating system, much more memory, a storage device, and a monitor and USB devices are supported. The Pi can easily multitask, running several programs at once. It also has excellent networking support, both wired and wireless.<br />
<br />
The Arduino is a microcontroller. It has only a small amount of memory (2K RAM and 32K Flash) and runs a single program. This allows it to provide true real-time response. There is no USB support and adding networking is difficult and very limited. The advantage is that it starts up as soon as power is supplied and won’t be corrupted if power is lost. It also uses far less power and can easily run on batteries. An Arduino will happily run on 7-12 volts while the Pi must have a regulated 5V supply.<br />
<br />
<b>GPIO Capabilities</b><br />
<br />
This is where the Arduino really shines. The Raspberry Pi provides 28 GPIO pins, but only one that provides PWM output and none that provide analog input. The typical Arduino also has 28 GPIO pins, but six of those can provide PWM output and another six can be analog inputs as well.<br />
<br />
The Pi provides RS-232 as well as I2C, SPI, and 1-wire buses. The Arduino supports these as well.<br />
<br />
<b>Form Factors<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh5cpf_cJ0vwDvqaSLzpvTh2hmTJH3pvkZ3TTgceLsPtIjxd1hj-kqWMC23f5TFmUroqU24ZHFSOFaV6lw8OKeZJF1pB1bu-v1F8jUxvrjXX1IWFHh5C9Fu8A4PDGjU6Bk7ZtQnUfikCg/s1600/Image1.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh5cpf_cJ0vwDvqaSLzpvTh2hmTJH3pvkZ3TTgceLsPtIjxd1hj-kqWMC23f5TFmUroqU24ZHFSOFaV6lw8OKeZJF1pB1bu-v1F8jUxvrjXX1IWFHh5C9Fu8A4PDGjU6Bk7ZtQnUfikCg/s320/Image1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Example Arduino Boards</td></tr>
</tbody></table>
</b><br />
<b><br /></b>
If we ignore the original version of the Pi (which I tend to do now) there are only two form factors available – the model 2 and the zero. The Arduino, however, is open-source, and comes in many sizes. The Uno is by far the most common, but my preferred version is the nano. I have also become quite fond of the ESP8226-01 Arduino compatible board. It may only have 2 GPIO pins, but it is extremely cheap, low power, and has built in wifi. I am starting to use it for IoT projects with great success.<br />
<br />
<b>Which to Choose</b><br />
<b><br /></b>
There is a fair amount of overlap in the capabilities of both systems, so many tasks could be performed by either device. However, there are some things that at best done with one or the other.<br />
<br />
If you need:<br />
<br />
<ul>
<li>More than 2KB of RAM</li>
<li>A very large program or multiple programs</li>
<li>A network interface that can handle multiple clients or support more than one protocol</li>
</ul>
Then you should use a Raspberry Pi.<br />
<br />
If you need:<br />
<br />
<ul>
<li>True real-time response to inputs</li>
<li>Analog inputs </li>
<li>PWM output for motors or servos </li>
<li>Extremely low cost solution</li>
<li>Battery powered</li>
</ul>
<br />
Then you should use an Arduino.<br />
<br />
Yes, you can get analog input and PWM output on a raspberry Pi, but it requires additional hardware, which adds to the cost and complexity.<br />
<br />
Sometimes you need the best of both worlds and will use a Pi and and Arduino. I have done this on one commercial project already and it worked very well.<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com5tag:blogger.com,1999:blog-6238454757421809452.post-2720793362034049782016-05-06T09:29:00.000-04:002016-05-06T09:29:18.445-04:00Kano Kit I recently received a Raspberry Pi 3 kit from Kano (<a href="http://kano.me/">kano.me</a>) and thought I should give it a review.<br />
The kit includes:<br />
<div class="MsoNormal">
● Raspberry Pi model 3</div>
● 8GB microSD card preloaded with Kano OS, projects and games<br />
<div>
● Wireless keyboard with touchpad</div>
<div>
● Case with built-in speaker and LEDs</div>
<div>
● HDMI cable </div>
<div>
● Power supply and cable</div>
<div>
● Wifi adapter</div>
<div>
● Illustrated user guide with stencils and stickers</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinlrXG4JqQkwwCo0igqQ8Rk9etRfudqOGB3mKosnYYKoVvIRMMMO03zusrZz9EaL01WTTnVfcrQP967oyAz_3DOF58xPeLYzAMW-5IRoWamqCDH10ZZgjvf9JxPE3BVdV8xQVd785ydz4/s1600/DSC_0069.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinlrXG4JqQkwwCo0igqQ8Rk9etRfudqOGB3mKosnYYKoVvIRMMMO03zusrZz9EaL01WTTnVfcrQP967oyAz_3DOF58xPeLYzAMW-5IRoWamqCDH10ZZgjvf9JxPE3BVdV8xQVd785ydz4/s320/DSC_0069.JPG" width="320" /></a></div>
<span id="goog_668831749"></span><span id="goog_668831750"></span><br />
<br />
The cost is $150 and as you would expect for that price, the quality is very good. I especially like the keyboard. Since this was a v3 Pi, the Wifi adapter was redundant, but that's OK - it will get used on another system. The documentation provides a detailed and illustrated, step by step guide to setting up the system, It is suitable for a very young user and that is obviously the target audience for this kit.<br />
<br />
The cover to the case has a small speaker that doesn't appear to be amplified. There are, however, a couple of PCA9685 chips that are connected to the I2C bus and allow control of the LEDs using PWM. I will create some code to experiment with these and see what they're capable of. It would be really nice if the LEDs were RGB, but they appear to be simple blue LEDs.</div>
Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com0tag:blogger.com,1999:blog-6238454757421809452.post-47373769378879144282016-02-29T21:26:00.002-05:002016-02-29T21:28:52.861-05:00Hot Tub Controller Details<span style="font-family: "arial" , "helvetica" , sans-serif;"><b>By popular demand - some more details about my Hot Tub Controller project.</b></span><br />
<br />
See <a href="http://raspberrypihobbyist.blogspot.com/2016/02/improved-hot-tub-controller.html">the post about my Hot Tub Controller.</a><br />
<br />
<b>Controller Source Code</b><br />
Can be found on github - <a href="https://github.com/tedhale/hottub.git">https://github.com/tedhale/hottub.git</a><br />
You can pull it from this address using the git command, or just go to this address and click the "Download Zip" button.<br />
<br />
[Add web interface source files]<br />
<br />
<br />
<b>Partial parts list:</b><br />
<span style="font-size: x-small;">I will update this as I dig up the details for more of the parts I used.</span><br />
<br />
Waterproof Case with clear cover - <a href="https://www.adafruit.com/products/905" target="_blank">https://www.adafruit.com/products/905</a><br />
<br />
7-Segment LCD (I2C bus) - <a href="https://www.adafruit.com/products/761" target="_blank">https://www.adafruit.com/products/761</a><br />
There are many colors and a couple sizes<br />
<br />
Pushbuttons - <a href="https://www.adafruit.com/products/481" target="_blank">https://www.adafruit.com/products/481</a><br />
Several colors available. They don't call these weatherproof but they seem to be pretty weather tolerant.<br />
<br />
30A Relay (5V control) - <a href="http://www.mouser.com/Search/ProductDetail.aspx?R=JTN1AS-TMP-F-DC5V" target="_blank">http://www.mouser.com/Search/ProductDetail.aspx?R=JTN1AS-TMP-F-DC5V</a><br />
<br />
10A Relay (5V control) - <a href="http://www.mouser.com/Search/ProductDetail.aspx?R=G5CA-1A-TP-E_DC5" target="_blank">http://www.mouser.com/Search/ProductDetail.aspx?R=G5CA-1A-TP-E_DC5</a><br />
<br />
Waterproof Enclosure - <a href="http://www.mouser.com/Search/ProductDetail.aspx?R=1554E2GY" target="_blank">http://www.mouser.com/Search/ProductDetail.aspx?R=1554E2GY</a><br />
for relays inside hot tub<br />
<br />
Cable Gland (for running cable into waterproof box) - <a href="https://www.adafruit.com/products/761" target="_blank">https://www.adafruit.com/products/761</a><br />
<br />
2n2222 transistors<br />
<br />
Terminal Blocks<br />
<br />
Perf board<br />
<br />
40 pin GPIO connector - <a href="https://www.adafruit.com/products/1979" target="_blank">https://www.adafruit.com/products/1979</a><br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com5tag:blogger.com,1999:blog-6238454757421809452.post-65325909459688103152016-02-29T11:02:00.002-05:002016-02-29T11:02:27.809-05:00The Raspberry Pi version 3 is now AvailableThe latest version of the Pi is out and as expected, it has a faster CPU. Version 2 had a 900MHz Cortex-A7 chip. Version 3 has a 1.2GHz Cortex-A53. Still quad core and a little faster, but the big difference is that the A53 is a 64-bit processor where the A7 was 32-bit. We will have to wait for an OS upgrade to take advantage of that, but I doubt having 64-bit will make much difference for most applications.<br />
<br />
The really great upgrade is that version 3 has built in wifi (802.11n) and Bluetooth.<br />
<br />
I should be receiving one shortly and will let you know what I do with it.<br />
<br />
Here is some information provided by RS-Components, a great source for all things Pi.<br />
<h2>
How to set up your Raspberry Pi 3</h2>
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/rLAblELXygA" width="560">
</iframe>
<br />
<h2>
Comparison of Raspberry Pi 3 and the Raspberry Pi 2 </h2>
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/45Mls8BCgtE" width="560">
</iframe>
Fancy another slice of pi? <a href="http://uk.rs-online.com/web/generalDisplay.html?id=raspberrypi">Find out more about the Raspberry Pi 3</a>Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com0tag:blogger.com,1999:blog-6238454757421809452.post-63241664843725388742016-02-02T09:09:00.003-05:002016-02-02T09:09:46.750-05:00Improved Hot Tub Controller<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzlGdEgVvfDnjLPcdebmwDc7vBKug3a9x7ZmU_4Xv4FpRA9nAmyfbSaPoB41VyYjpV20wxlm6ucKefmiv_M1CV0xEbi3kWFDpxudIKwsAzJdaiDdX4f7x1R1lRdGqo4aXb2lAQEFLtn4s/s1600/HotTubController.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzlGdEgVvfDnjLPcdebmwDc7vBKug3a9x7ZmU_4Xv4FpRA9nAmyfbSaPoB41VyYjpV20wxlm6ucKefmiv_M1CV0xEbi3kWFDpxudIKwsAzJdaiDdX4f7x1R1lRdGqo4aXb2lAQEFLtn4s/s200/HotTubController.jpg" width="165" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Hot Tub Controller Circuit Board</td></tr>
</tbody></table>
The original version of my hot tub controller starting having some problems which ended up being caused by an animal chewing through the control cables. I never liked having that huge bundle of cables running all the way across the back of the house, so I now have a new controller in a waterproof enclosure mounted right next to the hot tub.<br />
<br />
The controller is built to mount on top of a Raspberry Pi and does the following:<br />
<div class="MsoNormal">
● Monitor the water temperature</div>
<div class="MsoNormal">
● Turn a circulation pump and heater on to heat the water as needed</div>
<div class="MsoNormal">
● Respond to buttons that increase/decrease the desired temperature</div>
<div class="MsoNormal">
● Respond to buttons that turn the water jets on and off</div>
<div class="MsoNormal">
● Display the current temperature<br />
● Detect various failure modes and place system in safe mode<br />
● Listen for commands from a smart phone app to control hot tub</div>
<div class="MsoNormal">
● Upload data periodically to an Internet of Things service</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Temperature monitoring is performed by a <a href="https://www.adafruit.com/products/381" target="_blank">waterproof DS18B20 from Adafruit</a>. It uses a simple 1-wire bus to read the data.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The display, <a href="https://www.adafruit.com/products/881" target="_blank">also from Adafruit</a>, is a 7-segment LED display and is controlled using an I2C bus.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The device is powered by a 24V DC power supply since the relays on the hot tub are controlled by a 24V signal. A 5V step down regulator provides power to the Raspberry Pi.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX7ApnUbFQi6gC5YDVevmOJ1Grpccm_N1dJF_jJwBGI6XWjKmqteeuoam09cWAYsDLXqNK2NvBw_lH0DrPHFJN7ijMtED7RiPBE0axbJiLpj0VT2P1yaDREfHlRzuhXYEO4HuVcwvPKOY/s1600/RelayControl.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="124" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX7ApnUbFQi6gC5YDVevmOJ1Grpccm_N1dJF_jJwBGI6XWjKmqteeuoam09cWAYsDLXqNK2NvBw_lH0DrPHFJN7ijMtED7RiPBE0axbJiLpj0VT2P1yaDREfHlRzuhXYEO4HuVcwvPKOY/s200/RelayControl.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Relay Control with LED Indicator</td></tr>
</tbody></table>
Transistors are used to control the relays and screw terminals provide the connections for all the wires.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The push buttons are connected to GPIO inputs which drive interrupts. These require "debounce" conditioning and this is explained in <a href="http://raspberrypihobbyist.blogspot.com/2014/11/debouncing-gpio-input.html" target="_blank">this post.</a></div>
<div class="MsoNormal">
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjK0kr9CdpXwLIotOS5Cfx_a7g1OoaMy320pLbwvsu8OPV8HDWbnAsuyiyU4AIqPr_Nr-BviI5tDkabc_FTgAVNyknuxAj9IaTU0lzIKvArsQyItUxeWezcukNm7s5_lRmJnSCfTnkwKcQ/s1600/HotTubApp.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjK0kr9CdpXwLIotOS5Cfx_a7g1OoaMy320pLbwvsu8OPV8HDWbnAsuyiyU4AIqPr_Nr-BviI5tDkabc_FTgAVNyknuxAj9IaTU0lzIKvArsQyItUxeWezcukNm7s5_lRmJnSCfTnkwKcQ/s320/HotTubApp.jpg" width="169" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Smart Phone app for Hot Tub</td></tr>
</tbody></table>
<br />
<br /></div>
<div class="MsoNormal">
The Internet of Things support is using ThingSpeak and the method is described in <a href="http://raspberrypihobbyist.blogspot.com/2015/11/thingspeak-api-for-internet-of-things.html" target="_blank">this post</a>. You can see the <a href="https://thingspeak.com/channels/65731" target="_blank">live data at this URL</a>.</div>
<div class="MsoNormal">
<br />
<br />
The system also listens on a network socket for incoming commands from a smart phone app that allows me to monitor and control the hot tub remotely. It's actually not an app, rather just a web page designed for a mobile screen. This way it can easily be used by my Android, my wife or son's iPhone, or from any web browser.<br />
<br /></div>
<div class="MsoNormal">
Here is a video showing the completed controller in action. </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/LOwnG5Vhzcs/0.jpg" src="https://www.youtube.com/embed/LOwnG5Vhzcs?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<div class="MsoNormal">
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<div class="MsoNormal" style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
</div>
<br />
<div class="MsoNormal" style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<div style="margin: 0px;">
And, yes, I really do keep my hot tub that hot. One advantage of making my own controller is that I am not limited to 104 degrees max.</div>
</div>
</div>
Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com30tag:blogger.com,1999:blog-6238454757421809452.post-88701725790544594322015-11-20T10:25:00.000-05:002015-11-20T10:25:37.325-05:00ThingSpeak API for Internet of Things There is much hype about the <a href="https://en.wikipedia.org/wiki/Internet_of_Things" target="_blank">"Internet of Things"</a> and the Raspberry Pi is increasingly used as an IoT controller. To describe it simply - if you have a web site accessible from anywhere that displays data from a device and/or allows control of that device - then you are part of the Internet of Things.<br />
<br />
I have a smart thermostat that allows me to control my heating and cooling system remotely from a smart phone app. This is one of the most commonly used IoT devices. I also have created web interfaces to some of the Raspberry Pi controlled devices in my home - alarm system, lights, sprinklers, hot tub, weather station, security cameras.<br />
<br />
I programmed these web interfaces myself, but there are much easier ways that are actually more secure, and these use the services that support the Internet of Things. One of the easiest to use is <a href="https://thingspeak.com/" target="_blank">ThingSpeak.com</a>. Here are the steps to use this service.<br />
<br />
Go to the ThingSpeak web site and click on "Get Started." Click on "Sign Up" to create an account and then log in. Now you can create a new "Channel" which includes 1 to 8 fields of data. Once created, the channel is assigned an API_Key which is required to update the channel. You can see this value by clicking on the "API Keys" tab.<br />
<br />
I have created a channel named "Example" with a single data field. Data can be uploaded to this field by using the following URL:<br />
<br />
https://api.thingspeak.com/update?api_key=JPISWIDBF2CERG24&field1=123<br />
<br />
(Yes, that is the actual API key. Feel free to post your own values, but try to keep them between 1-1000 so the chart is usable.)<br />
<br />
You can view the public view here: <a href="https://thingspeak.com/channels/67033" target="_blank">https://thingspeak.com/channels/67033</a><br />
<br />
Note that you can only update once per minute using this method.<br />
<br />
Examples in a couple dozen languages, including C and Python are available here:<br />
<a href="https://thingspeak.com/docs/examples" target="_blank">https://thingspeak.com/docs/examples</a><br />
<br />
Here is an example of real data - temperature and fermentation rate from my home-brewing system.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5_ZuKW6G9oU-sLRPLfrmceOFs2l5kAjQJ1mxXjbt4YXlFs6V78UNCAnxRFJO7APFsqQYj7K1aio3c4ivEe4C6hyphenhyphenDLbV4OHGwkxnJ1Ja14U0tdi78sr4qNycFRHuGMb082zMLdUhy3-24/s1600/ThingSpeak2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5_ZuKW6G9oU-sLRPLfrmceOFs2l5kAjQJ1mxXjbt4YXlFs6V78UNCAnxRFJO7APFsqQYj7K1aio3c4ivEe4C6hyphenhyphenDLbV4OHGwkxnJ1Ja14U0tdi78sr4qNycFRHuGMb082zMLdUhy3-24/s320/ThingSpeak2.gif" width="320" /></a></div>
<br />
<br />
I decided to create my own API since I had all the necessary code already. This API requires the CURL library to handle the web access. To install this:<br />
<span style="font-family: "courier new" , "courier" , monospace;">sudo apt-get update</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">sudo apt-get install libcurl4-openssl-dev</span><br />
<br />
Here is the API that I created for updating two fields.<br />
<pre class="brush: csharp">/***********************************************************************
Filename: thingspeak.c
send data to ThingSpeak IoT server
Uses libcurl to send the data via HTTP
13-Nov-2015 Ted Hale created
************************************************************************/
/* system includes */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <string.h>
#include <curl/curl.h>
// Note: this function can be replaced with printf if you like.
void Log(char *format, ... );
#define TRUE 1
// the URL structure to update ThingSpeak
// https://api.thingspeak.com/update?api_key=YOUR_CHANNEL_API_KEY&field1=7
char *URLtemplate = "https://api.thingspeak.com/update?api_key=%s&%s=%s&%s=%s";
// structure used by the libcurl write callback function
struct url_data {
size_t size;
char* data;
};
//=====================================================================
// write callback function needed by libCurl
size_t write_data(void *ptr, size_t size, size_t nmemb, struct url_data *data) {
size_t index = data->size;
size_t n = (size * nmemb);
char* tmp;
data->size += (size * nmemb);
tmp = realloc(data->data, data->size + 1); /* +1 for '\0' */
if(tmp) {
data->data = tmp;
} else {
if(data->data) {
free(data->data);
}
Log("wuthread> write_data Failed to allocate memory.\n");
return 0;
}
memcpy((data->data + index), ptr, n);
data->data[data->size] = '\0';
return size * nmemb;
}
//=====================================================================
// upload data to ThingSpeak
int UpdateThingSpeak(char *api_key, char *f1, char *v1, char *f2, char *v2)
{
int error = 1;
time_t now;
struct tm *dt;
char url[256];
CURL *curl;
CURLcode res;
struct url_data response;
time(&now);
dt = gmtime(&now);
// build the URL string
snprintf(url, sizeof(url)-1, URLtemplate, api_key, f1, v1, f2, v2);
// guarantee null termination of string
url[sizeof(url)-1] = 0;
Log("UpdateThingSpeak> send: [%s]",url);
curl = curl_easy_init();
if (curl) {
response.size = 0;
response.data = malloc(4096); /* reasonable size initial buffer */
response.data[0] = '\0';
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
Log("UpdateThingSpeak> curl_easy_perform() failed: %s\n",curl_easy_strerror(res));
Log("URL is: [%s]",url);
error = 1;
} else {
// ThingSpeak returns "0" for error, else returns sample number
error = (strcmp(response.data,"0") == 0);
}
curl_easy_cleanup(curl);
free (response.data);
} else {
Log("UpdateThingSpeak> curl_easy_init failed\n");
error = 1;
}
return error;
}
</pre>
Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com12tag:blogger.com,1999:blog-6238454757421809452.post-35308675258554168812015-11-11T11:19:00.000-05:002015-11-11T11:19:51.335-05:00Improved Alarm/Automation System<h3>
<span style="font-family: inherit;">A Little History</span></h3>
<span style="font-family: inherit;">I have been fascinated (some would say obsessed) with home automation for many years. I even had a paper published on the subject in 1978, so I experimented with many options before the Raspberry Pi came along. My first working system was based on an Atari 400. I then went through several versions based on microprocessors (like an Arduino, but much older and more primitive) but was never happy with their limitations. Eventually I was able to obtain an old PC and use parallel printer ports for digital I/O. I experimented with Linux and Windows versions and found Linux to be much better suited for what is essentially an embedded system.</span><br />
<span style="font-family: inherit;"><br /></span>
<h3>
<span style="font-family: inherit;">The Pi Comes Along</span></h3>
<span style="font-family: inherit;">Of course, the first project that I took on when I started working with the Raspberry Pi was a replacement for my PC based home alarm and automation system. The requirements were straight-forward:</span><br />
<span style="font-family: inherit;"> <span style="font-size: 11pt;">● several inputs for motion detectors and door/window sensors</span></span><br />
<span style="font-family: inherit;"><span style="font-size: 11pt;"> </span><span style="font-size: 11pt;">● several relay outputs for control of </span><span style="font-size: 14.6667px;">miscellaneous</span><span style="font-size: 11pt;"> devices </span></span><br />
<span style="font-family: inherit;"><span style="font-size: 11pt;"> </span><span style="font-size: 11pt;">● serial (RS-232) port for connecting to an <a href="https://en.wikipedia.org/wiki/X10_(industry_standard)" target="_blank">X10</a> interface</span></span><br />
<span style="font-family: inherit;"><span style="font-size: 11pt;"> </span><span style="font-size: 11pt;">● socket interface for control from other computers</span></span><br />
<span style="font-size: 11pt;"> </span><span style="font-size: 11pt;">● logic to provide some limited intelligence</span><br />
<span style="font-size: 11pt;"><span style="font-family: inherit;">I describe this first version in a series of my early blog posts. Look at Sept. and Oct. 2012 to see these.</span></span><br />
<span style="font-size: 11pt;"><span style="font-family: inherit;"><br /></span></span>
<h3>
<span style="font-size: 11pt;"><span style="font-family: inherit;">Time for an Update</span></span></h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_JCj0-QXlCknrCfsNbiyybCCq50CRCzjeqjUOqg7x8452ShkpkWofytNmSLttXbFcNevzxHhe9p4Dcp7lax14iQrAnBEA4FKawkeiKydjqBM1min9MQse5VP5MXYk7XolBW-6CgumuiQ/s1600/DSC_0002.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_JCj0-QXlCknrCfsNbiyybCCq50CRCzjeqjUOqg7x8452ShkpkWofytNmSLttXbFcNevzxHhe9p4Dcp7lax14iQrAnBEA4FKawkeiKydjqBM1min9MQse5VP5MXYk7XolBW-6CgumuiQ/s320/DSC_0002.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Updated Alarm/Automation System</td></tr>
</tbody></table>
<span style="font-family: inherit;"><span style="font-size: 11pt;">In the several years that I have worked with the Raspberry Pi I have learned a lot about the best way to do some things and applied these lessons to my updated alarm/automation system. I think the most important lesson that I learned was to make things as modular as possible. It is inevitable that I will screw up something and if the project is one large circuit board, then I may well have to scrap it and start over. However, if I break that into several smaller boards, then a </span></span><span style="font-size: 14.6667px;">screw-up will, at most, cause the rebuild of a single small circuit. Some systems fit this designs method very well while some just can not be broken up. The alarm/automation system fits this method well and consists of the following parts:</span><br />
<span style="font-family: inherit;"><span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● Raspberry Pi (of course)</span></span><br />
<span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● Simple "hat" for the Pi to expose all the buses needed</span><br />
<span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● a relay board (bought, not built)</span><br />
<span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● control board for the relay</span><br />
<span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● control board for digital inputs</span><br />
<span style="font-size: 11pt;">Each of these is described below.</span><br />
<span style="font-size: 11pt;"><br /></span>
<span style="font-size: 11pt;"><br /></span>
<h3>
<span style="font-size: 11pt;">The "Bus Hat"</span></h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfB0NJaRgiK_mIfsJdHrx1xeFKJwiPwY4FJwllYyE2j2NQG-8ZALgnKzNgBxu9_f9cZd-B4O4SJZQk0iUEg5Q8u99iM044srcPWTC5D0_z51bKjhEnZIKbrJP6eBSETs7EwS8sLUJO0H4/s1600/bushat.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfB0NJaRgiK_mIfsJdHrx1xeFKJwiPwY4FJwllYyE2j2NQG-8ZALgnKzNgBxu9_f9cZd-B4O4SJZQk0iUEg5Q8u99iM044srcPWTC5D0_z51bKjhEnZIKbrJP6eBSETs7EwS8sLUJO0H4/s200/bushat.png" width="190" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The Bus Hat</td></tr>
</tbody></table>
<span style="font-size: 11pt;">In order to connect the various pieces to the Pi, I needed a way to access some of the buses available. I created what I call a "bus hat" to do this. This mounts on top of the Pi and provides access to the following:</span><br />
<span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● the I2C bus</span><br />
<span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● the SPI bus</span><br />
<span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● the 1-Wire bus</span><br />
<span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● RS-232 converted to proper levels</span><br />
<span style="font-size: 14.6667px;"> </span><span style="font-size: 11pt;">● 5V input to power it all</span><br />
<span style="font-size: 11pt;">I knew that I would be using 3.3V devices, so I did not include any level converters on the I2C or SPI buses. I did need proper voltage levels for the RS-232 serial line and that was provided by a MAX3232 chip. </span><br />
<span style="font-size: 11pt;"></span><br /><span style="font-size: 11pt;"></span>
<span style="font-size: 11pt;">This is a very simple device since all it really does is connect specific GPIO pins to connectors for the required buses.</span><br />
<br /><span style="font-size: 11pt;"></span>
<span style="font-size: 11pt;"></span><br />
<span style="font-size: 11pt;"></span><br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4DaPgYp9r04XT-6SBCsDRpb_wroTqsrbq7mVowsP-Y0TuTVLct5-o07euwEp1b17VncEugyeE8hHsT9eXtF65btLJmjCioT5-PpHR8m34a0DV2tdxRBRJvQgrujfPuIbr625UA_YMgWI/s1600/bushatDesign.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4DaPgYp9r04XT-6SBCsDRpb_wroTqsrbq7mVowsP-Y0TuTVLct5-o07euwEp1b17VncEugyeE8hHsT9eXtF65btLJmjCioT5-PpHR8m34a0DV2tdxRBRJvQgrujfPuIbr625UA_YMgWI/s200/bushatDesign.png" width="158" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bus Hat Circuit Design</td></tr>
</tbody></table>
<span style="font-size: 11pt;">My design for this bus hat is shown here. You may notice that this is a little different than most circuit diagrams you will see. I am a little </span><span style="font-size: 14.6667px;">embarrassed</span><span style="font-size: 11pt;"> to admit that I use Power Point to create these drawings. I am mostly concerned with how the components will be laid out on the perf board, so I make a perf board grid the background image and place the components onto that and add the wiring. Power Point makes this quick and easy. If you need to make a simple and better looking wiring diagram I recommend the Fritzing app. For real PCB drawings I have used Eagle and PCB Artist.</span><br />
<span style="font-size: 11pt;"><br /></span>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: left; float: left; margin-bottom: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO9Ias5gQq3utOlNpCVW-8ZRHplM6aB1RWhK7hNagXYuWHESwFBgkrQN1JM_Xt1zJxDYKlSQzJq3yeBzb04qd_qFlm0gOy879HSfftWm92jl9cESiW6QNhJKs9xe7QKW6ogT9PWoO3cGk/s1600/51MEeE5SqlL.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO9Ias5gQq3utOlNpCVW-8ZRHplM6aB1RWhK7hNagXYuWHESwFBgkrQN1JM_Xt1zJxDYKlSQzJq3yeBzb04qd_qFlm0gOy879HSfftWm92jl9cESiW6QNhJKs9xe7QKW6ogT9PWoO3cGk/s200/51MEeE5SqlL.png" width="115" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Relay Board</td></tr>
</tbody></table>
<span style="font-size: 11pt;"></span><br /><span style="font-size: 11pt;"></span>
<h3>
<span style="font-size: 11pt;">Relay Board</span></h3>
<span style="font-size: 14.6667px;">I decided to buy a relay board online. There are quite a few of these available and the price is hard to beat. You should be able to find an 8 channel board like this for well under $10. There is no way I could even buy the components for that cheap.</span><br />
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;"><br /></span>
<h3>
<span style="font-size: 11pt;">Relay Control<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLgN-GKF-u1gzprtKFXa8X6uyhr9WObGoGBIsOT4WsHH9sGzdAOvqCjBUgbAlE-6NsmtPsWNBbGKdIKGMEnDm9R1-C06JdHsN02rTNFFunTdfpENg_Rz1e0skmZhLzG1HNo97jTB6ys9g/s1600/RelayInterface.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLgN-GKF-u1gzprtKFXa8X6uyhr9WObGoGBIsOT4WsHH9sGzdAOvqCjBUgbAlE-6NsmtPsWNBbGKdIKGMEnDm9R1-C06JdHsN02rTNFFunTdfpENg_Rz1e0skmZhLzG1HNo97jTB6ys9g/s200/RelayInterface.png" width="188" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Relay Control Circuit</td></tr>
</tbody></table>
</span></h3>
<span style="font-size: 11pt;">To control the relays I needed 8 GPIO lines. The perfect job for the MCP23008 GPIO extender. This chip connects via I2C (there is also an SPI version) and provides 8 GPIO lines. I set them all as output and connect one to each relay control pin. One thing to be aware of - these relays require more power to operate than the Pi can generally provide. They will appear to work at first but then you try to turn on all 8 relays and the Pi will reboot due to the drop in power. The relay board will provide a pin for connecting external power to prevent this from happening. Since I was using 3.3V on the I2C bus, I added a 5V input to the relay controller to provide this power.</span><br />
<span style="font-size: 11pt;"><br /></span>
<h3>
<span style="font-size: 11pt;">Input Board</span></h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKUeIrTifAf7Pzv_N6Pi8w9-a6T1d8Li9YtPmhZfO-ZC9YUGipuw2M9fjysgDQYeAF7pd18pSsW4jkpsqenYZy0v1MeRY3UVRre-9QW3qP9VBl0ADApWuIEo2e3lS_AEZrxaY6MdRURa4/s1600/InputModule.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKUeIrTifAf7Pzv_N6Pi8w9-a6T1d8Li9YtPmhZfO-ZC9YUGipuw2M9fjysgDQYeAF7pd18pSsW4jkpsqenYZy0v1MeRY3UVRre-9QW3qP9VBl0ADApWuIEo2e3lS_AEZrxaY6MdRURa4/s200/InputModule.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Input Board Circuit</td></tr>
</tbody></table>
<span style="font-size: 14.6667px;">The input board provides 16 "contact closure" inputs. In other words, a switch of some kind connects two pins. This is typical of the way that motion detectors and door switches work. The input board has the GPIO pins pulled high and the external device will close a switch to connect the pin to ground.</span><br />
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;">The circuit uses an opto-isolator (sometimes called an opto-coupler) to provide protection to the GPIO pins. This is prudent since the inputs are connected to wires that run all over my house and anything could happen to put bad voltage onto those lines. I even went as far as having the opto-isolators in sockets so they could easily be replaced if they are blown. That's probably excessive, but it was easy enough to include, so I did.</span><br />
<span style="font-size: 14.6667px;"></span><br /><span style="font-size: 14.6667px;"></span>
<span style="font-size: 14.6667px;">Again, I used a GPIO extender. This time a MCP23017, which provides 16 GPIO pins with an I2C bus connection. Both of the extender chips I used will default to I2C bus address 0x20, so I set the address pins on this one so that it will appear on the bus at address 0x21. Note that A0 is tied high while A1 and A2 are tied low.</span><br />
<span style="font-size: 14.6667px;"><br /></span>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH1s-c9C63uBAQaubbb8uAIu5c0AQ2_pz0Ye5hVCdf9XIij8pnv9ShPc1hfq-kQ3W3pBHGOn62ALyJnIo-iPcupV3pvgwVoAjTTBwxqyBEkvDaeKtxlO0YFmL-h4rSsX7cmQEyZdp93j0/s1600/%2524_35.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH1s-c9C63uBAQaubbb8uAIu5c0AQ2_pz0Ye5hVCdf9XIij8pnv9ShPc1hfq-kQ3W3pBHGOn62ALyJnIo-iPcupV3pvgwVoAjTTBwxqyBEkvDaeKtxlO0YFmL-h4rSsX7cmQEyZdp93j0/s200/%2524_35.JPG" width="192" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">X10 Interface</td></tr>
</tbody></table>
<h3>
<span style="font-size: 14.6667px;">X10 Interface</span></h3>
<div>
<span style="font-size: 14.6667px;"><br /></span></div>
<span style="font-size: 14.6667px;">I control the X10 devices using a CM11A interface from ActiveHome. These haven't been made for a while now, but are still available on eBay. It connects via a serial port. NOTE: I had to swap send and receive from the original design of the Bus Hat to connect directly to the CM11A.</span><br />
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;">I have several X10 controllers for lighting as well as several wireless motion detectors that connect to X10 through a bridge device. These are convenient since they don't require running wires. The downside is that they use batteries. Fortunately, they are fairly efficient and only require replacing a few times a year.</span><br />
<span style="font-size: 14.6667px;"><br /></span>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzvw4_Er75thUc170_3ZmJJvYjDHPtMAMRGPOrGxzuQodTTgY4rs2uCCNYFkilxTbaPk9uCU3tXe70idvlEqsUl352BG6PWT8ZPxdARtocyiGVqa1gZhyphenhyphenREdaQjffBwgSVTSNBfFSwRQw/s1600/DSC_0004.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzvw4_Er75thUc170_3ZmJJvYjDHPtMAMRGPOrGxzuQodTTgY4rs2uCCNYFkilxTbaPk9uCU3tXe70idvlEqsUl352BG6PWT8ZPxdARtocyiGVqa1gZhyphenhyphenREdaQjffBwgSVTSNBfFSwRQw/s200/DSC_0004.png" width="108" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Smart Phone Interface</td></tr>
</tbody></table>
<h3>
<span style="font-size: 14.6667px;">Smart Phone User Interface</span></h3>
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;">What home automation system would be complete without a smart phone app? A web interface is much more universally usable, so I went that route rather than writing a phone app. Besides, I'm an Android guy, but my other half uses an iPhone. I had no desire to go down that rabbit hole.</span><br />
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;">The web interface was created using Apache, PHP, and the socket interface to the alarm/automation system. The details on that will have to be a post of its own.</span><br />
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;"><br /></span>
<span style="font-size: 14.6667px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com6tag:blogger.com,1999:blog-6238454757421809452.post-25531276140765071732015-11-05T16:58:00.003-05:002015-11-09T10:57:31.107-05:00HDC100x Temperature/Humidity SensorHumidity is notoriously difficult to measure accurately. And now I have found that humidity sensors are very fickle. I had been using the <a href="https://www.adafruit.com/products/1293" target="_blank">AM2315</a> sensor, which Adafruit clearly states is not weatherproof. I can attest that it is definitely not. It worked OK for a few months, although it did have a problem when it rained. After rain, it would show 100% humidity for a few days until it dried out. Finally a couple of months ago, it died completely.<br />
<div>
<br />
<div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUcnJwqbNaP-WOOaLhyAyP7cyrDefafAjGibc4njiHvygF1_yx0DP9H9gfFJGomgaflAylpWXgyYorz_rKVLm6uy0mucbE_iqYFmMb9Fyh0LxwQMlqslAgpUM0QJfWeCvgEp44lLupRCk/s1600/2635-00.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUcnJwqbNaP-WOOaLhyAyP7cyrDefafAjGibc4njiHvygF1_yx0DP9H9gfFJGomgaflAylpWXgyYorz_rKVLm6uy0mucbE_iqYFmMb9Fyh0LxwQMlqslAgpUM0QJfWeCvgEp44lLupRCk/s200/2635-00.jpg" width="200" /></a>I have now installed an <a href="https://www.adafruit.com/products/2635" target="_blank">HDC1008</a> sensor. This device uses an I2C interface and has a very simple protocol. There is some sample code below.</div>
<div>
To get a reliable temperature reading from any sensor it should be placed in a shroud that provides shade and good ventilation. I mounted the HDC1008 inside the shroud from my old weather system. This will protect it from the weather and prevent a spike in temperature reading when the sun hits it.</div>
<div>
<br /></div>
<div>
<br />
<h3>
Accuracy Issues</h3>
The image below shows a plot of temperature for an entire day. The HDC1008 is the top line and the bottom line is a DS18B20 one-wire temperature sensor.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRcyDlT_PeZkDEep1JzCoO3U0PZliMV7clPsJiM5U9bLEAp936iWpOprJNkKQKfm-XEEZd-nECWu3Xlps0_w-HVOIaNVaZ8ZNu0lfrZduhFDIJ3_UyUlaXlTC2RG0z2RMoScVfY7DYcsE/s1600/TempPlot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRcyDlT_PeZkDEep1JzCoO3U0PZliMV7clPsJiM5U9bLEAp936iWpOprJNkKQKfm-XEEZd-nECWu3Xlps0_w-HVOIaNVaZ8ZNu0lfrZduhFDIJ3_UyUlaXlTC2RG0z2RMoScVfY7DYcsE/s640/TempPlot.png" width="640" /></a></div>
<br />
There are two things easily noticeable - First, there is a two degree difference in the sensors. I placed my laboratory thermometer next to these sensors for several minutes to get an accurate reading of the true temperature. It was exactly in between the two sensors, so one is one degree low and the other is one degree high. The DS18B20 specifications say it has an accuracy of ±0.5°C which is 0.9°F, so this reading is only a little outside its claimed accuracy. The HDC1008 claims an accuracy of ±0.2°C which is 0.36°F, but mine shows a difference of 0.9°F.<br />
<br />
The second thing to notice in the plot below is how wavy the top line is. The reading from the HDC1008 often fluctuate by a degree or more in a very short period. My software takes twenty readings per minute and averages them. This data is recorded each minute. This averaging does not smooth out the plot so I have to conclude that the readings from the HDC1008 really are changing like the plot shows.<br />
<br />
<h3>
Conclusions</h3>
Neither of the sensors discussed are going to provide laboratory level accuracy, but I wouldn't expect that from a low cost device. Both are fine for typical home weather monitoring. I use the DS18B20 on several other devices and prefer it because it is very low cost and very simple to use.<br />
<br />
I have no way to measure the accuracy of the humidity readings from the HDC1008, but they seem to correlate well with nearby weather stations. My overall impression of the device is positive and I find it considerably better than the AM2315 that it replaced.</div>
<div>
<br />
<h3>
Code</h3>
Below is sample code that I used to initially test the device. This was adapted from the library for arduino provided by Ladyada. Many thanks to her and the other folks at Adafruit. </div>
<div>
<br /></div>
</div>
<pre class="brush: csharp">/***************************************************
sample code for the HDC1000 Humidity & Temp Sensor
by ted.b.hale@gmail.com
2015-08-28
adapted from Adafruit_HDC1000 library, license follows:
Designed specifically to work with the HDC1000 sensor from Adafruit
----> https://www.adafruit.com/products/2635
These sensors use I2C to communicate, 2 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#define HDC1000_I2CADDR 0x40
#define HDC1000_TEMP 0x00
#define HDC1000_HUMID 0x01
#define HDC1000_CONFIG_MODE (1 << 12)
#define HDC1000_CONFIG_RST (1 << 15)
#define HDC1000_CONFIG_TRES_14 0
#define HDC1000_CONFIG_HRES_14 0
#define HDC1000_MANUFID 0xFE
#define HDC1000_DEVICEID 0xFF
uint16_t i2c_read16(int fd, uint8_t outbyte)
{
uint16_t retval;
write(fd, &outbyte, 1);
delay(50);
read(fd, &retval, 2);
return ntohs(retval);
}
uint32_t i2c_read32(int fd, uint8_t outbyte)
{
uint32_t retval;
write(fd, &outbyte, 1);
delay(50);
read(fd, &retval, 4);
return ntohl(retval);
}
int HDC1000_Init(uint8_t addr)
{
uint32_t x;
int fd = wiringPiI2CSetup(addr);
if (fd==-1)
{
printf("wiringPiI2CSetup for hdc1000 failed\n");
return -1;
}
// reset, and select 14 bit temp & humidity
uint16_t config = HDC1000_CONFIG_RST | HDC1000_CONFIG_MODE | HDC1000_CONFIG_TRES_14 | HDC1000_CONFIG_HRES_14;
write(fd, &config, 2);
delay(15);
x = i2c_read16(fd,HDC1000_MANUFID);
if (x != 0x5449)
{
printf("HDC1000_MANUFID returned %4X\n",x);
return -1;
}
x = i2c_read16(fd,HDC1000_DEVICEID);
if (x != 0x1000)
{
printf("HDC1000_DEVICEID returned %4X\n",x);
return -1;
}
return fd;
}
float HDC1000_readTemperature(int fd)
{
float temp = (i2c_read32(fd,HDC1000_TEMP) >> 16);
temp /= 65536;
temp *= 165;
temp -= 40;
return temp;
}
float HDC1000_readHumidity(int fd)
{
float hum = (i2c_read32(fd, HDC1000_TEMP) & 0xFFFF);
hum /= 65536;
hum *= 100;
return hum;
}
int main()
{
int fd;
float x;
fd = HDC1000_Init(HDC1000_I2CADDR);
if (fd==-1)
{
printf("HDC1000_Init failed\n");
return 0;
}
x = HDC1000_readTemperature(fd);
printf("\n temperature = %4.1f degC %4.1f degF\n",x,((x*9)/5)+32);
x = HDC1000_readHumidity(fd);
printf(" humidity = %4.1f%%\n\n",x);
return 0;
}
</pre>
Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com1tag:blogger.com,1999:blog-6238454757421809452.post-34147748303920723742015-07-04T13:57:00.000-04:002015-07-04T13:57:47.146-04:00New Utilization DisplayIn my last post I showed the new case for my MySQL server. The original case had two 10-segment LED bar graph displays that showed CPU and disk utilization. Now I have added a similar display onto the new case.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9TIH3rBx3wn_pqjmJ3YCFzzQMpuDVGt9J88c8mXKMF3XvrOnwxe9UXqWM4LR4rrgU4pLMKGESB2WIWYE5P_09O_k66Fb14NKpYYZscYom1PBUZf0tBkfEkZnFJLb5JAKX0z-zyFTm2fA/s1600/Util1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9TIH3rBx3wn_pqjmJ3YCFzzQMpuDVGt9J88c8mXKMF3XvrOnwxe9UXqWM4LR4rrgU4pLMKGESB2WIWYE5P_09O_k66Fb14NKpYYZscYom1PBUZf0tBkfEkZnFJLb5JAKX0z-zyFTm2fA/s640/Util1.jpg" width="640" /></a></div>
<br />
I chose to only display CPU usage but after I do some testing, I may change it to show disk I/O instead. This is a simple change to the configuration file of the utilization app. One issue with showing CPU is that the Pi 2 has four CPUs and typically only one will be maxed out. In the image above two of the CPUs are maxed out so the utilization shows 50 percent. The most I normally see is 25 percent since I seldom have more that one client querying the database.<br />
<br />
The hardware used is very straightforward. I used a MCP23017 GPIO extender with ten of its pins wired directly to the LEDs. This chip uses an I2C bus connection so it only requires four pins on the Pi - power, ground, SDA, and SCL.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-D_KQO4hdURJzcUSKdvz68ggxtbW9mGYdaaF2HGuv25WpES7CGG2Hw1eIiCKeEkoV2TNBywh6yakWoeSsQRcQATVcmlHGUL3aTHmbjstzCQKqGP7uTxE6n7sAmDP7q9TKv9z66O_t608/s1600/util2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-D_KQO4hdURJzcUSKdvz68ggxtbW9mGYdaaF2HGuv25WpES7CGG2Hw1eIiCKeEkoV2TNBywh6yakWoeSsQRcQATVcmlHGUL3aTHmbjstzCQKqGP7uTxE6n7sAmDP7q9TKv9z66O_t608/s320/util2.jpg" width="320" /></a></div>
<br />
A couple of notes on the build:<br />
<br />
1 - a resistor network would have been much neater than 10 separate resistors. I didn't have one handy but I do have a huge amount of single resistors.<br />
<br />
2 - don't use ribbon cable. Just don't. It looks nice but it is normally used with press on connectors and is not intended for soldering. As soon as you touch the soldering iron to the wire an inch of the insulation melts away. Even with my super nice soldering iron turned to the minimum setting it was a pain to use. I won't make that mistake again.<br />
<br />
If you want to use my code for the utilization display, I will be putting it on github. Check the comments for the address.<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com2tag:blogger.com,1999:blog-6238454757421809452.post-70736377304088233002015-06-05T14:02:00.001-04:002015-06-05T14:04:05.526-04:00Another Linksys Case Mod for a Pi<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8TYWsjgjDh5iQeSInExD85jugQZfVtg-qzeHk9ded316vPu2T_jh3eu4gHKZv2l9tDuJqZXQUuK695_UAQoMOyzgzz_VVnqIeCXF5sm8Xs4ph8ZRrYMiAjyL2iQKcvUlF75skduUqlFE/s1600/_DSC_0021.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8TYWsjgjDh5iQeSInExD85jugQZfVtg-qzeHk9ded316vPu2T_jh3eu4gHKZv2l9tDuJqZXQUuK695_UAQoMOyzgzz_VVnqIeCXF5sm8Xs4ph8ZRrYMiAjyL2iQKcvUlF75skduUqlFE/s320/_DSC_0021.JPG" width="320" /></a>I have rebuilt my MySQL server system using a Pi version 2 and a new external hard drive. I did this one in a Linksys router case. These cases are really easy to work with and not hard to come by.<br />
<br />
I skipped the USB hub on this build. There isn't enough room and I found an easier way. Power is spliced directly into a usb cable from a connector on the rear of the case. I found that this would not backfeed the Pi like I expected. (This does work on some of my older Pi systems.) To overcome this, I added a wire feeding 5V into GPIO pin #2.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0NZX7uBkMqV1l1Q4M1vfAHyu0eN86k6UUQ6Op-9dfJLkho_z6r3Ox0jiS9gVURjrzvyIKwwLa0jgKSvc7n-qQqyflfr5sInmqbfD9f-R0-R32kATZVeLKsmnit1IELa0q8uyW1VuH3jE/s1600/_DSC_0023.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0NZX7uBkMqV1l1Q4M1vfAHyu0eN86k6UUQ6Op-9dfJLkho_z6r3Ox0jiS9gVURjrzvyIKwwLa0jgKSvc7n-qQqyflfr5sInmqbfD9f-R0-R32kATZVeLKsmnit1IELa0q8uyW1VuH3jE/s320/_DSC_0023.JPG" width="320" /></a>The Raspberry Pi is mounted on the base of the case with the USB and network connectors facing the rear. The rear has to be trimmed a little for the connectors to be clearly accessible.<br />
<br />
The hard drive is mounted onto the top of the case. The USB cable has to exit the case and to plug in the the Pi.<br />
<br />
In the process of building this, I updated the instructions on <a href="http://raspberrypihobbyist.blogspot.com/2013/07/running-from-external-hard-drive.html">how to run from an external hard drive.</a><br />
<br />
This case mod makes a neat little case that stacks nicely. Here it is stacked with my cable modem and firewall. (The firewall is a Pi too!)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7Ca3kyi6oZVCxX3dzLthi8kMfa4XuV5wWMKkQTKr197IojzaOlBf1poy_J6KqBURUhS3rw7fmx9Ox19ESU-grIBQcM5ynYQTw6p0BKcLH7lwYLFNmlcXFDLYzDx-E4oRO9b3wiCJAWLM/s1600/DSC_0001.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7Ca3kyi6oZVCxX3dzLthi8kMfa4XuV5wWMKkQTKr197IojzaOlBf1poy_J6KqBURUhS3rw7fmx9Ox19ESU-grIBQcM5ynYQTw6p0BKcLH7lwYLFNmlcXFDLYzDx-E4oRO9b3wiCJAWLM/s320/DSC_0001.JPG" width="307" /></a></div>
<br />
<br />
<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com1tag:blogger.com,1999:blog-6238454757421809452.post-19728248643491644802015-04-21T15:15:00.004-04:002015-04-21T15:15:42.204-04:00Fermentation DetectorThis is a follow up to my posts on automated home brewing:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhevI4oD4gns0_yh9T_t065mpCHL_ruwpNNvNzCyMpcQAyrcZtXM4HnJGtIDxIt-sxdvylgJBpTMt2lSqTFIDx1pbJggbTUp70MpwYHePJDchSBgtPuDFYrP89L_wG0mYTeKqkokOT2Vg/s1600/BloopometerClose.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhevI4oD4gns0_yh9T_t065mpCHL_ruwpNNvNzCyMpcQAyrcZtXM4HnJGtIDxIt-sxdvylgJBpTMt2lSqTFIDx1pbJggbTUp70MpwYHePJDchSBgtPuDFYrP89L_wG0mYTeKqkokOT2Vg/s1600/BloopometerClose.png" height="180" width="200" /></a></div>
<a href="http://raspberrypihobbyist.blogspot.com/2014/03/automated-home-brewing.html">Automated Home Brewing</a><br />
and<br />
<a href="http://raspberrypihobbyist.blogspot.com/2014/10/improved-home-brewing-controller.html">Improved Home Brewing Controller</a><br />
<br />
In the second post I mentioned that I would be adding a "bubble detector" to my interface. Now I have finally gotten the time to do it and am using it to monitor the fermentation stage of a lager. This sensor detects bubbles in the air lock and if you have ever seen an airlock in action you will understand why I call this a "bloop-ometer."<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMK5dXfP3fz1G9hj0OKNNJ48NyRHmYAPlWzrA2ZRbO2ksBrVZuxjeRLSITP49ER8u7yEuHdahuPPo_T7SJTy41M_uWm1aG3KNKW4mkBJNi8eocQ-wJEVm74x6UxMjDmTcBqIIgbdA-zfI/s1600/Interrupter.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMK5dXfP3fz1G9hj0OKNNJ48NyRHmYAPlWzrA2ZRbO2ksBrVZuxjeRLSITP49ER8u7yEuHdahuPPo_T7SJTy41M_uWm1aG3KNKW4mkBJNi8eocQ-wJEVm74x6UxMjDmTcBqIIgbdA-zfI/s1600/Interrupter.png" height="200" width="177" /></a>The sensor uses <a href="https://www.sparkfun.com/products/9299">this photo interrupter</a> with a simple circuit to trigger an interrupt on the Raspberry Pi which records how many bubbles per minute are produced. The photo interrupter has a gap with an infrared LED on one side and an infrared sensor on the other. Voltage is provided to the output pin until an object enters the gap and breaks the infrared beam.<br />
<br />
In this case the object to block the beam is a small amount of water which is mostly transparent to infrared. To overcome this the circuit has a potentiometer to adjust the voltage applied to the LED. It must be adjusted down until the sensor is just on the edge of triggering. In this configuration, the water will block the infrared enough to trigger the device, but when a bubble passes, the infrared can pass.<br />
<br />
The circuit is very simple - an interrupter and a potentiometer is all that is really needed. To make it easier to adjust, I added a red LED. I also added an inverter since the output from the sensor is not enough to drive an LED and trigger the Pi. The potentiometer that I used was 5K ohms and I added an additional 100 ohms for safety. If you use less than 100 ohms then too much current will flow into the LED and it will die. (I know this from experience.)<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNrnv-7pt0CRvLNCbuP1vk01UasbjoV8mfwNZ6MBu4tT_rlM4f5aTfzTOynRa8B4K9ax24jG85qYX3Qby0-248aBcay7h3B8080RGGGlnd7l9Lt1hqIrlGsqSuOpJuvAlLBI55R-DhEFs/s1600/GP1A57HRJ00F.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNrnv-7pt0CRvLNCbuP1vk01UasbjoV8mfwNZ6MBu4tT_rlM4f5aTfzTOynRa8B4K9ax24jG85qYX3Qby0-248aBcay7h3B8080RGGGlnd7l9Lt1hqIrlGsqSuOpJuvAlLBI55R-DhEFs/s1600/GP1A57HRJ00F.png" /></a><br />
Here is the pinout for the GP1A57HRJ00F.<br />
<br />
And here is the circuit as I built it.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7JQBtOtRR31zeXAs28ILjUDfec8i14TfyDP8gpKItd-jg3o9Sll0x8t6Blf41cPUqJG86xcLZCYFRImsaRjr8zDYTEBO0bXsmrQn_aMSmF8Uh8vOjM5FLuYv_CeqkVXPyXS_Mu0sIoXU/s1600/BubbleSensorCircuit.png" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7JQBtOtRR31zeXAs28ILjUDfec8i14TfyDP8gpKItd-jg3o9Sll0x8t6Blf41cPUqJG86xcLZCYFRImsaRjr8zDYTEBO0bXsmrQn_aMSmF8Uh8vOjM5FLuYv_CeqkVXPyXS_Mu0sIoXU/s1600/BubbleSensorCircuit.png" height="248" width="320" /></a><br />
<br />
And finally, a video of it in action.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dwIxkRgzBNbkbrUCnOlsn-UxplH6U89H9dn9thdfU6UGzsTo_sEd72FY2AWceI6RX3Bl314VLrRbtNVsUjLIQ' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com7tag:blogger.com,1999:blog-6238454757421809452.post-83639902814840755502015-03-26T12:04:00.001-04:002015-03-26T12:11:00.148-04:00New Raspberry Pi GPIO Pinout DiagramSince I have been using model B+ and model 2 a lot lately, I wanted an updated GPIO pinout diagram. Also, since I used WiringPi, the diagram had to include that numbering scheme. None of the diagrams I found satisfied me, so I made my own. I used the output from the WiringPi command <span style="font-family: Courier New, Courier, monospace;">gpio readall</span> and did some formatting in excel to produce the following diagram. I hope you find it useful.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMy6EOuohMOgB6TPEUHTZOlh1Y9Zj30waJc1zmoeMmmp3iwNbHgtg1bK-GxZEFEVYkN50T1kY8mvCcsXkIj-z6I13YkI7valafnAcYk8vveaIdA0gF5XYQ4sfZPlIXV6DmCc93kQSsEEA/s1600/Raspberry+Pi+GPIO+Pins.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMy6EOuohMOgB6TPEUHTZOlh1Y9Zj30waJc1zmoeMmmp3iwNbHgtg1bK-GxZEFEVYkN50T1kY8mvCcsXkIj-z6I13YkI7valafnAcYk8vveaIdA0gF5XYQ4sfZPlIXV6DmCc93kQSsEEA/s1600/Raspberry+Pi+GPIO+Pins.png" height="640" width="603" /></a></div>
<span id="goog_1262896127"></span><span id="goog_1262896128"></span><br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com1tag:blogger.com,1999:blog-6238454757421809452.post-75050566145276332952015-03-08T22:01:00.002-04:002015-03-08T22:07:03.425-04:00Using the MPL115A2 to read Temperature and Barometric PressureThis post is a continuation of the series on my weather station system.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF70SUBYqmYdyf5G9BCGnTALzZhF9_lt_VROB3lTiddpFZQAVvoaTJNEiWm8dO_mfm4ZchtX3KUyOY37NWti-Nnib7Lo8sqqcAlbvdf0XfMV3CsU-cL_xh3FkE8rdsqDxCrvQ77L6dI74/s1600/mpl115a.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF70SUBYqmYdyf5G9BCGnTALzZhF9_lt_VROB3lTiddpFZQAVvoaTJNEiWm8dO_mfm4ZchtX3KUyOY37NWti-Nnib7Lo8sqqcAlbvdf0XfMV3CsU-cL_xh3FkE8rdsqDxCrvQ77L6dI74/s1600/mpl115a.jpg" height="179" width="200" /></a></div>
My weather station uses the MPL115A2, <a href="http://www.adafruit.com/product/992">available from Adafruit</a>. It is an inexpensive sensor for measuring temperature and barometric pressure. It is only moderately accurate - the MPL3115A2, which only slightly more expensive, would probably have been a better choice. Both sensors are interfaced using an I2C bus and are fairly simple to use.<br />
<br />
In order to compute the correct pressure, several coefficient values must be read from the device first. These coefficients are unique to each device and provide the calibration necessary to arrive at an accurate reading. Since they don't change, they only need to be read once.<br />
<br />
After reading the coefficients, the data capture and conversion are started by writing a zero to register address 0x12. The program must then pause briefly to allow the conversion to complete. The results are stored in the device registers and are read with the standard I2C commands. The temperature value is taken directly from the register values, with some simple adjustments to get it to degrees Celsius. The pressure is then computed by a formula that applies the coefficients read earlier as well as the temperature. The value is in kilo Pascals. For use by an American like myself, these are finally converted to degrees Fahrenheit and inches of Mercury.<br />
<br />
Below is an example, in C, of the code similar to what I use.<br />
<br />
<pre class="brush: csharp">/*
example to test mpl115a2 (temp/baro sensor) on i2c
ted.b.hale@gmail.com
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
int main(int argc, char *argv[])
{
int i, n, fd;
// command string to get coefficients
unsigned char coef_request[3] = {3, 4, 8};
// command string to request conversion
unsigned char conv_request[3] = {0, 0x12, 0};
// variables for the final results
float baro, celsius, farenheit;
// variables to hold the integer values of coefficients
int16_t a0coeff;
int16_t b1coeff;
int16_t b2coeff;
int16_t c12coeff;
// variables to hold the floating point coefficients
float a0;
float b1;
float b2;
float c12;
// some intermediate values
int pressure, temp;
float pressureComp;
// open a file descriptor to the device on the I2C bus
fd = wiringPiI2CSetup(0x60); // 0x60 is bus address of mpl115a2
if (fd==-1)
{
printf("wiringPiI2CSetup failed\n");
return 0;
}
// get the coefficients. This only needs to be done once.
// Note on C language: the << and >> operators perform bit shifting
a0coeff = (( (uint16_t) wiringPiI2CReadReg8(fd,4) << 8) | wiringPiI2CReadReg8(fd,5));
b1coeff = (( (uint16_t) wiringPiI2CReadReg8(fd,6) << 8) | wiringPiI2CReadReg8(fd,7));
b2coeff = (( (uint16_t) wiringPiI2CReadReg8(fd,8) << 8) | wiringPiI2CReadReg8(fd,9));
c12coeff = (( (uint16_t) (wiringPiI2CReadReg8(fd,10) << 8) | wiringPiI2CReadReg8(fd,11))) >> 2;
printf("%d %d %d %d\n",a0coeff,b1coeff,b2coeff,c12coeff);
// convert coefficients to floating point
a0 = (float)a0coeff / 8;
b1 = (float)b1coeff / 8192;
b2 = (float)b2coeff / 16384;
c12 = (float)c12coeff;
c12 /= 4194304.0;
printf("%f %f %f %f\n\n",a0,b1,b2,c12);
// start conversion and wait a tiny bit
wiringPiI2CWriteReg8(fd,0x12,0);
delay(5);
// get the results by reading the device registers
pressure = (( (uint16_t) wiringPiI2CReadReg8(fd,0) << 8) | wiringPiI2CReadReg8(fd,1)) >> 6;
temp = (( (uint16_t) wiringPiI2CReadReg8(fd,2) << 8) | wiringPiI2CReadReg8(fd,3)) >> 6;
// compute temperature compensation for pressure
pressureComp = a0 + (b1 + c12 * temp ) * pressure + b2 * temp;
// get the pressure in kiloPascals
baro = ((65.0F / 1023.0F) * pressureComp) + 50.0F; // kPa
// get the temperature in celsius degrees
celsius = ((float) temp - 498.0F) / -5.35F +25.0F; // C
// convert kilo-Pascals to inches of mercury
baro = baro * 0.295299830714;
// convert Celsius to Farenheit
farenheit = (celsius * 1.8) + 32.0;
//show the results
printf("%f %f\n\n",baro,farenheit);
return 0;
}</pre>
<br />
The device comes with a 6x1 header which allows it to be mounted simply on a circuit board. I mounted it directly on the interface board that I built for the weather station. This is in a weatherproof enclosure, but that should have negligible effect on the reading of pressure since the enclosure is not completely air-tight. This will, however, affect temperature reading. Therefore, while I do record the temperature value, it is not the primary source for temperature that my weather station uses. For that I use the AM2315 sensor, which is described in my previous post.Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com4tag:blogger.com,1999:blog-6238454757421809452.post-83516364715809835432015-02-26T14:50:00.004-05:002015-02-26T17:11:48.056-05:00Using the AM2315 Temperature/Humidity Sensor<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9j7oYYidkVElJ7E4mpqZ-KM0IrZpT0qGl0JAVgvnrZxFJi0VdLtxafn6hrvP61t_vT1XhbzzXefDBzal2_dy99wMeDLFywXiTR6auMmhZfBm2lLM5yFuq5MdCgi29zuJs0bvVO1k0Kas/s1600/am2315.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9j7oYYidkVElJ7E4mpqZ-KM0IrZpT0qGl0JAVgvnrZxFJi0VdLtxafn6hrvP61t_vT1XhbzzXefDBzal2_dy99wMeDLFywXiTR6auMmhZfBm2lLM5yFuq5MdCgi29zuJs0bvVO1k0Kas/s1600/am2315.jpg" height="150" width="200" /></a></div>
This post is a continuation of my series on the weather station that I built. On e of the sensors that it uses is the AM2315 temperature/humidity sensor<br />
<br />
The AM2315 is very poorly documented. This leads to several problems when attempting to use it. Thankfully, Sopwith has provided details of his experience with this device <a href="http://sopwith.ismellsmoke.net/wp-content/uploads/2014/03/PI-How-To-AM2315.pdf">http://sopwith.ismellsmoke.net/wp-content/uploads/2014/03/PI-How-To-AM2315.pdf</a> so we can move on more quickly to making use of it. Sopwith provides a more detailed explanation of how to set up and use this device. If you are using Python, then you must read his article, since he explains some additional problems caused by the way the Python library works.<br />
<br />
The first problem you will run into is that it doesn't show up on the i2c bus. That is because the device stays in sleep mode until it is woken up to prevent generating heat that would affect the humidity sensor accuracy. If you run the command i2cdetect twice quickly, then the second time it will show up.<br />
<br />
The second problem is that the i2c address is wrong in the datasheet. It is no longet at 0xB8, but is instead at 0x5c. This is not a big problem since you will see the correct address show up in the second i2cdetect results.<br />
<br />
The third problem is really a side effect of the first - the device does not keep updated values in registers like most i2c devices. You will have to issue a read request command and then read the response.<br />
<br />
Even though I use the i2c support provided by the WiringPi library, it is best to do raw reads and writes to the device because it does not follow the i2c standard very well. This is the sequence to follow:<br />
<br />
<ul>
<li>Write a zero byte to it twice to wake it up</li>
<li>Write a read request to make it update the temperature and humidity values</li>
<li>Read the response to the read request</li>
<li>Do some manipulations on the data to get the values in degress Celcius and %RH</li>
</ul>
<br />
<br />
Here is an example program in C with comments that give more detailed explanation.<br />
<pre class="brush: csharp">
/*
example code to test am2315 (temp/humid sensor) on i2c bus
ted.b.hale@gmail.com
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
int main(int argc, char *argv[])
{
int n, fd;
// read request - 3 is the read register command
// 0 is the address to start at
// 4 is the number of bytes to read
unsigned char read_request[3] = {3, 0, 4};
// buffer for the response: command byte, length byte, 4 bytes data, 2 bytes of checksum
unsigned char response[8];
// dummy data sent to wake up device
unsigned char dummy[1] = {0};
// the final results
float humidity, celsius;
// open the am2315 device using WiringPi
// 0x5C is bus address of am2315
// fd is the "file descriptor" used in later read and writes
fd = wiringPiI2CSetup(0x5c);
if (fd==-1)
{
printf("wiringPiI2CSetup failed\n");
return 0;
}
// run until killed with Ctrl-C
while (1)
{
// send some data to wake it up
n = write(fd, dummy, 1);
n = write(fd, dummy, 1);
// send the read request
n = write(fd, read_request, 3);
printf("write returned %d bytes\n",n);
// very short delay to allow device to do data conversion
delay(2);
// read the reaponse
n = read(fd, response, 8);
printf("read returned %d bytes\n",n);
// sanity check on data returned
// first byte should echo the read requst byte (3)
// second byte should indicate 4 bytes of data returned
// I don't bother verifying the checksum
if ((response[0]!=3) || (response[1]!=4))
{
printf("i2c response invalid\n");
for (n=0; n<8; n++)
printf("%02x ",response[n]);
}
else
{
// (high byte * 256) + low byte
// divide by 10
humidity = (256*response[2] + response[3])/10.0;
// same as above but mask out the sign bit on the high byte
celsius = (256 * (response[4] & 0x7F) + response[5]) / 10.0;
// make result negative if the sign bit is set
if ((response[4]&0x80)!=0)
celsius *= -1.0;
printf(" humidity = %5.1f%%\n",humidity);
printf("temperature = %5.1f\n",celsius);
}
printf("\n\n\n");
// wait two second and loop again
delay(2000);
}
return 0 ;
}
</pre>
The AM2315 is supposed to be a very accurate device, but after using it a while, I am very suspicious
of the humidity values. The plots of my data show the humidity doing things that are not possible. I suspect that it sometimes gets saturated with moisture from fog, dew or rain and then it reads 100% for a long time. Mine is mounted so that it is directly exposed to the outside environment. Best practice says that I should have a radiation shield protecting the temperature sensor from direct sunlight. I plan on creating one for the AM2315 and this may also allow the humidity sensor to be more accurate.
Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com2tag:blogger.com,1999:blog-6238454757421809452.post-55863222304104314822015-02-06T00:14:00.000-05:002015-02-06T00:19:30.740-05:00Log Data to the Weather UndergroundThe next topic for my weather station system is how to send your data to a "Personal Weather Station" on the <a href="http://www.wunderground.com/">Weather Underground</a> web site. This provides a nice interface for the world to see your current (and past) conditions.<br />
<br />
The <a href="http://www.wunderground.com/weatherstation/overview.asp">PWS Overview</a> explains what personal weather stations are. It also has a buying guide. For comparison, the total cost for my system was somewhere around $150 (That's just a very rough guess.)<br />
<br />
See <a href="http://wiki.wunderground.com/index.php/PWS_-_Upload_Protocol">PWS Upload Protocol</a> for the complete documentation for uploading data for a PWS. To summarize, you need to send a properly formatted string to a web address (a simple HTTP GET to a PHP script.)<br />
<br />
So here is a simplified example of the code that I am using.<br />
<br />
<pre class="brush: csharp">/***********************************************************************
Filename: wunderground.c
send current conditions to my Personal Weather Station on
The Weather Underground
Uses libcurl to send the data via HTTP
build with:
gcc -o wutest wunderground.c -L/usr/local/lib -L/usr/local/ -lcurl -lwiringPi
23-Jan-2015 Ted Hale created this as an example for blog
************************************************************************/
/* system includes */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <string.h>
#include <curl/curl.h>
#define TRUE 1
#define FALSE 0
// these are normally global varables that my weather system updates
// just put them here for this example
float outsideTemp;
float windSpeed;
float windGust;
float rainPeriod;
float humidity;
float barometric;
// my PWS ID and password
char *myStationID = "KVAWILLI99";
char *myStationPassword = "NOTMYPASSWORD";
// structure used by the libcurl write callback function
struct url_data {
size_t size;
char* data;
};
//=====================================================================
// write callback function needed by libCurl
size_t write_data(void *ptr, size_t size, size_t nmemb, struct url_data *data) {
size_t index = data->size;
size_t n = (size * nmemb);
char* tmp;
data->size += (size * nmemb);
tmp = realloc(data->data, data->size + 1); /* +1 for null terminator */
if(tmp) {
data->data = tmp;
} else {
if(data->data) {
free(data->data);
}
printf("skynet_post Failed to allocate memory.\n");
return 0;
}
memcpy((data->data + index), ptr, n);
data->data[data->size] = '\0';
return size * nmemb;
}
//=====================================================================
// upload current conditions to Weather Underground
int UpdateWunderground()
{
// URL format
char *myFmt = "http://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?"
// 1 2 3 4 5 6 7 8
"ID=%s&PASSWORD=%s&dateutc=%04d-%02d-%02d+%02d%%3A%02d%%3A%02d"
// 9 10 11 12
"&windspeedmph=%f&windgustmph=%f&tempf=%f&rainin=%f"
// 13 14
"&baromin=%f&humidity=%f&action=updateraw";
/* 1 ID
* 2 passwd
* 3 yr
* 4 mon
* 5 day
* 6 hr
* 7 min
* 8 sec
* 9 winspeed
* 10 gusts
* 11 Outdoor temp
* 12 rain
* 13 baro
* 14 humidity
*/
int error = TRUE;
time_t now;
struct tm *dt;
int hour,minute,second,year,month,day;
char url[1024];
CURL *curl;
CURLcode res;
struct url_data response;
time(&now);
dt = gmtime(&now);
// build the URL string
// 1 2
snprintf(url, sizeof(url)-1, myFmt, myStationID, myStationPassword,
// 3 4 5 6 7 8
dt->tm_year, dt->tm_mon, dt->tm_mday, dt->tm_hour, dt->tm_min, dt->tm_sec,
// 9 10 11 12 13 14
windSpeed, windGust, outsideTemp, rainPeriod, barometric, humidity);
// guarantee null termination of string
url[sizeof(url)-1] = 0;
curl = curl_easy_init();
if (curl) {
response.size = 0;
response.data = malloc(4096); /* reasonable size initial buffer */
response.data[0] = '\0';
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
{
printf("curl_easy_perform() failed: %s\n",curl_easy_strerror(res));
error = TRUE;
} else {
error = (strcmp(response.data,"Success") != 0);
}
curl_easy_cleanup(curl);
free (response.data);
} else {
printf("curl_easy_init failed\n");
error = TRUE;
}
return error;
}
int main()
{
// set some dummy data
outsideTemp = 69.7;
windSpeed = 2.3;
windGust = 5.6;
rainPeriod = 0.001;
humidity = 75.0;
barometric = 31.5;
UpdateWunderground();
return 0;
}
</pre>
<br />
Please let me know if you use this code. I would like to hear how it works for you.<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com0tag:blogger.com,1999:blog-6238454757421809452.post-18556066069294931592015-01-23T15:39:00.000-05:002015-03-25T15:27:01.307-04:00GPIO Interrupts using WiringPiMy weather station has two devices that send simple pulses to the Raspberry Pi. The rain gauge pulses each time its "bucket" fills and the wind speed gauge pulses for each rotation. The best way to handle this is by using interrupts.<br />
<br />
An interrupt is a signal to the computer to stop what it is doing and do something else. These are used extensively by the operating system, but an application can use them as well. If you have a GPIO input that needs to be responded to, you could poll the GPIO pin in a loop waiting for it to change, but this can be unreliable for very brief state changes. It is also wasteful of the CPU. The better way is to assign an interrupt that will be activated when the GPIO pin changes state.<br />
<br />
I code all my projects in C and use <a href="http://wiringpi.com/">Gordon's WiringPi API</a>. This library makes it much easier to use GPIO. Interrupts are now supported using the <span style="font-family: Courier New, Courier, monospace;">wiringPiISR </span>function. (The <span style="font-family: Courier New, Courier, monospace;">waitForInterrupt </span>function is deprecated and should not be used.) Using interrupts takes only three steps:<br />
<br />
<ul>
<li>Create a function to be called when the GPIO pin changes state. This must be defined like this: <span style="font-family: Courier New, Courier, monospace;">void myInterrupt(void)</span></li>
<li>Initialize the WiringPi library by calling <span style="font-family: Courier New, Courier, monospace;">wiringPiSetup</span></li>
<li>Call <span style="font-family: Courier New, Courier, monospace;">wiringPiISR </span>to configure the interrupt</li>
</ul>
<br />
You can choose to have your interrupt called when the pin goes low, goes high, or both (<span style="font-family: Courier New, Courier, monospace;">INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH</span>)<br />
<br />
My interrupts simply increment a global variable. The value of this variable is then checked periodically (typically once per second) and the count is converted into the appropriate units for the device.<br />
<br />
An example of how to use an interrupt is shown below.<br />
<br />
<pre class="brush: csharp">#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>
// Use GPIO Pin 17, which is Pin 0 for wiringPi library
#define BUTTON_PIN 0
// the event counter
volatile int eventCounter = 0;
// -------------------------------------------------------------------------
void myInterrupt(void) {
eventCounter++;
}
// -------------------------------------------------------------------------
int main(void) {
// sets up the wiringPi library
if (wiringPiSetup () < 0) {
fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno));
return 1;
}
// set Pin 17/0 generate an interrupt on high-to-low transitions
// and attach myInterrupt() to the interrupt
if ( wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0 ) {
fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno));
return 1;
}
// display counter value every second.
while ( 1 ) {
printf( "%d\n", eventCounter );
eventCounter = 0;
delay( 1000 ); // wait 1 second
}
return 0;
}
</pre>
<br />
All of the code from my weather station can be found at<br />
<a href="https://github.com/tedhale/raspberry-pi-hobbyist">https://github.com/tedhale/raspberry-pi-hobbyist</a><br />
<br />
You can also get it using git:<br />
git clone https://github.com/tedhale/raspberry-pi-hobbyist.git<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com4tag:blogger.com,1999:blog-6238454757421809452.post-57896431315074738712014-12-28T17:07:00.001-05:002014-12-28T17:07:58.266-05:00Raspberry Pi Weather StationMy latest Pi project involves creating a weather station in a way very different from most others. I will cover various parts of this project in my next several posts.<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho_vvxGAi6vbyb9owadKwPkXYhzvIBv98DCMIaL-dGezjotaZVcHn3Kal0nP4LabML0fc7upAwU2e0lBSFSAB1spTUvDd2rhkPbi1iHgDc5rbRi4Dar2ONyz1BEAq-LJNgVrpvIoJAvec/s1600/weatherstation3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEho_vvxGAi6vbyb9owadKwPkXYhzvIBv98DCMIaL-dGezjotaZVcHn3Kal0nP4LabML0fc7upAwU2e0lBSFSAB1spTUvDd2rhkPbi1iHgDc5rbRi4Dar2ONyz1BEAq-LJNgVrpvIoJAvec/s1600/weatherstation3.png" height="261" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The weather station completed and mounted outdoors.</td></tr>
</tbody></table>
<div>
The most common way that a Raspberry Pi (or any other computer) is interfaced is via a pre-built system that has a serial or USB connection. This is the fastest and easiest way to do this. But what fun is doing things the way everyone else does?</div>
<div>
<div>
<br /></div>
<div>
I had an old weather station that was relatively cheap (less than $100) and did not have any drivers for Linux. I ran it on an old PC for several years, but it finally stopped working. The wireless part was never very reliable and it was a pain to keep replacing batteries. I was able to salvage the anemometer (wind speed) and rain gauge and hack them into my new system.</div>
</div>
<div>
<br /></div>
<div>
For temperature and humidity readings I use the <a href="http://www.adafruit.com/products/1293">AM2315 from adafruit</a>. For barometric pressure I use the <a href="http://www.adafruit.com/products/992">MPL115A2, also from adafruit</a>. Both of the devices interface via the I2C bus. I have to give a plug for adafruit. It's a great place to get parts to connect to the Raspberry Pi.</div>
<div>
<br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWWyw2dKaOfkkjNsnqUjEr__wV4sGFPBJwr0Eh7JHvi9aE9iwsuwtOa9Bgae67KEb4bZRYcvwfkjmxrOZamVtbOYGP2qbMLkXX87nUCjPPuLr5P_MYrFeahyphenhyphen-MYLI2LP6uRy7tPPY_cmY/s1600/weatherstation1.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWWyw2dKaOfkkjNsnqUjEr__wV4sGFPBJwr0Eh7JHvi9aE9iwsuwtOa9Bgae67KEb4bZRYcvwfkjmxrOZamVtbOYGP2qbMLkXX87nUCjPPuLr5P_MYrFeahyphenhyphen-MYLI2LP6uRy7tPPY_cmY/s1600/weatherstation1.png" height="220" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The interface board and Pi on a mounting plate.</td></tr>
</tbody></table>
<div>
The anemometer and rain gauge are simple contact closure interfaces. Each tiny bucket of rain and each rotation of the anemometer produce a single pulse. These are connected simply through GPIO pins and drive interrupts which count the pulses.</div>
<div>
<br /></div>
<div>
The interface board that connects to the Pi is actually very simple. It mostly just passes GPIO pins to screw terminals. The MPL115A2 is the tiny blue board next to the ribbon connector.</div>
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJGJAIQYUniDMbXCcb0syUEqY2_2vSb8yink8dXKrkbz3zVdwRtm_hX0Z2Gwu0latHbabHTIN0zg5kXHdm-VEFKl9NpYgdIuOsQOFEh8MGHugkeoXdaHz4IDPLqVguZi98DHQrXepfLDg/s1600/weatherstation2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJGJAIQYUniDMbXCcb0syUEqY2_2vSb8yink8dXKrkbz3zVdwRtm_hX0Z2Gwu0latHbabHTIN0zg5kXHdm-VEFKl9NpYgdIuOsQOFEh8MGHugkeoXdaHz4IDPLqVguZi98DHQrXepfLDg/s1600/weatherstation2.png" height="223" width="320" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Adafruit also provided the perfect <a href="http://www.adafruit.com/products/905">weatherproof enclosure</a>. I will have to drill holes to feed wires in, but those will be sealed with silicone.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
In the near future I will write up posts on some of the problems I had to overcome to complete this project.</div>
<div>
<ul>
<li>Handling GPIO interrupts</li>
<li>Interfacing to the AM2315 via I2C</li>
<li>Interfacing to the MPL115A2 via I2C</li>
<li>Calibrating the rain and wind sensors</li>
<li>Logging to my MySQL database server</li>
<li>Logging to Weather Underground</li>
<li>Providing a nice web interface to display the weather data</li>
</ul>
Also, I will post my source code for others to use and/or learn from.</div>
<div>
<br /></div>
<div>
This has been a very fun project and I expect to use the weather station for many years to come.</div>
<div>
<br /></div>
<div>
Of course, Murphy had to strike - when I went to mount the system outdoors, <b>it was raining!</b></div>
<div>
<br /></div>
<div>
<br /></div>
Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com12tag:blogger.com,1999:blog-6238454757421809452.post-41868408214562137042014-12-14T13:33:00.004-05:002014-12-27T07:50:24.896-05:00My New System ChecklistI recently had need to create a new Raspbian system for a project and decided to record all the things I did after the system image first boots. Frequently, I forget one or two of these, so this will become a checklist that I follow when I create a new system.<br />
<br />
There are many guides to creating a system for the Raspberry Pi and this post is not an attempt to create another. I am putting this here for my own reference as much as to share. To make it helpful to beginners, I have added some explanations. You may prefer nano over vi as the file editor.<br />
<br />
Please feel free to use the comments section to let people know what customization you like to make for your Pi systems.<br />
<br />
Load image as usual<br />
raspi-config runs first time<br />
- expand file system<br />
- Internationalization -> set locale -> TZ = US-Eastern<br />
- Internationalization -> Keyboard = English(US)<br />
- advanced -> hostname (RasPi-##-Purpose)<br />
- advanced -> mem split 16 for GPU<br />
- advanced -> enable SPI and I2C and Serial<br />
reboot, and log in as pi (raspberry)<br />
<br />
CPU overclocking would also be set up in raspi-config, but I haven't had any need to do this.<br />
<br />
All of the following commands require root privilege. You can either put <span style="font-family: Courier New, Courier, monospace;">sudo</span> before each command or enter <span style="font-family: Courier New, Courier, monospace;">sudo -i </span>and run a shell as root.<br />
<br />
Create a new user for myself, give it sudoer privilege.<br />
<span style="font-family: Courier New, Courier, monospace;">adduser ted </span><br />
<span style="font-family: Courier New, Courier, monospace;">echo "ted ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers</span><br />
<br />
<span style="font-family: inherit;">Update the package database and upgrade all installed packages.</span><br />
<span style="font-family: Courier New, Courier, monospace;">apt-get update </span><br />
<span style="font-family: Courier New, Courier, monospace;">apt-get upgrade</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: inherit;">Install some new packages.</span><br />
<span style="font-family: Courier New, Courier, monospace;">apt-get install samba screen libmysqlclient-dev libi2c-dev</span><br />
<br />
Configure Samba (Windows file sharing)<br />
<span style="font-family: Courier New, Courier, monospace;">vi /etc/samba/smb.conf</span><br />
uncomment "socket options = TCP_NODELAY"<br />
delete all shares and add:<br />
<span style="font-family: Courier New, Courier, monospace;">[opt]</span><br />
<span style="font-family: Courier New, Courier, monospace;"> comment = opt</span><br />
<span style="font-family: Courier New, Courier, monospace;"> writable = yes</span><br />
<span style="font-family: Courier New, Courier, monospace;"> locking = no</span><br />
<span style="font-family: Courier New, Courier, monospace;"> path = /opt</span><br />
<span style="font-family: Courier New, Courier, monospace;"> public = yes</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
Restart the Samba service<br />
<span style="font-family: Courier New, Courier, monospace;">service samba restart </span><br />
<br />
Edit the SSH server config. Turning off DNS reverse lookups will speed up the connection process when to log in through SSH.<br />
<span style="font-family: Courier New, Courier, monospace;">vi /etc/ssh/sshd_config</span><br />
add "UseDNS no"<br />
<br />
Edit the netwrok configuration and set static IP address and wifi config. The interface name for the wifi will be used below in the supplicant file.<br />
<span style="font-family: Courier New, Courier, monospace;">vi /etc/network/interfaces</span><br />
<span style="font-family: Courier New, Courier, monospace;">iface eth0 inet static</span><br />
<span style="font-family: Courier New, Courier, monospace;"> address 192.168.0.51</span><br />
<span style="font-family: Courier New, Courier, monospace;"> netmask 255.255.255.0</span><br />
<span style="font-family: Courier New, Courier, monospace;"> gateway 192.168.0.1</span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;">iface home inet static </span><br />
<span style="font-family: Courier New, Courier, monospace;"> address 192.168.0.53</span><br />
<span style="font-family: Courier New, Courier, monospace;"> netmask 255.255.255.0</span><br />
<span style="font-family: Courier New, Courier, monospace;"> gateway 192.168.0.1</span><br />
<br />
Edit the wifi supplicant file. The "id_str" setting connects back to the name used above.<br />
<span style="font-family: Courier New, Courier, monospace;">vi /etc/wpa_supplicant/wpa_supplicant.conf</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">network={</span><br />
<span style="font-family: Courier New, Courier, monospace;"> id_str="home"</span><br />
<span style="font-family: Courier New, Courier, monospace;"> ssid="NOTMYSSID"</span><br />
<span style="font-family: Courier New, Courier, monospace;"> psk="NotMyPassword"</span><br />
<span style="font-family: Courier New, Courier, monospace;"> proto=WPA</span><br />
<span style="font-family: Courier New, Courier, monospace;"> key_mgmt=WPA-PSK</span><br />
<span style="font-family: Courier New, Courier, monospace;"> pairwise=TKIP</span><br />
<span style="font-family: Courier New, Courier, monospace;"> auth_alg=OPEN</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<br />
<span style="font-family: inherit;">Install Gordon's WiringPi library. I use this extensively in my C programming.</span><br />
<span style="font-family: Courier New, Courier, monospace;">cd ~</span><br />
<span style="font-family: Courier New, Courier, monospace;">git clone git://git.drogon.net/wiringPi</span><br />
<span style="font-family: Courier New, Courier, monospace;">cd wiringPi</span><br />
<span style="font-family: Courier New, Courier, monospace;">git pull origin</span><br />
<span style="font-family: Courier New, Courier, monospace;">./build</span><br />
<span style="font-family: Courier New, Courier, monospace;">gpio -v</span><br />
<span style="font-family: Courier New, Courier, monospace;">gpio readall</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: inherit;">Edit the kernel module configuration to enable SPI, I2C, and 1-Wire.</span><br />
<span style="font-family: Courier New, Courier, monospace;">vi /etc/modprobe.d/raspi-blacklist.conf</span><br />
uncomment SPI and I2C devices<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">vi /etc/modules</span><br />
<span style="font-family: inherit;">add this</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"># SPI devices </span><br />
<span style="font-family: Courier New, Courier, monospace;">spi-dev </span><br />
<span style="font-family: Courier New, Courier, monospace;"># I2C devices </span><br />
<span style="font-family: Courier New, Courier, monospace;">i2c-dev </span><br />
<span style="font-family: Courier New, Courier, monospace;">i2c_bcm2708</span><br />
<span style="font-family: Courier New, Courier, monospace;"># 1-Wire devices </span><br />
<span style="font-family: Courier New, Courier, monospace;">w1-gpio </span><br />
<span style="font-family: Courier New, Courier, monospace;"># 1-Wire thermometer devices </span><br />
<span style="font-family: Courier New, Courier, monospace;">w1-therm </span><br />
<br />
Finally, reboot the system again. Then log on as the new user you created and remove the default user.<br />
<span style="font-family: Courier New, Courier, monospace;">userdel pi</span><br />
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">If you don't do this last step and your system is accessible from the internet, then it will not be long (sometimes only hours or minutes) before a hacker finds it and does<i> bad things</i>. My firewall log shows constant attempts to brute force a login via SSH and "pi" is a common user name that is tried.</span></div>
<br />
<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com4tag:blogger.com,1999:blog-6238454757421809452.post-18374695583140906782014-12-09T21:31:00.001-05:002014-12-09T21:31:29.573-05:00Wifi Router Case Mod<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ezLzcYRItLkYmJVNuoIA6qXU6Vm8xiFijU-UhlZiOruiWdRb0H4GFvxNzWtzJFdXcvdzcR1P4plj8g5YrtHqL8uO1z0lMiWYs64uANxzLAsctpojebxdnkmgoAnRA1IozDOHlewU6wI/s1600/p2.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ezLzcYRItLkYmJVNuoIA6qXU6Vm8xiFijU-UhlZiOruiWdRb0H4GFvxNzWtzJFdXcvdzcR1P4plj8g5YrtHqL8uO1z0lMiWYs64uANxzLAsctpojebxdnkmgoAnRA1IozDOHlewU6wI/s1600/p2.png" height="176" width="200" /></a>In my previous post I showed how to use the case from an old LinkSys router as a case for a Raspberry Pi. Today I decided that it needed a little improvement. Bring on the blinking lights. Isn't everything better with blinking lights?<br />
<br />
I showed in the posts <a href="http://raspberrypihobbyist.blogspot.com/2014/03/server-box-with-utilization-displays.html">Server Box with Utilization Displays</a> and <a href="http://raspberrypihobbyist.blogspot.com/2014/03/cpu-and-io-utilization-display-details.html">CPU and I/O Utilization Display - Details</a> how to use LEDs for a utilization display. This project is a little smaller scale - only six LEDs instead of twenty.<br />
<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOBfSspWjPjw2PbYhB8s5yUKxE6TsRLgm_OoyUWI1fM8fdpDKhRjAmk3kDX2eYCVvEGJLXx0WeslYuTG38anc_At4na4pWkmVqvAKaL9GdtNY4u3k6WXexoqFP-BtYjd8Z9yjQZd9yj9A/s1600/p1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOBfSspWjPjw2PbYhB8s5yUKxE6TsRLgm_OoyUWI1fM8fdpDKhRjAmk3kDX2eYCVvEGJLXx0WeslYuTG38anc_At4na4pWkmVqvAKaL9GdtNY4u3k6WXexoqFP-BtYjd8Z9yjQZd9yj9A/s1600/p1.png" height="143" width="200" /></a>The circuit is very simple. The positive lead to each LED is connected to a resistor. All of the resistors are connected to 5V. The negative lead of each LED is connected to a GPIO pin. A low signal on the GPIO pin turns the LED on.<br />
<br />
This inverts the logic, but that can be handled in software. This has the benefit of being able to push more current through the LEDs than would be possible if the GPIO line was connected to the positive lead of the LED.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHdEdM-iY8HlYfGWWCRhaPUEJzVakT7ktFJg2WlERJaGkX-iVXCBMrw6zfzrSuAY7yIGHrjoEMIkGZV5VVxvdpBwrL019XzcuvYB0loezbKLFX4NpNVa45R6_BRQjBwUHT7nCWXrRCYOo/s1600/Led-2x3.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHdEdM-iY8HlYfGWWCRhaPUEJzVakT7ktFJg2WlERJaGkX-iVXCBMrw6zfzrSuAY7yIGHrjoEMIkGZV5VVxvdpBwrL019XzcuvYB0loezbKLFX4NpNVa45R6_BRQjBwUHT7nCWXrRCYOo/s1600/Led-2x3.png" height="121" width="200" /></a><br />
<br />
This PCB layout shows a close approximation of how I made the circuit. I didn't make a printed circuit board, but I have been designing some for work this week, so I did this drawing using PCB Artist. I definitely plan to create some PCBs for my Pi hobby, once I decide what to make next.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVDU6Qdtxn0cTXhpIlt6Y0rwP2kSmFf1UCW7UJlsC87ce2MYhi0Ey8xLJOU1hBsSyUFIYNf1rM9vKC7YhyhRB8VBVSRP7cPSOv8VYphXap77uUhn6bw8dO0TDtZUdiXVbsGc6gDtpWY3k/s1600/p3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVDU6Qdtxn0cTXhpIlt6Y0rwP2kSmFf1UCW7UJlsC87ce2MYhi0Ey8xLJOU1hBsSyUFIYNf1rM9vKC7YhyhRB8VBVSRP7cPSOv8VYphXap77uUhn6bw8dO0TDtZUdiXVbsGc6gDtpWY3k/s1600/p3.png" height="214" width="320" /></a><br />
All the wires are connected directly to a ribbon cable. I created a real power plug while I was at it.<br />
<br />
The LED circuit is pushed into the front part of the case and through some holes that I drilled. It is held in place by friction and a little tape.<br />
<br />
<br />
<br />
<br />
<br />
<br />
My latest Raspberry Pi creation is stacked with the modem and router with all their blinking lights.<br />
<br />
Now maybe it will not feel inadequate.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAX_qfJ4dr7RQv5nEeEOdv1QuwRm8actuSJBzvmXcO8PA6DCDjRg9TW4XDngP3lUizZilYxtXReBcydC1rrn-TZ3M0KrN5Jhqj5SL2ambUXEliG_QByKQi3F5kYzmOkTJ7Sxynh8KU_lk/s1600/p4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAX_qfJ4dr7RQv5nEeEOdv1QuwRm8actuSJBzvmXcO8PA6DCDjRg9TW4XDngP3lUizZilYxtXReBcydC1rrn-TZ3M0KrN5Jhqj5SL2ambUXEliG_QByKQi3F5kYzmOkTJ7Sxynh8KU_lk/s1600/p4.png" height="488" width="640" /></a></div>
<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com0tag:blogger.com,1999:blog-6238454757421809452.post-5332242670010132212014-12-07T14:36:00.000-05:002014-12-07T14:36:05.433-05:00Raspberry Pi Case From Wifi Router<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDyuplPYY04nRquGUUCcN0WuHXrJotJRdo5shMQBLDoMUm-gO5Io-kgIBvo5wsGd0ON9OjqOCFM3t2K4ccaiMAmR-Vw3jrFZTDd-nubbBtRyXH7g6TKcfc89Ix6bMpyXb0efH01l3EBbU/s1600/blog1.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDyuplPYY04nRquGUUCcN0WuHXrJotJRdo5shMQBLDoMUm-gO5Io-kgIBvo5wsGd0ON9OjqOCFM3t2K4ccaiMAmR-Vw3jrFZTDd-nubbBtRyXH7g6TKcfc89Ix6bMpyXb0efH01l3EBbU/s1600/blog1.jpg" height="200" width="200" /></a><br />
You have most likely seen one of these somewhere before. <br />
<br />
This case style is very common. If you happen to get your hands on one, you can make a great case for the Raspberry Pi. <br />
<br />
(Or, you can re-load the router firmware. See <a href="http://www.dd-wrt.com/">dd-wrt.org</a> for more information.)<br />
<br />
I had two in my huge pile of junk, so I though I'd have some fun. This was literally a ten minute project.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcHcZfANMCSk3h0s85wX5XYOSl-5b4Wpui9xEtAXaD2mBEIGGW2vn6GLnIzDreeVaHgoZd1rQqcA72HuSj5eGEuqpwQ90GR2bNB3mfliasmGg06ymR1G-Aa-YfVI1gYlIHflTelN0zF6Y/s1600/blog2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcHcZfANMCSk3h0s85wX5XYOSl-5b4Wpui9xEtAXaD2mBEIGGW2vn6GLnIzDreeVaHgoZd1rQqcA72HuSj5eGEuqpwQ90GR2bNB3mfliasmGg06ymR1G-Aa-YfVI1gYlIHflTelN0zF6Y/s1600/blog2.png" height="98" width="200" /></a><br />
The case pops apart easily, if you know the trick. Grab the blue front part and pull apart from the rear part. After that, the top and bottom will come apart. A couple of screws later and you have prime case material.<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWtZFZ32eHsBBrvbByemx52C6jzKrHgV65dNziCB5n7wLM3bFxnSKRtt_2bfLvbBdg_ftqW2LWqya-rkF5j338icKMehyljFInnSZLZ0GRYVbM_rBiXe-HZMJ8VVEgoxSGoJCsHHba4-8/s1600/blog3.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWtZFZ32eHsBBrvbByemx52C6jzKrHgV65dNziCB5n7wLM3bFxnSKRtt_2bfLvbBdg_ftqW2LWqya-rkF5j338icKMehyljFInnSZLZ0GRYVbM_rBiXe-HZMJ8VVEgoxSGoJCsHHba4-8/s1600/blog3.png" height="179" width="200" /></a><br />
I drilled two holes to mount the Pi and trimmed the rear opening just a little. It needs a better power connector.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiCmINrn2NuyNLpvR4rbvtka3DSsVlVPPIOrgTi0yHnP8A3BbVnrzkZOKwt7VmLA_4eWiJCHMhT0rx_PkCLCAUSdPYBX-4yluawpTLLMR2IJmAweE1k5zATxau7i-4MFKmMEXi_mQ-HS0/s1600/blog4.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiCmINrn2NuyNLpvR4rbvtka3DSsVlVPPIOrgTi0yHnP8A3BbVnrzkZOKwt7VmLA_4eWiJCHMhT0rx_PkCLCAUSdPYBX-4yluawpTLLMR2IJmAweE1k5zATxau7i-4MFKmMEXi_mQ-HS0/s1600/blog4.png" height="203" width="320" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPDGUJlHc5cI5CKu5AkLywoU2i2tyP-iXU_uQHUGaF2WTMRHkBzjJBdjWC0ck1DeOJb4Kfd1ZF3CfHWexrxtRDEcPELjh8DoHDNtz2V8cBdkv1Yz9SBMZxqsHhyZP91CAOvZE4L6oI0vY/s1600/blog5.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPDGUJlHc5cI5CKu5AkLywoU2i2tyP-iXU_uQHUGaF2WTMRHkBzjJBdjWC0ck1DeOJb4Kfd1ZF3CfHWexrxtRDEcPELjh8DoHDNtz2V8cBdkv1Yz9SBMZxqsHhyZP91CAOvZE4L6oI0vY/s1600/blog5.png" height="314" width="320" /></a><br />
<br />
<br />
One good thing about these cases, they stack very nicely. <br />
<br />
Now to search the pile of junk for a hard drive. There is enough room to add one in this case.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV_mEfWmmaRxKOrZWx8CMuei5pEOj1J5vCGmXpYHgYhYZzJX7ngFVDEQzANvp27Jc1k14PwSAOCBZtOhDNpdcH_WRfbt2jOtCtLcmBBSKoBQeAwt5oK8m027FIHHDgVp7zf8ce-12Yh9A/s1600/RPi_insideTRANS.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV_mEfWmmaRxKOrZWx8CMuei5pEOj1J5vCGmXpYHgYhYZzJX7ngFVDEQzANvp27Jc1k14PwSAOCBZtOhDNpdcH_WRfbt2jOtCtLcmBBSKoBQeAwt5oK8m027FIHHDgVp7zf8ce-12Yh9A/s1600/RPi_insideTRANS.gif" height="173" width="200" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Works Great!<br /><br />
<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com0tag:blogger.com,1999:blog-6238454757421809452.post-80563111338443774732014-11-16T19:29:00.001-05:002014-11-16T19:30:52.151-05:00Debouncing GPIO InputReading the state of a GPIO pin is very simple. There are several methods to do this. But what if you need to detect a very short pulse on a GPIO line or you need to respond very quickly to a state change without using a lot of the CPU to poll the state of the pin? This is exactly what interrupts are designed for. I will cover how to use interrupts in a future post. This post will show you how to deal with a common problem that must be addressed before interrupts will work correctly.<br />
<br />
When the contacts of a mechanical switch close, they will almost always bounce a little. This causes multiple spikes up and down on the connected line until the contact is firmly made. The result is a series of pulses when a single state change was expected. This is, for obvious reasons, called "bouncing" and must be corrected either with hardware or software.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkqYjc6FFvOB0ffxHdn-U7zB6XK6IgmlX_U9euRzGHVmSEpBZ5mrYxVy_i7LkwrNwsDDqZ_E8vj9RfvPfO6djNZgo-APLU5JTrFZhyTzTdwhtuo6sCfbOQQpjYQSgj_maE_Gvv6swNl2k/s1600/debouce-graph.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkqYjc6FFvOB0ffxHdn-U7zB6XK6IgmlX_U9euRzGHVmSEpBZ5mrYxVy_i7LkwrNwsDDqZ_E8vj9RfvPfO6djNZgo-APLU5JTrFZhyTzTdwhtuo6sCfbOQQpjYQSgj_maE_Gvv6swNl2k/s1600/debouce-graph.png" height="253" width="400" /></a>If that wasn't clear enough, maybe a picture will help. Imagine a push-button connected to a GPIO line. When the button is not pressed, a pull-up resistor holds the GPIO at 3.3 volts so that it reads a value of 1. When the button is pressed, the line is connected to ground and the GPIO will read 0. But on closer inspection, something else really happens. As this graph shows, the bouncing of the voltage level causes spurious state changes to the GPIO input. If you use an interrupt to increment a counter when the state changes on the GPIO, then a single button press can result in the counter incrementing two, three, or more times when the programmer is expecting only a single increment.<br />
<br />
This can be dealt with in software, but that method tends to be unreliable in many instances. It is much better to correct for the bouncing using a simple hardware circuit. This is called debouncing and one simple solution is shown below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiee3GDve4fs-Ki3h8hchL6Wb7kBYSStGV5ntNjuxwBc5iyQT0sfrgoaRZaHvmZe9yu1uopfE8XiYPPDUvuIbuM_VqepyR-HRnuD6CjilN__4lQeO7tDi2Ud9qkNCqqsoEBMH2DvL5hypA/s1600/debouce-circuit.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiee3GDve4fs-Ki3h8hchL6Wb7kBYSStGV5ntNjuxwBc5iyQT0sfrgoaRZaHvmZe9yu1uopfE8XiYPPDUvuIbuM_VqepyR-HRnuD6CjilN__4lQeO7tDi2Ud9qkNCqqsoEBMH2DvL5hypA/s1600/debouce-circuit.png" height="272" width="320" /></a></div>
By connecting a capacitor as shown here, the result is a "smoothing" of the voltage curve. Before the button is pressed, the capacitor is fully charged and the GPIO will read 1. When the button is pressed, the capacitor will start draining through R2 at a rate determined by the size of the C1 and the R2. The voltage on the GPIO pin will smoothly curve down from 3.3V to 0V and the GPIO will sense a single state change.<br />
<br />
The values for C1 and R2 will determine how quickly the state changes. If they are too small, then there could still be some bouncing. If they are too large, then the circuit may respond too slowly for the application needed. This could result in state changes being missed. You may need to experiment to find the proper values for a specific application. The values shown in this circuit are a good place to start.<br />
<br />
A digital circuit that is also commonly used for debouncing is called the set/reset latch and can be constructed from two nand gates. To learn more about this option and everything else you might want to know about debouncing, read this paper. <a href="http://www.eng.utah.edu/~cs5780/debouncing.pdf">A Guide to Debouncing</a><br />
<br />
Now that you input is properly debounced, you can go on to using it to reliably drive an interrupt.<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com4tag:blogger.com,1999:blog-6238454757421809452.post-26147495602875457172014-10-29T12:27:00.000-04:002014-10-29T12:27:41.433-04:00Improved Home Brewing ControllerThis post is an update to my <a href="http://raspberrypihobbyist.blogspot.com/2014/03/automated-home-brewing.html" target="_blank">Automated Home Brewing</a> post. See that post for more details on the project. After adding some new features haphazardly, I had an ugly conglomeration of old and new parts. It worked, but it wasn't pretty, and I sure didn't want to show it on this blog. So, I decided to build a whole new interface and include the new items:<br />
<ul>
<li>thermocouple interface for flame detection</li>
<li>relay control for refrigerator</li>
<li>relay control for heater (these two are used for controlling lagering temperature during fermentation)</li>
<li>digital input for counting the bubble rate in the airlock during fermentation.</li>
<li>battery level monitor, since I usually run this on a small 12V battery</li>
</ul>
<div>
I also kept all the original controls:</div>
<div>
<ul>
<li>relay for propane valve</li>
<li>relay for igniter</li>
<li>1-wire bus for multiple temperature inputs</li>
<li>relay for circulation pump</li>
</ul>
<div>
The item that I struggled with the most was how to make a reliable flame sensor. This is covered in the <a href="http://raspberrypihobbyist.blogspot.com/2014/04/flame-sensor-update.html" target="_blank">Flame Sensor Update</a> post. Note - the drawing for the amplifier circuit in that post has the resistor values reversed. Here is the corrected drawing.</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxJ5R_AiaYGMApDZJet9RIZFXb0MWDD9x8_ZG4uURWPXnNwfoFsV2gmuoR2D1Hw4qwS1TiEiiHGUwHv4UxfjVZ7qECNmxkh4q70-u9IZd8-ng-iyEIADxm9UomdiUJXlk1ERcl9DeBohw/s1600/Thermocouple-Amp.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxJ5R_AiaYGMApDZJet9RIZFXb0MWDD9x8_ZG4uURWPXnNwfoFsV2gmuoR2D1Hw4qwS1TiEiiHGUwHv4UxfjVZ7qECNmxkh4q70-u9IZd8-ng-iyEIADxm9UomdiUJXlk1ERcl9DeBohw/s1600/Thermocouple-Amp.png" height="299" width="320" /></a></div>
<div>
<br /></div>
The gain formula for a LM358 non-inverting circuit is<br />
<br />
<b>gain = 1 + R2/R1</b><br />
<br />
In this case, R1 = 1K and R2 = 200K, resulting in a gain of 201. This means that a thermocouple output of 5mv will produce an output of just over 1V. Using a gain of 500 would allow for better resolution of the temperature, but 200 is adequate for this purpose. I don't care about the actual temperature. I just need to see if the value is increasing to verify that the flame actually lighted.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWSn0tohMLZyPeTp8BQwvWuTL596GzLB9kcrNpNSxYids0J5xoZ36xeigx9Cr91kFgVjNcvbmRLJbHmE3X6OdkTP5FHFrxWesXlmDufRvQgKmF8VS6PnMJLNy5Qz070BburBEfGAPH0OM/s1600/DSC_0002.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWSn0tohMLZyPeTp8BQwvWuTL596GzLB9kcrNpNSxYids0J5xoZ36xeigx9Cr91kFgVjNcvbmRLJbHmE3X6OdkTP5FHFrxWesXlmDufRvQgKmF8VS6PnMJLNy5Qz070BburBEfGAPH0OM/s1600/DSC_0002.jpg" height="244" width="320" /></a><br />
<br />
<br />
<br />
I decided to build the interface on a circuit board that would plug directly into the GPIO pins on the Raspberry Pi and mount it with a Pi permanently in a project box. Here is the completed circuit board, in its enclosure, installed on the Raspberry Pi<br />
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf3IjUoSA7vJTkthOe1BQFUS3Pgkv-FUPHAcusUDQ0JAp40timlLm007-4FQ59cMyow-WqV8of20BGAQwtSRLEmIYhVw_OQL3Mjsgf4ZWio2LQN0HNSDX8IUZ0q-joYbEMZyX6xCMo6WU/s1600/DSC_0004.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgf3IjUoSA7vJTkthOe1BQFUS3Pgkv-FUPHAcusUDQ0JAp40timlLm007-4FQ59cMyow-WqV8of20BGAQwtSRLEmIYhVw_OQL3Mjsgf4ZWio2LQN0HNSDX8IUZ0q-joYbEMZyX6xCMo6WU/s1600/DSC_0004.png" height="302" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
Here is the project box with the Pi mounted inside. There are holes cut for the USB, network, and HDMI connections. I like this arrangement a lot and will use it again in the future.<br />
<br />
<br />
<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxBQXxlrWmdzWbf4Vzm-qaws_Q_Q-BuuBlw0nPA3wVqxNvGbmhZMVxRMtOnHFvR1BxKPa94N_jAIccpDCAUGnscMOk6HAxTlBxyfPuMqQPJpTPHxMCUwWpek1KH-0VDy1I8SQ-VOgxhrA/s1600/DSC_0005.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxBQXxlrWmdzWbf4Vzm-qaws_Q_Q-BuuBlw0nPA3wVqxNvGbmhZMVxRMtOnHFvR1BxKPa94N_jAIccpDCAUGnscMOk6HAxTlBxyfPuMqQPJpTPHxMCUwWpek1KH-0VDy1I8SQ-VOgxhrA/s1600/DSC_0005.jpg" height="209" width="320" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
Finally, this is the completed system with all the connectors labelled.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
The "bubble detector" input was a last minute addition. I haven't actually built the detector yet but the design is straight forward. It will use an infrared LED and detector (sometimes called an IR gate) to see when a section of the airlock changes from water to air. Water is mostly opaque to IR light. <br />
<br />
The pulses from the bubble detector will be very short and difficult to accurately count using a simple polling loop. I expect that it will need to be done using GPIO interrupts. I will post the code when I get that working.<br />
<br />
Monitoring the "bubble rate" won't really produce any useful numeric data. It is only good for determining when the fermentation has completed. This is important since fermentation can stop early for various reasons and steps must be taken to correct the problem.<br />
<br />
Finally, a warning: <span style="color: red;"><b>Working with flammable gas and boiling liquids can be hazardous. I take no responsibility for your use of the advice provided in this post.</b></span> <br />
BE CAREFUL! And drink responsibly.<br />
<br />
<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com2tag:blogger.com,1999:blog-6238454757421809452.post-89547643965279442172014-04-28T21:33:00.000-04:002014-04-28T21:33:36.442-04:00Flame Sensor UpdateThis is a follow up to the post on <a href="http://raspberrypihobbyist.blogspot.com/2014/03/automated-home-brewing.html" target="_blank">Automated Home Brewing</a>. There were several good ideas in the comments to that post about how to create a flame sensor. Some require an analog input, which I describe in <a href="http://raspberrypihobbyist.blogspot.com/2014/04/schematic-for-analog-interface.html" target="_blank">this post</a>. I have experimented now with a few methods for detecting a flame and here is what I found.<br />
<br />
<h3>
Plasma Conductance</h3>
Cool Fact - flame is a plasma and will conduct current. I tried using two wires stuck into the flame. The flame has a fair amount of resistance. One of the wires was connected to 5V. The other was connected to a voltmeter. There were dozens of mV present when the flame was on and zero when it was not. <br />
I think this could be used with an analog input as a flame sensor.<br />
<br />
<h4>
</h4>
<h3>
Thermocouple </h3>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4J4Gzrzs9ZnPfQmv6M8geFGLEf2ibqbH-vSJbEcjVIkkhFLJv9P73xmbSnz5CEB1bQ9vI65pxEqZUlITeSwRRkCzOUNfk5KDYpe-k9sZdeOvVl7fPCATQ8KfnLpKkKWfV09-uzUtAvhQ/s1600/Thermocouple+Type-K+-+5cm+Probe_A.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4J4Gzrzs9ZnPfQmv6M8geFGLEf2ibqbH-vSJbEcjVIkkhFLJv9P73xmbSnz5CEB1bQ9vI65pxEqZUlITeSwRRkCzOUNfk5KDYpe-k9sZdeOvVl7fPCATQ8KfnLpKkKWfV09-uzUtAvhQ/s1600/Thermocouple+Type-K+-+5cm+Probe_A.jpg" height="144" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Thermocouple</td></tr>
</tbody></table>
I got a type K thermocouple and tested that directly with a voltmeter. It only show a couple of mV with a flame on the tip. I added a simple 100X amplification circuit and connected that to the analog input. Now I see a range around 300-400mV and see a clear increase when the flame is on it. One problem I saw is that the sensor has a fair amount of mass, mostly stainless steel. Once it heats up, it takes a while for it to cool off. As long as there is a distinct increase when the flame comes on, this could also be used for the flame sensor.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiICo1VbtokKiiSs0HDdSNTjTGX3vdWJqa0UuM80ct2yLOMSeHFx090dM9t4kMccc8Wm5Jig_cRglMLRIxIwuS1sCQrOKgsr6Y6X4_6WoCCsQmgMDBFiDYcJ3n60PEzYczghMrV0CNQDk4/s1600/Amplifier.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiICo1VbtokKiiSs0HDdSNTjTGX3vdWJqa0UuM80ct2yLOMSeHFx090dM9t4kMccc8Wm5Jig_cRglMLRIxIwuS1sCQrOKgsr6Y6X4_6WoCCsQmgMDBFiDYcJ3n60PEzYczghMrV0CNQDk4/s1600/Amplifier.png" height="210" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">100X Amplification Circuit for Thermocouple</td></tr>
</tbody></table>
<br /><table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZFJBYUnywFysegFcWZidzgZWFyQUaqP2D6BBsZ5ikOT6N_jkk62SwKUNpjeKNtz_f4C8iJte5hIsEwNNHjFN3LK6jDBz9ChvbSpg-5dPAud9upOZ3b3MgLrZroQz10WTlcPLHd1J5c3k/s1600/Arduino_flame_sensor_digital_sensor.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZFJBYUnywFysegFcWZidzgZWFyQUaqP2D6BBsZ5ikOT6N_jkk62SwKUNpjeKNtz_f4C8iJte5hIsEwNNHjFN3LK6jDBz9ChvbSpg-5dPAud9upOZ3b3MgLrZroQz10WTlcPLHd1J5c3k/s1600/Arduino_flame_sensor_digital_sensor.jpg" height="200" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Digital IR Flame Detector</td></tr>
</tbody></table>
<h3>
IR Flame Detector</h3>
Sensors are available that detect the IR signature of a flame. Most of these provide analog output only, but I found some that also include a digital output. This is provided by a built in level compare circuit with an adjustable level. Because this method is so simple to interface with, this is what I decided to use. One big problem quickly became apparent - the sensor is triggered by incandescent lights and sunlight. It worked fine under florescent lights.<br />
<br />
<br />
<br />
<br />
I was successful in using this configuration for brewing. The IR sensor works, but has the false trigger problem. It works for me but won't work in many environments. My plan is to rebuild the brewing interface with analog input capability and try one of the other methods. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmBpm3GMgeo6mQTzlCb-P5geFmHFxxNtu0DIrs_ulTzK92aINAlEOaaa0Z-twITf9b5aAtNxMIdhh1k1K9aWa40L-z9dB1rDPe5rdAASfgHU9lfs9xkdmt5g8yaBuENj8AAoY4E6tiouQ/s1600/FlameSensor.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmBpm3GMgeo6mQTzlCb-P5geFmHFxxNtu0DIrs_ulTzK92aINAlEOaaa0Z-twITf9b5aAtNxMIdhh1k1K9aWa40L-z9dB1rDPe5rdAASfgHU9lfs9xkdmt5g8yaBuENj8AAoY4E6tiouQ/s1600/FlameSensor.png" height="320" width="315" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">IR sensor mounted on a small block of wood and placed under the flame.</td></tr>
</tbody></table>
<br />
<br />
<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com6tag:blogger.com,1999:blog-6238454757421809452.post-60925222608478394572014-04-25T23:47:00.002-04:002014-04-25T23:47:31.510-04:00Interface to the Internet of Things with SkyNetThe Internet of Things (IoT) refers to the many servers that store data uploaded from various devices (things) connected to the Internet, which can range from weather stations, to home appliances, or a farm animal with a biochip transponder. Even <a href="https://www.youtube.com/watch?v=CCr17B1gSPw" target="_blank">dancing robotic quad choppers</a>. <br />
<br />
There are many services that provide IoT support. After experimenting with some, I settled on the SkyNet.im IoT server. It provides several simple ways to allow machine to machine communications, including MQTT, REST, and WebSockets. There are Python and JavaScript libraries to support it. The API for SkyNet is fairly simple, as is using the REST protocol. With the<b> <span style="font-family: Courier New, Courier, monospace;">curl</span></b> utility, you can interface to SkyNet from shell commands.<br />
<br />
First you need to install the curl program and since I will also be calling this from a C program, I also need the development support.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><b>sudo apt-get install curl libcurl4-gnutls-dev</b></span><br />
<br />
To create a new device on Skynet, issue the following command (changing the parameters as you see fit)<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><b>curl -X POST -d "type=raspberry-pi-example&myvariable=12345" http://skynet.im/devices</b></span><br />
<br />
SkyNet returns a UUID and a security token. Save this info. The device id is used to identify the new device and the security token allows a little security so that only someone with the token can update the data for this device. If you really need to maintain security for the device, be sure to always update it using HTTPS. If you use HTTP, then the session is not encrypted and someone could intercept the token and use it themselves. Also, be aware that anyone can read your data.<br />
<br />
To update the data for the device, issue this command. (All one line.)<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><b>curl -X PUT -d "token=PUT-YOUR-TOKEN-HERE&myvariable=5678online=true" http://skynet.im/devices/PUT-YOUR-UUID-HERE</b></span><br />
<br />
To view the data for a device, issue this command.<br />
<br />
<b><span style="font-family: Courier New, Courier, monospace;">curl –X GET http://skynet.im/devices/PUT-YOUR-UUID-HERE</span></b><br />
<br />
The function listed below provides a simple interface to SkyNet, in C, using libcurl.<br />
<br />
<br />
<script src="https://gist.github.com/tedhale/10516841.js"></script>
<br />
<div>
<br /></div>
Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com6tag:blogger.com,1999:blog-6238454757421809452.post-14600324270470887172014-04-04T23:36:00.002-04:002014-04-04T23:36:32.604-04:00Schematic for Analog InterfaceA commenter asked for the schematic of the analog interface I made using an MPC3008. I seldom include schematics with my posts for several reasons. I don’t expect anyone to duplicate exactly what I have done, so if I post anything, it is just partial drawings of the most important concepts. But the biggest reason is that I almost never create true schematics and I am too busy to do it just for the blog. Something that I do frequently do is a simple drawing that helps me lay out the components onto the perf board. Then I use that as my guide when I build the device. These are seldom complete enough to be useful to others. In this case, however, the entire circuit is shown.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij940FG7L7lNq1qgCdN76dumvwD2UPSO-RkOA6xd-RGIMcoeBjusJm5qBUs-K1j8z-lPDA_2P3GsG9dxIOsfT66YqCT8M3f-AnF7nHawqiiRZjVXw_ZdzwLUKr45QJSdv6q0jcNsLv_eE/s1600/AnalogInterface.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij940FG7L7lNq1qgCdN76dumvwD2UPSO-RkOA6xd-RGIMcoeBjusJm5qBUs-K1j8z-lPDA_2P3GsG9dxIOsfT66YqCT8M3f-AnF7nHawqiiRZjVXw_ZdzwLUKr45QJSdv6q0jcNsLv_eE/s1600/AnalogInterface.png" height="200" width="165" /></a><br />
<br />
This is what I created for the analog interface. The 7-pin header connects to my main circuit board where I have two SPI ports – one with CE0 connected and the other with CE1. The 3-pin header allows me to select the reference voltage for the MCP3008. The blocks along the bottom are screw terminals. See the post <a href="http://raspberrypihobbyist.blogspot.com/2012/12/analog-interface.html" target="_blank">Analog Interface</a> for a picture of how this looked when built.<br />
<br />
I will probably be pulling this old board out again to experiment with a thermocouple that I just received. I need it for the flame detection on my <a href="http://raspberrypihobbyist.blogspot.com/2014/03/automated-home-brewing.html" target="_blank">Home Brewing Automation</a> setup.<br />
<br />Ted B Halehttp://www.blogger.com/profile/16887056993667506084noreply@blogger.com0