{"id":2333,"date":"2012-04-05T16:06:14","date_gmt":"2012-04-05T21:06:14","guid":{"rendered":"http:\/\/www.plastibots.com\/?p=2333"},"modified":"2017-04-26T11:21:16","modified_gmt":"2017-04-26T16:21:16","slug":"arduino-temperature-humidity-sensor","status":"publish","type":"post","link":"https:\/\/www.plastibots.com\/index.php\/2012\/04\/05\/arduino-temperature-humidity-sensor\/","title":{"rendered":"Arduino Temperature \/ Humidity Sensor"},"content":{"rendered":"<p>The projects I do tend to fall in one of two buckets &#8211; either proof-of-concept (so I can learn new stuff) or items that have some sort of functional use. \u00a0<img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-2337\" title=\"HuTmp1b\" src=\"http:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp1b.jpg\" alt=\"\" width=\"300\" height=\"131\" \/> The need for this project came about when my wife was prodding me about the humidity in the house and whether our humidifier was doing it&#8217;s job correctly. \u00a0Most people would just go out and buy a temp \/ humidity sensor and be done with it. \u00a0However, if you have a look around here, you will see that I don&#8217;t fit that mold. \u00a0Instead, I decided to build an accurate temp \/ humidity sensor with a Sensiron SHT11 to read the values, a RBBB Arduino kit to process everything and an Adafruit 128&#215;32 OLED to display the results &#8211; all wrapped up in&#8230; LEGO! \u00a0 Read on for more&#8230;<\/p>\n<p><!--more--><\/p>\n<p>Admittedly, I would not normally spend the money required to outright build this gizmo (approx $95 incl shipping for all parts). \u00a0Instead, I was able to acquire the parts for a fraction of this price. \u00a0 As a result, the purpose of this build is twofold. 1) Create a sensor that can be used in my house on an ongoing basis; 2) Review the parts to provide insight for those considering using them for similar or other projects.<\/p>\n<p>Parts:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.adafruit.com\/products\/661\" target=\"_blank\">Adafruit Monochrome 128&#215;32 OLED Display<\/a> &#8211; ($17.50)<\/li>\n<li><a href=\"http:\/\/canada.newark.com\/sensirion\/sht11\/humidity-sensor\/dp\/69C4848?Ntt=sht11\" target=\"_blank\">Newark Sensiron SHT11 Humidity \/ Temperature Sensor<\/a> ($29.xx)<\/li>\n<li><a href=\"https:\/\/moderndevice.com\/?s=rbbb\" target=\"_blank\">Modern Device RBBB Arduino Kit<\/a> (3.3v) \u00a0($13.00)<\/li>\n<li><a href=\"https:\/\/www.adafruit.com\/products\/504\" target=\"_blank\">Adafruit Through Hole 5-Way Navigation Switch<\/a> ($2.95)<\/li>\n<li><a href=\"http:\/\/www.dipmicro.com\/store\/WIRE-K30BLK\" target=\"_blank\">Insulated Silver-Plated Copper 30Ga Wire<\/a> (~1.00)<\/li>\n<li>The rest of the parts (caps, resistors, LED) I had as spares.<\/li>\n<\/ul>\n<p>There were a few goals that I wanted to achieve with this project. \u00a0Make it small and compact, easy to use, and conserve as little power as possible. \u00a0 \u00a0Getting it into a small package was aided by the RBBB. \u00a0I could have gone a step further by just making a standalone Atmega, but the LEGO shell was my starting place and everything fit fine within the space it had. \u00a0 For power conservation, I used the sleep abilities of the chip and tied it to Interrupt2 tied to the toggle switch. \u00a0Pushing the switch &#8216;in&#8217; would trigger the interrupt and wake the unit. \u00a0 I also have power for the OLED and the SHT11 sensor shut down just before it goes to sleep, and back on immediately after it wakes. \u00a0To do this, I used 2 digital pins set to HIGH \/ LOW as needed. \u00a0 \u00a0I am running the unit off 2x 3V 2032 cells in series, which are put through a 3.3v regulator to power the board and components. \u00a0 \u00a0When running with all components powered it pulls 12mA. \u00a0In sleep mode it pulls 0.6mA. \u00a0I&#8217;d like to get it lower, but think that my use of the regulator is partially killing it due to the voltage drop out.<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-2323  aligncenter\" src=\"http:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp1-300x131.jpg\" alt=\"\" width=\"300\" height=\"131\" \/><\/a><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-2343 alignright\" title=\"HuTmp11\" src=\"http:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp11.jpg\" alt=\"\" width=\"198\" height=\"200\" \/>The key to the accurate humidity \/ temp readings is the Sensiron SHT11 sensor. \u00a0It&#8217;s tiny &#8211; really tiny. \u00a0 There are 4 connections: 3.3V- 5V, GND, Data, CLK. \u00a0In order to protect the sensor, it has been mounted to the side of the unit inside a clear plastic housing. \u00a0The housing has a hole in the side to allow air to flow freely, but limits the any water that might find its way in there (because you never know when it might rain inside the house \ud83d\ude09<\/p>\n<p style=\"text-align: center;\">[ad name=&#8221;GoogleAS728x90ImgOnly&#8221;]<\/p>\n<p>Since everything is so small, I used very fine 30 gauge silver plated copper wire for this. \u00a0It worked quite well for what I needed to do here.<\/p>\n<p>Before migrating all the components into the project, I set everything up on a breadboard and used the Uno to test the sketches. \u00a0 \u00a0 Interestingly, I found getting the 5-way switch working the most challenging. \u00a0It has a common anode I am using as both an Interrupt link (Pin2) as well as toggle switch for scrolling the OLED.<\/p>\n<p style=\"text-align: center;\">[ad name=&#8221;GoogleAS728x90ImgOnly&#8221;]<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-2327 aligncenter\" title=\"HumidityTempSensor2\" src=\"http:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp3-172x300.jpg\" alt=\"\" width=\"172\" height=\"300\" \/><\/a><\/p>\n<p>Below showing the completed RBBB kit. \u00a0Initially, this came with an earlier Bootloader, but I updated to the <a href=\"http:\/\/arduino.cc\/en\/Tutorial\/ArduinoToBreadboard\" target=\"_blank\">Uno one with ease<\/a>.<\/p>\n<p><a href=\"http:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp3B1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-2357\" title=\"HuTmp3B\" src=\"http:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp3B1-300x113.jpg\" alt=\"\" width=\"300\" height=\"113\" srcset=\"https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp3B1-300x113.jpg 300w, https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp3B1.jpg 1024w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>The next step was to start fitting the components into the case. \u00a0The first parts to go in were the switch and red\/green status LED. \u00a0The LED was a pull from an old portable DVD player. After that was done, one side was cut to make room for the length of the RBBB kit. \u00a0Being a die-hard LEGO fan and spending most of my life building, I was always against bastardizing LEGO for things like this &#8211; until I discovered Arduino \/ micro-controllers. \u00a0Sorry AFOL&#8217;s. \ud83d\ude42 \u00a0 The 3rd pic shows the bits all soldered together using that nice 30Ga wire. \u00a0The 4th shows a test fit with the RBBB inserted. \u00a0I made the mistake of completing the RBBB kit as per instructions only to realize that I did not want the rows of breadboard pins as would not need them.. So, out came the solder sucker and I removed them (hence the burn marks you see in other pics). \u00a0In the last picture, you can see a side view showing the SHT11 sensor.. Did I mention this thing is tiny!?<\/p>\n<div id='gallery-1' class='gallery galleryid-2333 gallery-columns-3 gallery-size-thumbnail'><figure class='gallery-item'>\n\t\t\t<div class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp4.jpg'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp4-150x150.jpg\" class=\"attachment-thumbnail size-thumbnail\" alt=\"\" \/><\/a>\n\t\t\t<\/div><\/figure><figure class='gallery-item'>\n\t\t\t<div class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp7.jpg'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp7-150x150.jpg\" class=\"attachment-thumbnail size-thumbnail\" alt=\"\" \/><\/a>\n\t\t\t<\/div><\/figure><figure class='gallery-item'>\n\t\t\t<div class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp5.jpg'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp5-150x150.jpg\" class=\"attachment-thumbnail size-thumbnail\" alt=\"\" \/><\/a>\n\t\t\t<\/div><\/figure><figure class='gallery-item'>\n\t\t\t<div class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp8.jpg'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp8-150x150.jpg\" class=\"attachment-thumbnail size-thumbnail\" alt=\"\" \/><\/a>\n\t\t\t<\/div><\/figure><figure class='gallery-item'>\n\t\t\t<div class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp21.jpg'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp21-150x150.jpg\" class=\"attachment-thumbnail size-thumbnail\" alt=\"\" \/><\/a>\n\t\t\t<\/div><\/figure><figure class='gallery-item'>\n\t\t\t<div class='gallery-icon landscape'>\n\t\t\t\t<a href='https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp3B1.jpg'><img loading=\"lazy\" decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HuTmp3B1-150x150.jpg\" class=\"attachment-thumbnail size-thumbnail\" alt=\"\" \/><\/a>\n\t\t\t<\/div><\/figure>\n\t\t<\/div>\n\n<p><strong><span style=\"text-decoration: underline;\">The Verdict:<\/span><\/strong><\/p>\n<p><strong>Adafruit 128&#215;32 OLED:<\/strong> If you are looking for a crisp display with a small footprint, then this is the unit for you. \u00a0Don&#8217;t expect to be able to read this thing from afar. \u00a0However, up close, the display is clear, and crisp. \u00a0Because it does not have a backlight, and each pixel is self- illuminated, it has low power consumption and is easy to read. \u00a0 Out of the box, the display is slow to render for anything where rapid updates are necessary. \u00a0However, the driver can easily be modified to use the Arduino SPI hardware to speed up its response. \u00a0For this purpose, its not really necessary as I am not drawing rapid graphics or animating. \u00a0If you are doing that, then you want to do this easy mod. \u00a0Just remember that you must then also use the dedicated hardware SPI pins.<\/p>\n<p><strong>Sensiron SHT11: <\/strong>Did I mention the sensor is small? \u00a0Ok, I know I did &#8211; so it&#8217;s small. \u00a0 This is great for integrating it into small projects like this. \u00a0 Sensiron claims the unit has a high degree of accuracy (+\/- 0.4&#8217;C and +\/-3% RH). \u00a0When pitching the results against other temperature gauges in our house, I had different readings on all of them. \u00a0When I tested the readings against a classic mercury unit, it was off by about 1 degree. \u00a0 It also responded well to rapid temperature changes at about a 1-2 hz rate. \u00a0Not super fast, but good enough for measuring changes in room temperature. \u00a0I did some tests where I set the update frequency to less than 500 Ms and it still took about 1+ seconds to return a result &#8211; so it seems that the sensor requires this time to produce and return an accurate reading.<\/p>\n<p style=\"text-align: center;\">[ad name=&#8221;GoogleAS728x90ImgOnly&#8221;]<\/p>\n<p><strong>Modern Device RBBB Kit:<\/strong> If you are looking for a small Arduino footprint, then this is a nice unit. \u00a0It is not the smallest out there, but good enough for most small projects. \u00a0For the price of about $13 plus shipping you can get a full setup in either 3.3v or 5v, the board, parts and an Atmega 328P with bootloader. \u00a0The only caveat is that it comes with the\u00a0Diecimila Bootloader, but you can change it to whatever you like easily. \u00a0Yes, I could have put together a standalone kit with a little more soldering, but considering time and cost, it is not really worth it.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">The Code:<\/span> <\/strong><a href=\"http:\/\/www.plastibots.com\/wordpress\/wp-content\/uploads\/2012\/04\/HumidityTempSensor1_4.zip\">(download it<\/a>)<\/p>\n<pre>\r\n#include \/\/SSD\r\n#include \/\/for OLED\r\n#include <avr\/sleep.h>\r\n#include <avr\/power.h>\r\n#include \/\/HumidityTemp Sensor SHT11\r\n\r\n\/\/OLED PINS\r\n#define OLED_RESET 7 \/\/ RST on OLED\r\n#define OLED_DC 8 \/\/ S\/C on OLED\r\n#define OLED_CS 6 \/\/ CS on OLED - SPI slave-select\r\n#define OLED_MOSI 11 \/\/ DATA on OLED - hardware SPI MOSI\r\n#define OLED_CLK 13 \/\/ CLK on OLED - hardware SPI clock\r\n\r\n\/\/SHT11 Tmp\/Humidity Sensor\r\n\/\/ Specify data and clock connections and instantiate SHT1x object\r\n#define dataPin 9\r\n\/\/#define clockPin 11\r\n#define clockPin 10\r\nSHT1x sht1x(dataPin, clockPin);\r\nfloat temp_c;\r\nfloat temp_f;\r\nfloat humidity;\r\n\r\n\/\/#define SHTPwrPin 4 -not used. When using this, current draw went from 0.6mA when off to 37mA when off!!!! put back\r\n\/\/to 5V pin and back to 0.6mA when off - much better!\r\n#define OLEDPwrPin 3\r\nint redLED = A2;\r\nint grnLED = A3;\r\nint LEDcounter = 0;\r\n\r\nint SHTReadCounter = 0;\r\nint centerToggle = 2;\r\nint upToggle = 12;\r\nint dnToggle = 5;\r\n\/\/switch debouncing\r\nlong debounceDelay = 20; \/\/ the debounce time; increase if the output flickers -\r\nlong lastDebounceTime = 0; \/\/ the last time the output pin was toggled\r\n\/\/for up toggle\r\nint upButtonState; \/\/ the current reading from the input pin\r\nint upLastButtonState = LOW; \/\/ the previous reading from the input pin\r\n\/\/for down toggle\r\nint dnButtonState; \/\/ the current reading from the input pin\r\nint dnLastButtonState = LOW; \/\/ the previous reading from the input pin\r\n\r\n\/\/end switch debouncing\r\n\r\nvolatile int toggle = 1;\r\nchar cVal[32];\r\n\r\nint displayState = 1; \/\/up and down toggles will change the display to different states\r\n\r\nlong shutoffStartMillis = 0; \/\/Store the value to start the shutoff timer from in Milliseconds.\r\n\/\/**********************************\r\n\/\/Change this to determine how long the device stays on - in MS\r\nlong shutOffDelayMS = 180000; \/\/In Milliseconds - Determines how long to keep LED system on (after shutoff timer clicked) in Milliseconds 10000 (10sec), 60000 (1min) 600000 (10min)\r\n\/\/**********************************\r\nboolean debug = false; \/\/turn debugging on or off here\r\n\r\n\/\/OLED\r\nSSD1306 oled(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);\r\n\r\nvoid (*restart)(void) = 0;\r\n\r\n\/***************************************************\r\n* Name: pin2Interrupt\r\n*\r\n***************************************************\/\r\nvoid pin2Interrupt(void)\r\n{\r\n  \/* This will bring us back from sleep. *\/\r\n\r\n  \/* We detach the interrupt to stop it from\r\n  * continuously firing while the interrupt pin\r\n  * is low.\r\n  *\/\r\n\r\n  \/\/appears that the interrup is not working correctly and re-triggering things. Try a restart instead\r\n  restart();\r\n\r\n  \/\/ - removed while testing restart() function. Put these back if restart removed\r\n  \/\/toggle = 1;\r\n  \/\/delay(100);\r\n\r\n  detachInterrupt(0);\r\n\r\n}\r\n\r\n\/***************************************************\r\n* Description: Enters the arduino into sleep mode.\r\n***************************************************\/\r\nvoid enterSleep(void)\r\n{\r\n\r\n  \/* Setup pin2 as an interrupt and attach handler. *\/\r\n  \/\/attachInterrupt(interrupt, function, mode)\r\n  \/\/attachInterrupt(0, pin2Interrupt, LOW);\r\n  attachInterrupt(0, pin2Interrupt, FALLING);\r\n\r\n  delay(100);\r\n\r\n  \/\/Serial.println(\"Going to sleep....\");\r\n\r\n  set_sleep_mode(SLEEP_MODE_PWR_DOWN);\r\n\r\n  sleep_enable();\r\n\r\n  sleep_mode();\r\n\r\n  \/* The program will continue from here. *\/\r\n\r\n  \/* First thing to do is disable sleep. *\/\r\n  sleep_disable();\r\n}\r\n\r\nvoid setup()\r\n{\r\n  Serial.begin(38400);\r\n  pinMode(A5, OUTPUT); \/\/testing blink\r\n  \/* Setup the pin direction. *\/\r\n  pinMode(centerToggle, INPUT);\r\n  \/\/pinMode(SHTPwrPin, OUTPUT);\r\n  pinMode(OLEDPwrPin, OUTPUT);\r\n  pinMode(redLED, OUTPUT);\r\n  pinMode(grnLED, OUTPUT);\r\n  digitalWrite(grnLED, HIGH); \/\/turn off the green LED - common annode - so they have to be high\r\n  digitalWrite(redLED, HIGH); \/\/turn off the gred LED - common annode - so they have to be high\r\n\r\n  digitalWrite(upToggle, LOW);\r\n  digitalWrite(dnToggle, LOW);\r\n  \/\/digitalWrite(SHTPwrPin, LOW);\r\n  digitalWrite(OLEDPwrPin, LOW);\r\n\r\n  \/\/********* OLED SETUP STUFF ******************************************************************\/\r\n  SPI.begin (); \/\/for OLED\r\n  \/\/ OLED: By default, we'll generate the high voltage from the 3.3v line internally! (neat!)\r\n  oled.ssd1306_init(SSD1306_SWITCHCAPVCC);\r\n  \/\/********* OLED SETUP STUFF ******************************************************************\/\r\n  \/\/oled.clear();\r\n  \/\/oled.display();\r\n\r\n  \/\/ displayState = 1;\r\n\r\n  if (debug)\r\n  {\r\n    Serial.println(\"Initialisation complete.\");\r\n    Serial.println(\"Entering sleep\");\r\n  }\r\n  \/\/delay(200);\r\n  \/\/enterSleep();\r\n\r\n  oled.clear();\r\n\r\n}\r\n\r\nvoid doHumTmp(void)\r\n{\r\n\r\n  \/\/ Read values from the sensor\r\n  if (SHTReadCounter == 20) \/\/this is based on the delay at the bottom. if delay changes, this value should as well\r\n  {\r\n    temp_c = sht1x.readTemperatureC();\r\n    temp_f = sht1x.readTemperatureF();\r\n    humidity = sht1x.readHumidity();\r\n    SHTReadCounter = 0;\r\n    if (debug)\r\n    {\r\n      \/\/ Print the values to the serial port\r\n      Serial.print(\"Temperature: \");\r\n      Serial.print(temp_c, DEC);\r\n      Serial.print(\"C \/ \");\r\n      Serial.print(temp_f, DEC);\r\n      Serial.print(\"F. Humidity: \");\r\n      Serial.print(humidity);\r\n      Serial.println(\"%\");\r\n    }\r\n\r\n  }\r\n\r\n  oled.clear();\r\n\r\n  if (temp_c < 0 || temp_f < 0 || humidity < 0) { \r\n    \/\/calibrating \/\/\r\n    oled.drawstring([character position from left - by pixel], [line number 0,1,2,3], \"[text]\"); \r\n    blinkLED(redLED); \r\n    oled.drawline(0, 9, 128, 9, WHITE); \r\n    oled.drawstring(0, 2, \"Calibrating...\"); \r\n    oled.drawline(0, 30, 128, 30, WHITE);\r\n    } else \r\n    if(displayState == 1) \/\/good readings show - 2 display states { blinkLED(grnLED); \/\/Temp in C and F \r\n      oled.drawstring(0, 0, \"Temp: \"); \r\n      ftoa(cVal, temp_c, 1); \r\n      oled.drawstring(35, 0, cVal); \r\n      \/\/oled.drawchar(65, 0, 9); \r\n      \/\/draw degree symbol \r\n      \/\/oled.drawcircle([x position px], [y pos line], [diameter units??], WHITE); \r\n      oled.drawcircle(61, 1, 1.5, WHITE); \r\n      oled.drawstring(64, 0, \"C\"); \r\n      \/\/degrees F \r\n      ftoa(cVal, temp_f, 1); \r\n      oled.drawstring(85, 0, cVal); \r\n      \/\/oled.drawchar(115, 0, 9); \r\n      oled.drawcircle(110, 1, 1.5, WHITE); \r\n      oled.drawstring(114, 0, \"F\"); \r\n      \/\/draw split line \r\n      oled.drawline(0, 15, 128, 15, WHITE); \r\n      \/* int upstate = digitalRead(upToggle); itoa(upstate, cVal, 0); oled.drawstring(0, 2, \"up:\"); oled.drawstring(10, 2, cVal); int dnstate = digitalRead(dnToggle); itoa(dnstate, cVal, 0); oled.drawstring(45, 2, \"dn:\"); oled.drawstring(50, 2, cVal); *\/ \r\n      ftoa(cVal, humidity, 1); \r\n      oled.drawstring(0, 3, \"Humidity:\"); \r\n      oled.drawstring(60, 3, cVal); \r\n      oled.drawstring(85, 3, \"%\"); \r\n      } \r\n      else \r\n        if (displayState == 2)\r\n        \/\/display state would be 2 here \r\n        { \r\n          blinkLED(grnLED); \r\n          oled.drawstring(0, 0, \"Sensor: Sensiron SHT11 Temp &#038; Humidity\"); \r\n          oled.drawstring(0, 2, \"OLED:Adaft SSD1306 128x32\"); \r\n        } \r\n      else \r\n        if (displayState == 3) \r\n        { \r\n          blinkLED(grnLED); \r\n          oled.drawstring(0, 0, \"Board: Modern Device RBBB Kit\"); \r\n          oled.drawstring(0, 2, \"Chip: Atmega 328P w\/UNO Bootloader\"); \r\n        } \r\n      else \r\n      if (displayState == 4) \r\n        { \r\n          blinkLED(grnLED); \r\n          oled.drawstring(0, 0, \"Sketch:\"); \r\n          oled.drawstring(0, 1, \"HumidityTempSensor1_4\"); \r\n        } \r\n        \/\/Display all the results \r\n        oled.display(); \r\n        delay(100); \r\n        SHTReadCounter++ ; } \r\n       \/*************************************************** * \r\n         Name: loop * Description: Main application loop. * Operation Our code will operate as follows: \r\n         1.Set up the serial port and set pin 2 (INT0) as an input; \r\n         2. Run the loop function which will: \r\n         3. Stay awake for 3 seconds; \r\n         4. Once the 3 seconds have elapsed, SLEEP_MODE_PWR_DOWN will be entered; \r\n         5. All code execution stops; \r\n         6. The user then pushes the switch and pin 2 (INT0) will become low; \r\n         7. The INT0 interrupt will fire and bring the Arduino out of sleep mode; \r\n         8. Code execution continues where it had previously stopped. Circuit: http:\/\/donalmorrissey.blogspot.com\/2010\/04\/arduino-external-interrupts.html \r\n         ***************************************************\/ \r\n         \/\/int seconds=0; \r\nvoid loop() \r\n{ \r\n  if (debug) \r\n    { \r\n      \/\/ Serial.println(\"Still awake....\"); } \r\n      \/\/Will put the unit to sleep after a pre-defined amount of time \r\n      if (shutoffStartMillis != 0 &#038;&#038; millis() - shutoffStartMillis > shutOffDelayMS) \r\n      \/\/if shutoff time has elapsed, turn the LEDs off 1000ms = 1 second\r\n    {\r\n      \/\/delay(100);\r\n\r\n      shutoffStartMillis = 0;\r\n      \/\/power down the SHT11 Sensor and other ports\r\n      digitalWrite(upToggle, LOW);\r\n      digitalWrite(dnToggle, LOW);\r\n      \/\/digitalWrite(SHTPwrPin, LOW);\r\n\r\n      \/\/Power down the OLED\r\n      oled.clear();\r\n      oled.display();\r\n      \/\/digitalWrite(OLED_RESET, LOW);\r\n      digitalWrite(OLEDPwrPin, LOW);\r\n\r\n      \/\/go to sleep\r\n      if (debug) {\r\n        Serial.println(\"Entering sleep\");\r\n      }\r\n      delay(200);\r\n      \/\/seconds = 0;\r\n      enterSleep();\r\n\r\n    }\r\n\r\n    \/\/watch the up and down toggle\r\n\r\n    \/\/int upToggleReading = digitalRead(upToggle);\r\n    \/\/int dnToggleReading = digitalRead(dnToggle);\r\n\r\n    \/\/will be able to read each other toggle pin as LOW when it is pressed.\r\n    if (debug)\r\n    {\r\n      \/\/ Serial.print(\"UpToggle: \"); Serial.print(digitalRead(upToggle)); \/\/ Read the pin and display the value\r\n      \/\/ Serial.print(\" DnToggle: \"); Serial.println(digitalRead(dnToggle)); \/\/ Read the pin and display the value\r\n      \/\/ Serial.print(\" DisplayState: \"); Serial.println(displayState); \/\/ Read the pin and display the value\r\n    }\r\n\r\n    if (digitalRead(upToggle) == 0)\r\n    {\r\n      \/\/displayState++;\r\n      \/\/if (displayState > 2) {displayState = 1;} \/\/simple method to only go to 2 states\r\n      displayState = 1;\r\n      delay(100);\r\n    }\r\n\r\n    if (digitalRead(dnToggle) == 0)\r\n    {\r\n\r\n      \/\/if (displayState < 1) {displayState = 2;} \/\/simple method to only go to 2 states\r\n\r\n      if (displayState < 4)\r\n      {\r\n        displayState++;\r\n      } \/\/dont let it go past a max value\r\n      delay(100);\r\n    }\r\n\r\n    \/*\r\n    Serial.print(\"ButtonState: \"); Serial.print(upButtonState);\r\n    Serial.print(\" LastButtonState: \"); Serial.print(upLastButtonState);\r\n    Serial.print(\" DisplayState: \"); Serial.println(displayState);\r\n\r\n    Serial.print(\"ButtonState: \"); Serial.print(dnButtonState);\r\n    Serial.print(\" LastButtonState: \"); Serial.print(dnLastButtonState);\r\n    Serial.print(\" DisplayState: \"); Serial.println(displayState);\r\n    *\/\r\n\r\n    \/\/ save the reading. Next time through the loop,\r\n    \/\/ it'll be the lastButtonState:\r\n    \/\/upLastButtonState = upToggleReading;\r\n    \/\/dnLastButtonState = dnToggleReading;\r\n\r\n    if (toggle == 1)\r\n    {\r\n      shutoffStartMillis = millis(); \/\/get a start value to start the countdown from.\r\n      displayState = 1; \/\/ensure the display defaults to the main screen\r\n      \/\/digitalWrite(SHTPwrPin, HIGH);\r\n      digitalWrite(OLEDPwrPin, HIGH);\r\n      delay(1000);\r\n      \/\/********* OLED SETUP STUFF ******************************************************************\/\r\n      \/\/have to do this again with each power on state or the OLED does not come on.\r\n      SPI.begin (); \/\/for OLED\r\n      \/\/ OLED: By default, we'll generate the high voltage from the 3.3v line internally! (neat!)\r\n      oled.ssd1306_init(SSD1306_SWITCHCAPVCC);\r\n      \/\/********* OLED SETUP STUFF ******************************************************************\/\r\n      delay(500);\r\n      \/\/oled.clear();\r\n      \/\/oled.display();\r\n\r\n      doHumTmp();\r\n\r\n      \/\/provide power to the toggle switch up and down.\r\n      digitalWrite(upToggle, HIGH);\r\n      digitalWrite(dnToggle, HIGH);\r\n\r\n      delay(500); \/\/give it some time to calibrate etc\r\n      toggle = 0;\r\n\r\n    }\r\n    else\r\n    {\r\n      \/\/show the temp and humidity values\r\n      doHumTmp();\r\n    }\r\n\r\n    LEDcounter++;\r\n  }\r\n\r\n  \/\/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n  char *ftoa(char *a, double f, int precision)\r\n  {\r\n    long p[] = {0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};\r\n\r\n    char *ret = a;\r\n    long heiltal = (long)f;\r\n    itoa(heiltal, a, 10);\r\n    while (*a != '\\0') a++;\r\n    *a++ = '.';\r\n    long desimal = abs((long)((f - heiltal) * p[precision]));\r\n    itoa(desimal, a, 10);\r\n    return ret;\r\n  }\r\n\r\n  \/\/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n  static void print_str(const char *str, int len)\r\n  {\r\n    int slen = strlen(str);\r\n    for (int i = 0; i < len; ++i)\r\n      Serial.print(i\r\n    }\r\n  \/\/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n  static void print_int(unsigned long val, unsigned long invalid, int len)\r\n  {\r\n    char sz[32];\r\n    if (val == invalid)\r\n      strcpy(sz, \"*******\");\r\n    else\r\n      sprintf(sz, \"%ld\", val);\r\n    sz[len] = 0;\r\n    for (int i = strlen(sz); i < len; ++i) sz[i] = ' '; if (len > 0)\r\n      sz[len - 1] = ' ';\r\n    Serial.print(sz);\r\n  }\r\n\r\n  void blinkLED(int led)\r\n  {\r\n    if (LEDcounter == 10) \/\/we do not want the LED blinking with every cycle as it is seizure enducing!\r\n    {\r\n      if (led == redLED)\r\n      {\r\n        digitalWrite(redLED, LOW);\r\n        delay(50);\r\n        digitalWrite(redLED, HIGH);\r\n      }\r\n      else\r\n      {\r\n        digitalWrite(grnLED, LOW);\r\n        delay(50);\r\n        digitalWrite(grnLED, HIGH);\r\n      }\r\n      LEDcounter = 0;\r\n    }\r\n\r\n  }\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The projects I do tend to fall in one of two buckets &#8211; either proof-of-concept (so I can learn new stuff) or items that have some sort of functional use. \u00a0 The need for this project came about when my wife was prodding me about the humidity in the house and whether our humidifier was doing it&#8217;s job correctly. \u00a0Most people would just go out and buy a temp \/ humidity sensor and be done &hellip; <a href=\"https:\/\/www.plastibots.com\/index.php\/2012\/04\/05\/arduino-temperature-humidity-sensor\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[65,1],"tags":[64,71],"class_list":["post-2333","post","type-post","status-publish","format-standard","hentry","category-arduino-electronics","category-uncategorized","tag-arduino","tag-oled","has_no_thumb"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pK41j-BD","jetpack_sharing_enabled":true,"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.plastibots.com\/index.php\/wp-json\/wp\/v2\/posts\/2333","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.plastibots.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.plastibots.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.plastibots.com\/index.php\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.plastibots.com\/index.php\/wp-json\/wp\/v2\/comments?post=2333"}],"version-history":[{"count":0,"href":"https:\/\/www.plastibots.com\/index.php\/wp-json\/wp\/v2\/posts\/2333\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.plastibots.com\/index.php\/wp-json\/wp\/v2\/media?parent=2333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.plastibots.com\/index.php\/wp-json\/wp\/v2\/categories?post=2333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.plastibots.com\/index.php\/wp-json\/wp\/v2\/tags?post=2333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}