{"id":264,"date":"2014-08-29T20:25:32","date_gmt":"2014-08-29T20:25:32","guid":{"rendered":"http:\/\/blog.cup-of-joe.me\/?p=264"},"modified":"2018-12-12T19:41:13","modified_gmt":"2018-12-12T19:41:13","slug":"i2c-sensors-using-adafruit-trinket","status":"publish","type":"post","link":"http:\/\/blog.cup-of-joe.me\/?p=264","title":{"rendered":"I2C sensors using Adafruit Trinket"},"content":{"rendered":"<p>I finally completed migrating the weather sensors for the weather station that is at my father-in-law&#8217;s farm.  I had issues with the rain gauge not working too well with the pi directly, so I decided to use an Adafruit Trinket to capture the values of the sensors and send them to the pi for tracking.  The communication between the two is accomplished using I2C.<\/p>\n<p><a href=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image6.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image6-225x300.jpg\" alt=\"image\" width=\"225\" height=\"300\" class=\"alignnone size-medium wp-image-263\" srcset=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image6-225x300.jpg 225w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image6-768x1024.jpg 768w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image6.jpg 1536w\" sizes=\"(max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p>Here&#8217;s the completed mast with sensors attached.  (This is actually a pic of it at my house for testing)  What you&#8217;ll need for this is 1 of each of an <a href=\"http:\/\/blog.cup-of-joe.me\/?p=232\">anemometer<\/a>, <a href=\"http:\/\/blog.cup-of-joe.me\/?p=245\">wind vane<\/a> &#038; <a href=\"http:\/\/blog.cup-of-joe.me\/?p=153\">rain gauge<\/a>.  It works with the sensors I built, but I&#8217;m sure you could incorporate it to use any sensors you have as well.<\/p>\n<p>I&#8217;ve used PVC to build all my sensors as it&#8217;s easy to connect together.  In my anemometer &#038; wind vane posts I have used certain PVC pieces to allow for connection to my mast.  For the rain gauge, it&#8217;s a little different.  I used a piece of cedar fence board to secure the sensor, then some u-bolts to attach the board to a 1 inch pvc pipe, plugged one end and drilled a hole for the wire to run through.  <\/p>\n<p>For the rest of the top part of the mast I use a 1&#8243; T-connector at the top with about 8 or so inches of 1&#8243; pipe to connect the anemometer &#038; wind vane. I run the wires down through the pipes.  I then use a small piece of 1 inch pipe (about 3 or so inches) to connect another T-connector for the anemometer.  I then use another portion of 3 or so inches of 1&#8243; pvc pipe to connect to the lower portion.  (Sorry, but I don&#8217;t have any pics of this&#8230;)<\/p>\n<p>The lower mast is where the trinket comes in&#8230;I connect all the sensor wires to a single cat 5 cable to connect to trinket and then another wire for the I2C communication.  The idea is to house the trinket in some 3\/4&#8243; pipe that is waterproofed and have it sit inside some 1 1\/2&#8243; pipe.  (You can see this bulge in the pic above)  I use some connectors to move from 1&#8243; to 1 1\/2&#8243; pipe.  Then a portion of 1 1\/2&#8243; pipe (I think it&#8217;s 12 inches long) and then connect it back to another 1&#8243; piece of pipe to mount it.<\/p>\n<p>Before wiring up your trinket, make sure you upload the code to it.  Here is what I use which tracks the sensors and sends the data via I2C:<\/p>\n<blockquote><p>\n#include avr\/interrupt.h<br \/>\n#include TinyWireS.h<\/p>\n<p>\/\/ setup cbi &#038; sbi for interrupts<br \/>\n#ifndef cbi<br \/>\n#define cbi(sfr, bit) (_SFR_BYTE(sfr) &#038;= ~_BV(bit))<br \/>\n#endif<br \/>\n#ifndef sbi<br \/>\n#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))<br \/>\n#endif<\/p>\n<p>\/\/Define address of device<br \/>\n#define I2C_SLAVE_ADDRESS 0x04<\/p>\n<p>\/\/ Set up registers to hold data to send<br \/>\nvolatile uint8_t reg[] =<br \/>\n{<\/p>\n<p>    0xDE,<br \/>\n    0xAD,<br \/>\n    0xBE,<br \/>\n    0xEF,<br \/>\n    0xEE,<br \/>\n    0xED<br \/>\n};<\/p>\n<p>\/\/ Set up variables used<\/p>\n<p>volatile byte reg_position;  \/\/ keep track of reg position sent from master<br \/>\nvolatile int rainGauge = 0;  \/\/ keep track of interrupts from rain gauge<br \/>\nvolatile int windSpeed = 0;  \/\/ keep track of interrupts from anemometer<br \/>\nvolatile int windDirection = 0;  \/\/ keep track of value of wind direction sensor<br \/>\nvolatile int windSpeedSend = 0;  \/\/ used to send 10 second interrupt value to pi<br \/>\nlong debouncing_time_rain = 300; \/\/Debouncing Time in Milliseconds for rain gauge<br \/>\nvolatile unsigned long last_micros_rain;  \/\/ micros since last rain gauge interrput<br \/>\nlong debouncing_time_wind = 100; \/\/Debouncing Time in Milliseconds for anemometer<br \/>\nvolatile unsigned long last_micros_wind; \/\/ micros since last anemometer interrupt<br \/>\nvolatile int val1 = 0;  \/\/ pin 1 value at interrupt<br \/>\nvolatile int val2 = 0;  \/\/ pin 4 value at interrupt<\/p>\n<p>\/\/ Function to send data when it is requested.  Sends 2 register positions<br \/>\n\/\/ for each request<br \/>\nvoid onRequest()<br \/>\n{  <\/p>\n<p>     \/\/ Load all values into registers.  (even though only 2 will go to master)<br \/>\n    reg[0] = lowByte(windDirection);<br \/>\n    reg[1] = highByte(windDirection);<br \/>\n    reg[2] = lowByte(windSpeedSend);<br \/>\n    reg[3] = highByte(windSpeedSend);<br \/>\n    reg[4] = lowByte(rainGauge);<br \/>\n    reg[5] = highByte(rainGauge);<\/p>\n<p>    \/\/ send 2 reg positions to master<br \/>\n    TinyWireS.send(reg[reg_position]);<br \/>\n    reg_position++;<\/p>\n<p>}<br \/>\n\/\/ Function to set which register positions you wish to receive<br \/>\nvoid receiveEvent(uint8_t howMany)<br \/>\n{<br \/>\n  reg_position = TinyWireS.receive();<\/p>\n<p>  \/\/ if requested position is 7, reset rain gauge variable.  Will be sent at midnight each day<br \/>\n  if(reg_position == 7) {<br \/>\n    rainGauge = 0;<br \/>\n}<\/p>\n<p>}<\/p>\n<p>\/\/  Setup for connection<br \/>\nvoid setup()<br \/>\n{<br \/>\n    TinyWireS.begin(I2C_SLAVE_ADDRESS);<br \/>\n    TinyWireS.onReceive(receiveEvent);<br \/>\n    TinyWireS.onRequest(onRequest);<br \/>\n    pinMode(1,INPUT);<br \/>\n    pinMode(4,INPUT);<\/p>\n<p>    sbi(GIMSK,PCIE); \/\/ Turn on Pin Change interrupt<br \/>\n    sbi(PCMSK,PCINT1); \/\/ Which pins are affected by the interrupt.  Turn on Pin 1<br \/>\n    sbi(PCMSK,PCINT4); \/\/ Which pins are affected by the interrupt.  Turn on Pin 2<br \/>\n}<\/p>\n<p>void loop()<br \/>\n{<\/p>\n<p>   \/\/ anemometer counts interrupts for 10 second interval.  This is sent to master for calculation<br \/>\n    windSpeed = 0;<br \/>\n    tws_delay(10000);<br \/>\n    windSpeedSend = windSpeed;<\/p>\n<p>    \/\/ read pin 3 analog value of wind direction sensor<br \/>\n    windDirection = analogRead(3);<\/p>\n<p>  \/\/ Check for connection to be stopped.<br \/>\n    TinyWireS_stop_check();<br \/>\n}<\/p>\n<p>\/\/ debounce rain gauge.  make sure new reading is greater than old reading + debounce rain micros<br \/>\nvoid debounceRainGauge() {<br \/>\n  if((long)(micros() &#8211; last_micros_rain) >= debouncing_time_rain * 1000) {<br \/>\n    rainGaugeFunc();<br \/>\n    last_micros_rain = micros();<br \/>\n  }<br \/>\n}<\/p>\n<p>\/\/ debounce anemometer.  make sure new reading is greater than old reading + debounce wind micros<br \/>\nvoid debounceWindSpeed() {<br \/>\n  if((long)(micros() &#8211; last_micros_wind) >= debouncing_time_wind * 1000) {<br \/>\n    windSpeedFunc();<br \/>\n    last_micros_wind = micros();<br \/>\n  }<br \/>\n}<\/p>\n<p>\/\/ function to increment rain gauge count<br \/>\nvoid rainGaugeFunc() {<br \/>\n    rainGauge = rainGauge + 1;<br \/>\n}  \/\/ end of rainGauge<\/p>\n<p>\/\/ function to increment anemometer count<br \/>\nvoid windSpeedFunc() {<br \/>\n    windSpeed = windSpeed + 1;<br \/>\n}  \/\/ end of rainGauge<\/p>\n<p>\/\/ interrupt service routine.  What to do when an interrupt occurs as all pin change interrupts<br \/>\n\/\/ on ATTiny85 trigger PCINT0 vector.<br \/>\nISR(PCINT0_vect) {<br \/>\n  \/\/ get value of pin 1 @ interrupt<br \/>\n  val1 = digitalRead(1);<br \/>\n  \/\/ get value of pin 4 @ interrupt<br \/>\n  val2 = digitalRead(4);<\/p>\n<p>  \/\/ if pin 1 is HIGH (caused the interrupt), proceed with rain gauge increment functions<br \/>\n  if (val1 == HIGH) {<br \/>\n    debounceRainGauge();<br \/>\n  }<\/p>\n<p>  \/\/ if pin 4 is HIGH (caused the interrupt), proceed with wind speed (anemomether) increment function<br \/>\n  if (val2 == HIGH) {<br \/>\n    debounceWindSpeed();<br \/>\n  }<\/p>\n<p>}<\/p>\n<\/blockquote>\n<p>So, now to the wiring:<br \/>\n<a href=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image7.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image7-225x300.jpg\" alt=\"image\" width=\"225\" height=\"300\" class=\"alignnone size-medium wp-image-269\" srcset=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image7-225x300.jpg 225w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image7-768x1024.jpg 768w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image7.jpg 1536w\" sizes=\"(max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p>Here is the wiring diagram I drew out that shows how everything is connected.  When connecting, make sure you use solder and shrink tube  to protect the joints. <\/p>\n<p><a href=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image8.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image8-225x300.jpg\" alt=\"image\" width=\"225\" height=\"300\" class=\"alignnone size-medium wp-image-273\" srcset=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image8-225x300.jpg 225w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image8-768x1024.jpg 768w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image8.jpg 1536w\" sizes=\"(max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p>After all the wires are connected, drill a hole in a 3\/4&#8243; pvc plug and push the wire through that hole prior to connecting to the trinket.  You may want to run it through a piece of 3\/4&#8243; pipe as well (about 8 or so inches).<\/p>\n<p>All 3 sensors will need 1 wire connected to the +3v on the sensor.  I managed to get all 3 of the cat 5 wires into the hole on the trinket.  The read wires will need to go different pins.  For the anemometer and rain gauge, you will need to connect a 10k resistor to ground to pull the pin to ground.  The rain gauge read wire should go to pin 1 and the read side of the anemometer should go to pin 4.  The read wire for the wind vane should go to pin 3.  Connecting all the ground wires was fun.  What I did was run 1 wire out of the trinket and connected all the ground wires to it and put shrink tube over all of them.  (You can see it in the pics below.)<\/p>\n<p><a href=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image9.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image9-225x300.jpg\" alt=\"image\" width=\"225\" height=\"300\" class=\"alignnone size-medium wp-image-274\" srcset=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image9-225x300.jpg 225w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image9-768x1024.jpg 768w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image9.jpg 1536w\" sizes=\"(max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image10.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image10-225x300.jpg\" alt=\"image\" width=\"225\" height=\"300\" class=\"alignnone size-medium wp-image-275\" srcset=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image10-225x300.jpg 225w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image10-768x1024.jpg 768w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image10.jpg 1536w\" sizes=\"(max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p>I didn&#8217;t take a lot of single step pics on this and I apologize.  You can see the connections for the I2C wire as well in these pics.  The last part is connecting the wires for the I2C communications.  You&#8217;ll want to put the wire through hole in another 3\/4&#8243; pvc plug before you connect them to the trinket to allow for waterproofing.  Connect the +v to the battery pin (I use 5 volts out of my raspberry pi to power, but you can power it any way you want.  I used a 3 volt trinket for this setup).  Ground to your ground wire, SDA to pin 0 and SCL to pin 2.  Once this is done, slide it all into the 3\/4&#8243; pvc and plug the other side.  It should look like this:<\/p>\n<p><a href=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image12.jpg\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image12-225x300.jpg\" alt=\"image\" width=\"225\" height=\"300\" class=\"alignnone size-medium wp-image-277\" srcset=\"http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image12-225x300.jpg 225w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image12-768x1024.jpg 768w, http:\/\/blog.cup-of-joe.me\/wp-content\/uploads\/2014\/08\/image12.jpg 1536w\" sizes=\"(max-width: 225px) 100vw, 225px\" \/><\/a><\/p>\n<p>Place some hot glue on each plug where the wires go in to keep the water out, then shove this into the 1 1\/2&#8243; pvc pipe and then connect the rest of your mast. <\/p>\n<p>This is really set up to communicate with a pi, but I&#8217;m pretty sure it would work with an Arduino as well.  In the code you basically send the trinket a number and it will give you the response.  Sending 0 will give you the wind direction reading, 2 will give you the wind speed reading and 4 will give you the rain gauge reading.  Sending it 7 will cause the rain gauge count to reset.  Here&#8217;s a quick bit of code you can use for the pi:<\/p>\n<p><code><br \/>\n#!\/usr\/bin\/python<br \/>\n# Import needed libraries<br \/>\nimport smbus<br \/>\nimport time<\/p>\n<p># Set I2C address of device you wish to access<br \/>\nDEV_ADDR = 0x04<\/p>\n<p>bus = smbus.SMBus(1)<\/p>\n<p>#  Request values from device.  Number is start register position.<br \/>\nwhile True:<br \/>\n        print 'Testing for connection...'<br \/>\n        while True:<br \/>\n                try:<br \/>\n                        wind_dir_read = bus1.read_word_data(DEV_ADDR, 0)<br \/>\n                        wind_count = bus1.read_word_data(DEV_ADDR, 2)<br \/>\n                        rain_count = bus1.read_word_data(DEV_ADDR, 4)<br \/>\n                        break<br \/>\n                except IOError:<br \/>\n                        print 'No connection...'<br \/>\n                        time.sleep(5)<br \/>\n        #break<br \/>\n        if wind_dir_read < 1030:\n                break\n        else:\n                print 'Value too high.'\n                time.sleep(5)\n\n#  Use this to reset a variable:\n#d_val = bus.read_word_data(DEV_ADDR, 7)\n\n<\/code><\/p>\n<p>It doesn't seem that wordpress knows how to deal with indents in it's code sections, so make sure you indent it properly.  Sometimes the trinket can give you some funny business which I've handled via the error trapping above.  If you keep this bit of code you shouldn't run into any problems.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I finally completed migrating the weather sensors for the weather station that is at my father-in-law&#8217;s farm. I had issues with the rain gauge not working too well with the pi directly, so I decided to use an Adafruit Trinket to capture the values of the sensors and send them to the pi for tracking. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,2,7],"tags":[],"_links":{"self":[{"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=\/wp\/v2\/posts\/264"}],"collection":[{"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=264"}],"version-history":[{"count":17,"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=\/wp\/v2\/posts\/264\/revisions"}],"predecessor-version":[{"id":291,"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=\/wp\/v2\/posts\/264\/revisions\/291"}],"wp:attachment":[{"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=264"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.cup-of-joe.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}