{"id":54,"date":"2011-03-11T02:32:35","date_gmt":"2011-03-11T07:32:35","guid":{"rendered":"http:\/\/ahdesign.us\/blog\/?p=54"},"modified":"2012-01-12T15:18:38","modified_gmt":"2012-01-12T20:18:38","slug":"thermostat-project","status":"publish","type":"post","link":"https:\/\/ahdesign.us\/blog\/thermostat-project\/","title":{"rendered":"Thermostat Project"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" title=\"Thermostat\" src=\"http:\/\/thehoneckers.com\/var\/resizes\/AndyProjects\/IMG_6586.jpg?m=1317676645\" alt=\"RS-485 Thermostat\" width=\"640\" height=\"427\" \/><\/p>\n<p>This is the Thermostat project I set out designing about a year or two after we bought our first house.\u00a0 Yes, there&#8217;s really no need to make your own digital thermostat as you can buy a good one for under $50, but since we were heating with wood, it suddenly became apparent that it would be really handy to be able to turn on the &#8220;AC&#8221; (the unit&#8217;s breaker was actually off, I just used the AC mode of the thermostat to circulate the heat from the wood stove) and also be able to turn on the furnace if the temperature dropped too low from the fire dying out or just not being frigidly cold outside.\u00a0 The wood stove has a hard time keeping the temperature inside above 68ish when it&#8217;s about 15 degrees or colder outside.<\/p>\n<p><!--more--><\/p>\n<p>I essentially set out to create a thermostat that would allow temperature set points for both heating and cooling, and at the time I couldn&#8217;t find such a thermostat that existed that would do such a thing cheaply.\u00a0 This is not really the case now as you can find these two-stage (or multiple stage) thermostats all over now since a lot of people have multiple heating\/cooling sources and furnaces now have variable speed fans and all that good stuff.<\/p>\n<p>The other intent for the thermostat project was to try out some technologies that I had a lot of interest in.\u00a0 I&#8217;d never done anything large with a PIC microcontroller before, I wanted to have capacitive sensing pads instead of push-buttons, I wanted to fiddle with a touch screen, I wanted to use I2C for talking to parts on my board, and finally I wanted to try out RS-485 for networking multiple thermostats and temperature modules (more on these guys below) for temperature monitoring.<\/p>\n<p>Little did I know what I was getting myself into!\u00a0 I met all my goals in the design, and I was able to find a nice little graphic LCD that was backlit and had a small resistive touch screen on it.\u00a0 I ended up choosing a Cypress CapSense chip (one of the really basic ones that really only does buttons) to handle the six buttons on my board.\u00a0 The I2C bus ended up connecting up the CapSense chip, a I2C port expander (since I didn&#8217;t have enough I\/O from the 28 pin micro), a RTC chip, a temperature chip, touchscreen chip, and a serial EEPROM.\u00a0 After the hardware was designed, I set out creating the PCB and following the CapSense chip rules for creating buttons.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" title=\"RS-485 Thermostat\" src=\"http:\/\/thehoneckers.com\/var\/resizes\/AndyProjects\/IMG_6597.jpg?m=1317676650\" alt=\"RS-485 Thermostat\" width=\"640\" height=\"427\" \/><\/p>\n<p>The 1st rev of the board was very successful.\u00a0 It&#8217;s probably easily noticed in the pictures that there are some reworks, but a few of them are because it makes the software a little easier to deal with certain things.\u00a0 Other reworks are to fix minor boo-boos on the board.\u00a0 Anyways, the only real issue I had was controlling the reset pin on the microcontroller.\u00a0 The part I had chosen didn&#8217;t seem to come out of reset reliably in other projects, so I put a power supply monitor in the design and that controlled the reset on the micro.\u00a0 The problem here is that to program the PIC, ~13VDC is applied to the reset pin by the programmer when new code is programmed into the device.\u00a0 The reset supervisor chip really doesn&#8217;t like 13V on any of its pins.\u00a0 Luckily this revelation occurred to me before trying to program the PIC, and I ended up adding in a manual switch that you have to throw when programming the device.<\/p>\n<p>Once the PIC was resetting and programming as expected, I needed to write drivers for accessing all the peripherals on the I2C bus and some sort of code to test the drivers I was writing.\u00a0 This took a huge amount of time, and I didn&#8217;t have a lot of time to allocate to this project, so it seemingly took forever to get drivers in place.\u00a0 While starting to write a display driver, I quickly discovered that the graphic display chose does not have an onboard character generator or anything like that.\u00a0 All this display has onboard is RAM and some chip that takes the memory contents and turns pixels on.\u00a0 This was totally unexpected, but luckily I did find a display driver and font set that I was able to port to the PIC without too much pain.\u00a0 Once the display driver was all set and working, it quickly became apparent that I didn&#8217;t have enough program memory in the PIC for my code and the fonts (the fonts take up lots of memory as there&#8217;s a complete 6&#215;8 and 12&#215;16 or so font that I&#8217;m using).\u00a0 I now had to put the fonts out into the I2C EEPROM and modify the driver to fetch font data from the EEPROM instead of program memory.\u00a0 And of course this brought on the next problem of how to get the fonts into the EEPROM in the first place.\u00a0 Long story still long, I have compile switches that turn my main program into a &#8220;program all the parts on the board&#8221; program for easily loading up a new board.\u00a0 I also figured out how to program the CapSense chip via the PIC instead of having to hook up it&#8217;s programmer too.<\/p>\n<p>The only real issue with pulling font data out of I2C EEPROM is that the I2C bus is rather slow (I&#8217;m running at roughly 400KHz), so getting data for the large font set really slowed things down.\u00a0 I solved the apparent slow down to the user by doing burst reads of EEPROM data (instead of random reads) into PIC RAM.\u00a0 I think I buffer one whole character for the display driver.\u00a0 This improved perceived performance significantly while not using tons of RAM for buffering.<\/p>\n<p>The thermostat main program doesn&#8217;t really do anything at the moment except interact with all the hardware on the board.\u00a0 My program is solely interrupt driven.\u00a0 My main function is a while loop that does nothing until an interrupt is received.\u00a0 Then the main loop handles the action requested by the interrupt in a round-robin fashion until there are no more tasks to handle.\u00a0 The following tasks can occur (all by unique interrupt): Timer interrupt (interrupts a number of times a second for display refreshing), RTC alarm task, CapSense button press task (all this task does is turn on the LED of the button that was pressed), serial data received (from RS-485), touch screen pressed, and probably a few others that I&#8217;ve forgotten.<\/p>\n<p>Oh yeah, the temperature modules.\u00a0 Here&#8217;s a picture of one in front of the thermostat:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone\" title=\"RS-485 Temperature Module\" src=\"http:\/\/thehoneckers.com\/var\/resizes\/AndyProjects\/IMG_6584.jpg?m=1317676638\" alt=\"RS-485 Temperature Module\" width=\"640\" height=\"427\" \/><\/p>\n<p>Basically all these guys are is a PIC microcontroller with a I2C temperature sensor that can be located remotely, like outside or in a room, or&#8230;.kinda anywhere.\u00a0 The RS-485 link allows the unit to be placed a long distance away from the furthest node in the network.\u00a0 The distance depends on baud rate used.\u00a0 The faster the baud rate, the shorter the maximum distance, and vice-versa.\u00a0 Collisions aren&#8217;t explicitly handled for multiple nodes on the network.\u00a0 Instead, collision avoidance is handled by a master-slave type of communications.\u00a0 There is only one master allowed on the network, and slaves only respond to the master when the master requests data from them.\u00a0 Each module (thermostat or temperature module) has an ID dipswitch onboard to pick the ID of the module.\u00a0 I had to develop my own protocol for communicating with the slave devices since I wanted messages to be very short (currently at 3 or so bytes long) to ensure that I would have a hard time overflowing the PIC&#8217;s UART receive buffer in the event that the main loop can&#8217;t get to the serial interrupt task fast enough.\u00a0 Short message length plus slow baud rate (currently 9600 bps) seems to work well, although it would be interesting to try out 115200 bps and see what happens.\u00a0 I have been able to successfully communicate with a slave, but I have yet to figure out how to transfer the temperature readings from the temperature module to the thermostat efficiently.<\/p>\n<p>For the touch screen, this has also been tricky.\u00a0 The touch screen chip handles all the analog stuff that goes on for interfacing with the touch screen, and reading the touch values isn&#8217;t tough either.\u00a0 The hard part is creating a set of calibration values for the touch screen as the touch overlay can be skewed or rotated slightly from unit to unit straight from the factory.\u00a0 Plus over time, the overlay an move slightly.\u00a0 The solution to this is a set of equations that depend on readings from three predetermined touch points on the screen.\u00a0 Matrix algebra is used to solve the equations, and then you end up with an X and Y calibration value that you use in a simple linear equation to scale all the raw readings with.\u00a0 The matrix algebra proved to be very tricky to do in the PIC with the compiler I use (CCS PCD) as it cannot handle terribly complicated expressions.\u00a0 I believe the calibration routine is nearly complete, but some still remains to be completed on it.<\/p>\n<p>In all, the basic hardware testing and verification is about 95% complete.\u00a0 All that is really left to do is create a touchable user interface and make the thermostat function as a real thermostat.\u00a0 Unfortunately, I don&#8217;t think this will ever be completed as thermostats that do everything I&#8217;d ever want them to do are getting cheaper and cheaper and some even connect to the internet, which allows you to set them remotely.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the Thermostat project I set out designing about a year or two after we bought our first house.\u00a0 Yes, there&#8217;s really no need to make your own digital thermostat as you can buy a good one for under &hellip; <a href=\"https:\/\/ahdesign.us\/blog\/thermostat-project\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-54","post","type-post","status-publish","format-standard","hentry","category-thermostat"],"_links":{"self":[{"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/posts\/54","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/comments?post=54"}],"version-history":[{"count":4,"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/posts\/54\/revisions"}],"predecessor-version":[{"id":59,"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/posts\/54\/revisions\/59"}],"wp:attachment":[{"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/media?parent=54"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/categories?post=54"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ahdesign.us\/blog\/wp-json\/wp\/v2\/tags?post=54"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}