Thermostat Project

RS-485 Thermostat

This is the Thermostat project I set out designing about a year or two after we bought our first house.  Yes, there’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 “AC” (the unit’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.  The wood stove has a hard time keeping the temperature inside above 68ish when it’s about 15 degrees or colder outside.

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’t find such a thermostat that existed that would do such a thing cheaply.  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.

The other intent for the thermostat project was to try out some technologies that I had a lot of interest in.  I’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.

Little did I know what I was getting myself into!  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.  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.  The I2C bus ended up connecting up the CapSense chip, a I2C port expander (since I didn’t have enough I/O from the 28 pin micro), a RTC chip, a temperature chip, touchscreen chip, and a serial EEPROM.  After the hardware was designed, I set out creating the PCB and following the CapSense chip rules for creating buttons.

RS-485 Thermostat

The 1st rev of the board was very successful.  It’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.  Other reworks are to fix minor boo-boos on the board.  Anyways, the only real issue I had was controlling the reset pin on the microcontroller.  The part I had chosen didn’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.  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.  The reset supervisor chip really doesn’t like 13V on any of its pins.  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.

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.  This took a huge amount of time, and I didn’t have a lot of time to allocate to this project, so it seemingly took forever to get drivers in place.  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.  All this display has onboard is RAM and some chip that takes the memory contents and turns pixels on.  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.  Once the display driver was all set and working, it quickly became apparent that I didn’t have enough program memory in the PIC for my code and the fonts (the fonts take up lots of memory as there’s a complete 6×8 and 12×16 or so font that I’m using).  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.  And of course this brought on the next problem of how to get the fonts into the EEPROM in the first place.  Long story still long, I have compile switches that turn my main program into a “program all the parts on the board” program for easily loading up a new board.  I also figured out how to program the CapSense chip via the PIC instead of having to hook up it’s programmer too.

The only real issue with pulling font data out of I2C EEPROM is that the I2C bus is rather slow (I’m running at roughly 400KHz), so getting data for the large font set really slowed things down.  I solved the apparent slow down to the user by doing burst reads of EEPROM data (instead of random reads) into PIC RAM.  I think I buffer one whole character for the display driver.  This improved perceived performance significantly while not using tons of RAM for buffering.

The thermostat main program doesn’t really do anything at the moment except interact with all the hardware on the board.  My program is solely interrupt driven.  My main function is a while loop that does nothing until an interrupt is received.  Then the main loop handles the action requested by the interrupt in a round-robin fashion until there are no more tasks to handle.  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’ve forgotten.

Oh yeah, the temperature modules.  Here’s a picture of one in front of the thermostat:

RS-485 Temperature Module

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….kinda anywhere.  The RS-485 link allows the unit to be placed a long distance away from the furthest node in the network.  The distance depends on baud rate used.  The faster the baud rate, the shorter the maximum distance, and vice-versa.  Collisions aren’t explicitly handled for multiple nodes on the network.  Instead, collision avoidance is handled by a master-slave type of communications.  There is only one master allowed on the network, and slaves only respond to the master when the master requests data from them.  Each module (thermostat or temperature module) has an ID dipswitch onboard to pick the ID of the module.  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’s UART receive buffer in the event that the main loop can’t get to the serial interrupt task fast enough.  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.  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.

For the touch screen, this has also been tricky.  The touch screen chip handles all the analog stuff that goes on for interfacing with the touch screen, and reading the touch values isn’t tough either.  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.  Plus over time, the overlay an move slightly.  The solution to this is a set of equations that depend on readings from three predetermined touch points on the screen.  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.  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.  I believe the calibration routine is nearly complete, but some still remains to be completed on it.

In all, the basic hardware testing and verification is about 95% complete.  All that is really left to do is create a touchable user interface and make the thermostat function as a real thermostat.  Unfortunately, I don’t think this will ever be completed as thermostats that do everything I’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.

This entry was posted in Thermostat. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.