{"id":30,"date":"2009-09-07T13:46:40","date_gmt":"2009-09-07T11:46:40","guid":{"rendered":"http:\/\/wordpress1\/?page_id=30"},"modified":"2011-04-04T13:01:52","modified_gmt":"2011-04-04T11:01:52","slug":"arduino-thermostat","status":"publish","type":"page","link":"https:\/\/www.xenoworld.org\/?page_id=30","title":{"rendered":"Arduino Thermostat"},"content":{"rendered":"<p>After brewing our own beer for some time, a friend of mine and myself  thought we should find a way to ferment the kegs of beer on a constant  temperature and not just gambling on whatever temperature the basement  would hold.<\/p>\n<p>So, after being inspired by Sean Cotes&#8217; <a href=\"http:\/\/www.uchobby.com\/index.php\/2007\/10\/08\/arduino-beer-thermostat\/\" target=\"_blank\">Arduino Beer Thermostat<\/a>, I thought I might as well make one myself with a few alterations.<\/p>\n<p>I&#8217;ll upload the schematics when I get the chance&#8230;<\/p>\n<p>The code is as follows:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\/\/ Jon Ivar Larsen\/XeNo - www.xenoworld.org - 2009\r\n\/\/ Code based on Sean Cotes' Arduino Beer Thermostat -\r\n\/\/ http:\/\/www.uchobby.com\/index.php\/2007\/10\/08\/arduino-beer-thermostat\/\r\n\/\/ and Carlyn Maw and Tom Igoe's shiftOutCode - http:\/\/www.arduino.cc\/en\/Tutorial\/ShiftOut\r\n\r\n\/\/INCLUDES\r\n#include &lt;Wire.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\n\/\/VARIABLES\r\nfloat tempC;\r\nint tempHigh;\r\nint tempLow;\r\nint pot1Val;\r\nint pot2Val;\r\nint relayToggled;\r\nchar valueStr&#x5B;5];\r\n\/\/For finding most- and least-significant bit\r\nint msb;\r\nint lsb;\r\n\/\/For choosing what to display in the 7-segments based on the state of the 3-way switch\r\nint switchChosenValue;\r\n\/\/Variables for the state of each switchPin\r\nint switchPin1State = 0;\r\nint switchPin2State = 0;\r\nint switchPin3State = 0;\r\n\/\/holders for infromation you're going to pass to shifting function\r\nbyte dataLeft7Segment;\r\nbyte dataRight7Segment;\r\nbyte dataArrayNumbers&#x5B;10];\r\n\r\n\/\/ INPUTS\r\nint tempPin = 0;\r\nint pot1Pin = 1;\r\nint pot2Pin = 2;\r\nint latchPin = 8; \/\/Pin connected to ST_CP of 74HC595\r\nint clockPin = 11; \/\/Pin connected to SH_CP of 74HC595\r\nint dataPin = 10; \/\/Pin connected to DS of 74HC595\r\n\/\/Pins connected to the 3-way switch\r\nint switchPin1 = 5;\r\nint switchPin2 = 6;\r\nint switchPin3 = 7;\r\n\r\n\/\/OUTPUTS\r\nint relayPin = 12;\r\n\r\nvoid setup()\r\n{\r\nSerial.begin(9600); \/\/Opens serial port, sets data rate to 9600 bps\r\npinMode(relayPin, OUTPUT);\r\nrelayToggled = 0; \/\/Set the relay status to not toggled\r\n\r\npinMode(latchPin, OUTPUT);\u00a0 \/\/set pins to output because they are addressed in the main loop\r\n\r\n\/\/3-way Switch\r\npinMode(switchPin1, INPUT);\r\npinMode(switchPin2, INPUT);\r\npinMode(switchPin3, INPUT);\r\n\/\/sets the default (unpressed) state of the switchPins to HIGH\r\ndigitalWrite(switchPin1, HIGH);\r\ndigitalWrite(switchPin2, HIGH);\r\ndigitalWrite(switchPin3, HIGH);\r\n\r\n\/\/sets the array of hex-data for the numbers 0-9\r\ndataArrayNumbers&#x5B;0] = 0x3F; \/\/ 0\r\ndataArrayNumbers&#x5B;1] = 0x06; \/\/ 1\r\ndataArrayNumbers&#x5B;2] = 0x5B; \/\/ 2\r\ndataArrayNumbers&#x5B;3] = 0x4F; \/\/ 3\r\ndataArrayNumbers&#x5B;4] = 0x66; \/\/ 4\r\ndataArrayNumbers&#x5B;5] = 0x6D; \/\/ 5\r\ndataArrayNumbers&#x5B;6] = 0x7C; \/\/ 6\r\ndataArrayNumbers&#x5B;7] = 0x07; \/\/ 7\r\ndataArrayNumbers&#x5B;8] = 0x7F; \/\/ 8\r\ndataArrayNumbers&#x5B;9] = 0x67; \/\/ 9\r\n\r\n\/\/function that blinks all the LEDs\r\n\/\/gets passed the number of blinks and the pause time\r\nblinkAll_2Bytes(2,500);\r\n}\r\n\r\nvoid loop()\r\n{\r\ncheckPots();\r\ncheckTemp();\r\ncheckSwitch();\r\ndisplay7Segment();\r\nprintSerial();\r\n\r\ntoggle();\r\ndelay(200); \/\/Wait 200ms\r\n}\r\n\r\nvoid checkSwitch()\r\n{\r\n\/\/Read the states of the switchpins\r\nswitchPin1State = digitalRead(switchPin1);\r\nswitchPin2State = digitalRead(switchPin2);\r\nswitchPin3State = digitalRead(switchPin3);\r\n\r\nif (switchPin1State == LOW){\r\nswitchChosenValue = tempLow;\r\n}\r\nif (switchPin2State == LOW){\r\nswitchChosenValue = tempC;\r\n}\r\nif (switchPin3State == LOW){\r\nswitchChosenValue = tempHigh;\r\n}\r\n}\r\n\r\nvoid display7Segment()\r\n{\r\n\/\/Divide up the numbers in most significant bit (msb) and least significant bit (lsb)\r\nmsb = switchChosenValue \/ 10;\r\nlsb = switchChosenValue - (msb * 10);\r\n\r\n\/\/load the light sequence you want from array\r\ndataLeft7Segment = dataArrayNumbers&#x5B;msb];\r\ndataRight7Segment = dataArrayNumbers&#x5B;lsb];\r\n\/\/ground latchPin and hold low for as long as you are transmitting\r\ndigitalWrite(latchPin, 0);\r\n\/\/move 'em out\r\nshiftOut(dataPin, clockPin, dataRight7Segment);\r\nshiftOut(dataPin, clockPin, dataLeft7Segment);\r\n\/\/return the latch pin high to signal chip that it\r\n\/\/no longer needs to listen for information\r\ndigitalWrite(latchPin, 1);\r\n}\r\n\r\nvoid checkTemp()\r\n{\r\nint span = 20;\r\nint aRead = 0;\r\nfor (int i = 0; i &lt; span; i++) {\r\naRead = aRead + analogRead(tempPin);\r\n}\r\naRead = aRead \/ span;\r\ntempC = (4.96 * aRead * 100.0)\/1024.0; \/\/convert the analog data to temperature\r\n}\r\n\r\nvoid checkPots()\r\n{\r\npot1Val = analogRead(pot1Pin);\r\ntempHigh = (pot1Val \/ 30);\r\n\r\npot2Val = analogRead(pot2Pin);\r\ntempLow = (pot2Val \/ 30);\r\n}\r\n\r\nvoid printSerial()\r\n{\r\nSerial.print(tempC); Serial.print(&quot; &quot;); Serial.print(tempLow);\r\nSerial.print(&quot; &quot;); Serial.print(tempHigh); Serial.print(&quot; &quot;);\r\nSerial.println(relayToggled);\r\n}\r\n\r\nvoid toggle()\r\n{\r\nif (tempC &gt;= tempHigh) {\r\ntooHot();\r\n}\r\n\r\nif (tempC &lt;= tempLow) {\r\ntooCold();\r\n}\r\n}\r\n\r\nvoid tooHot()\r\n{\r\ndigitalWrite(relayPin, HIGH);\r\nrelayToggled = 1;\r\n}\r\n\r\nvoid tooCold()\r\n{\r\ndigitalWrite(relayPin, LOW);\r\nrelayToggled = 0;\r\n}\r\n\r\n\/\/ the heart of the program\r\nvoid shiftOut(int myDataPin, int myClockPin, byte myDataOut){\r\n\/\/ This shifts 8 bits out MSB first,\r\n\/\/on the rising edge of the clock,\r\n\/\/clock idles low\r\n\r\n\/\/internal function setup\r\nint i=0;\r\nint pinState;\r\npinMode(myClockPin, OUTPUT);\r\npinMode(myDataPin, OUTPUT);\r\n\r\n\/\/clear everything out just in case to\r\n\/\/prepare shift register for bit shifting\r\ndigitalWrite(myDataPin, 0);\r\ndigitalWrite(myClockPin, 0);\r\n\r\n\/\/for each bit in the byte myDataOut\u00ef\u00bf\u00bd\r\n\/\/NOTICE THAT WE ARE COUNTING DOWN in our for loop\r\n\/\/This means that %00000001 or &quot;1&quot; will go through such\r\n\/\/that it will be pin Q0 that lights.\r\nfor (i=7; i&gt;=0; i--)\u00a0 {\r\ndigitalWrite(myClockPin, 0);\r\n\r\n\/\/if the value passed to myDataOut and a bitmask result\r\n\/\/ true then... so if we are at i=6 and our value is\r\n\/\/ %11010100 it would the code compares it to %01000000\r\n\/\/ and proceeds to set pinState to 1.\r\nif ( myDataOut &amp; (1&lt;&lt;i) ) {\r\npinState= 1;\r\n}\r\nelse {\r\npinState= 0;\r\n}\r\n\r\n\/\/Sets the pin to HIGH or LOW depending on pinState\r\ndigitalWrite(myDataPin, pinState);\r\n\/\/register shifts bits on upstroke of clock pin\r\ndigitalWrite(myClockPin, 1);\r\n\/\/zero the data pin after shift to prevent bleed through\r\ndigitalWrite(myDataPin, 0);\r\n}\r\n\r\n\/\/stop shifting\r\ndigitalWrite(myClockPin, 0);\r\n}\r\n\r\n\/\/blinks the whole register based on the number of times you want to\r\n\/\/blink &quot;n&quot; and the pause between them &quot;d&quot;\r\n\/\/starts with a moment of darkness to make sure the first blink\r\n\/\/has its full visual effect.\r\nvoid blinkAll_2Bytes(int n, int d){\r\ndigitalWrite(latchPin, 0);\r\nshiftOut(dataPin, clockPin, 0);\r\nshiftOut(dataPin, clockPin, 0);\r\ndigitalWrite(latchPin, 1);\r\ndelay(200);\r\nfor (int x = 0; x &lt; n; x++) {\r\ndigitalWrite(latchPin, 0);\r\nshiftOut(dataPin, clockPin, 255);\r\nshiftOut(dataPin, clockPin, 255);\r\ndigitalWrite(latchPin, 1);\r\ndelay(d);\r\ndigitalWrite(latchPin, 0);\r\nshiftOut(dataPin, clockPin, 0);\r\nshiftOut(dataPin, clockPin, 0);\r\ndigitalWrite(latchPin, 1);\r\ndelay(d);\r\n}\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>After brewing our own beer for some time, a friend of mine and myself thought we should find a way to ferment the kegs of beer on a constant temperature and not just gambling on whatever temperature the basement would &hellip;<\/p>\n<p class=\"read-more\"><a href=\"https:\/\/www.xenoworld.org\/?page_id=30\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-30","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.xenoworld.org\/index.php?rest_route=\/wp\/v2\/pages\/30","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xenoworld.org\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.xenoworld.org\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.xenoworld.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xenoworld.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=30"}],"version-history":[{"count":9,"href":"https:\/\/www.xenoworld.org\/index.php?rest_route=\/wp\/v2\/pages\/30\/revisions"}],"predecessor-version":[{"id":173,"href":"https:\/\/www.xenoworld.org\/index.php?rest_route=\/wp\/v2\/pages\/30\/revisions\/173"}],"wp:attachment":[{"href":"https:\/\/www.xenoworld.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=30"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}