The Nest Learning Thermostat was introduced in 2011, and now several companies offer smart thermostats. Smart thermostats can be controlled remotely using a mobile app and offer features like adjusting the temperature, creating temperature schedules, reviewing energy usage, etc.
As further practice building and programming IoT devices with your Photon kit, your team will create a prototype of a smart thermostat that can be controlled by a web app.
However for this practice, you will only be given partial instructions. Your team will have to figure out the rest in order to build the device and program its apps.
Your team will need to carefully read through these instructions. Only ask questions if you have first read the instructions.
It might be helpful to have your team members divide up the work:
one person could build the device by connecting the parts
another person could program the Photon app
a third person could program the web app
Here is a system model showing how the parts of the smart thermostat prototype are supposed to work together:
Device (and web app) display room temperature, temperature setting, and system status (Off, Heating, Cooling).
Device (and web app) allow user to change desired temperature setting using buttons.
Device reads current room temperature.
Device compares room temperature with temperature setting to control system:
If room temperature is lower than temperature setting, device turns on heating system (represented by red LED).
If room temperature is higher than temperature setting, device turns on cooling system (represented by blue LED).
If room temperature is equal to temperature setting, device turns off heating and cooling systems.
NOTE: To make this device simpler to build and program, this thermostat is designed to run in a dual mode where it may turn on heating or cooling during the same day. For example, people that live in desert climates (such as Arizona, etc.) would want a thermostat that runs in dual mode because it can get very hot during the day but very cool at night.
Most thermostats are designed to be in only one mode at a time: Heat Only, Cool Only, or Off. The "Heat" mode is used during the winter to only run the furnace. The "Cool" mode is used during the summer to only run the air conditioning. The "Off" mode is used during parts of the spring and fall when no heating or cooling is needed. Most thermostats have a separate button to change the system mode.
Here's a picture of a smart thermostat prototype to give you a general sense of how it will look when finished. While it might look complex, each individual part is relatively simple to connect. The instructions provide references that show how to connect each part.
Red LED (to represent heating system, such as furnace)
Blue LED (to represent cooling system, such as air conditioner)
2 Resistors (one for each LED)
Red Push Button (used to increase temperature setting)
Blue Push Button (used to decrease temperature setting)
RHT03 Humidity and Temperature Sensor
Micro OLED Display Screen
18 Jumper Wires
Make sure the parts are arranged in a logical layout that makes it easy for a person to understand and use the device.
Remember that all the parts have to be arranged so their pins are in their own breadboard rows:
If different parts are on the same side of the breadboard, the pins of different parts should not be in the same row number.
A resistor is an exception because it is supposed to share a row number with a pin of another part (such as LED, etc.).
If different parts are on opposite sides of the breadboard (left vs. right), it is perfectly fine if they use the same row numbers because the left-hand rows are not connected to the right-hand rows.
Different pins from the same part should not be in the same row number. For example, the OLED display has 8 pins, and each of these pins must be in a different row number on the breadboard.
TIP: Try to place the jumper wires on the side closest to the Photon board, so the wires don't block parts that need to be seen or interacted with.
You can use one power rail on the breadboard to provide power to all the parts (similar to how a power strip works):
Connect a jumper wire from the 3.3V (+) pin on the Photon board to a pinhole in the positive (+) column of the power rail closest to the Photon board.
Then connect another jumper wire from a pinhole in the negative (-) column of this power rail back to a GND (-) pin on the Photon board.
All other parts that you add to the breadboard can connect to this power rail through their own jumper wires. Some parts will only need to connect to the negative (-) rail because their voltage source (+) will come from a digital pin. Other parts will need to connect to both the positive (+) and negative (-) rails.
IMPORTANT: The OLED display screen can only handle 3.3 volts of power, so be sure to use the 3.3V pin as your voltage source. (Caution: The V-USB pin supplies 5V, which could damage the OLED.)
The Micro OLED display requires using 7 jumper wires to connect the OLED pins to specific pins on the Photon board. Therefore, you should probably connect the OLED first before adding the other parts.
This reference for the Micro OLED display explains how to connect the OLED and provides example code for displaying text on the OLED screen.
The other parts can be connected to any of the other digital pins (or analog pins such as A0 or A1) that are not being used by the OLED.
This reference for the RHT03 sensor explains how to connect the RHT03 Humidity and Temperature Sensor and provides example code for taking readings with the RHT03 sensor.
If helpful, there are also references for the LED light and push button that show how to connect them and provide example code for using them.
Create a new app in Particle Build titled: SMART-THERMOSTAT
Remember that the structure and order of the code for a Photon app is:
libraries (if needed for certain inputs or outputs)
global variables
setup()
function (can only have one)
loop()
function (can only have one)
custom functions (as many as needed)
If helpful, here is additional information (and references) for coding Photon apps.
Be sure that you include the libraries for the Micro OLED display and the RHT03 sensor. The code examples in the Micro OLED reference and the RHT03 sensor reference explain how to include the library for each part.
Your app should declare global variables for each part's pin numbers (OLED, RHT03, both LEDs, both buttons) and declare objects for the OLED display and RHT03 sensor. The code examples in the references for the parts can help with this.
Be sure the pin numbers (such as: D0, D1, etc.) you list in your code match the actual pin that each part's jumper wire is connected to on the Photon board. If they don't match, it is usually easiest to fix it by changing your code (rather than moving your wire).
In addition, your app should also include these other global variables:
In your setup()
function, be sure to:
set the pin modes for your LEDs and buttons
turn off the LEDs at the start
start the OLED display and RHT03 sensor
include Particle.variable
statements to share these three variables with your web app: setTemp
, roomTemp
, systemStatus
include Particle.function
statements to allow your web app to call these two custom functions: tempUp
, tempDown
The code examples in the references for the parts can help with figuring out the pin modes, turning off the LEDs, and starting the OLED display and RHT03 sensor.
This Particle Cloud reference can help with the Particle.variable
and Particle.function
statements.
You can also refer back to the setup()
function in the final version of the Photon app for your Smart Lightbulb.
NOTE: If you have added the Particle.function
statements but haven't yet added the custom functions for tempUp
and tempDown
, Particle Build will say your app has errors when you try to verify the code. To avoid this, you can type two forward slashes directly before each Particle.function
statement to temporarily make them into comments. Later, you will need to remove these slashes once you've added the custom functions to your Photon app.
Good news – here is the entire code for your loop()
function:
However, you will have to create custom functions for: checkButtons()
, readTemp()
, compareTemp()
, displayTemp()
(as well as tempUp
and tempDown
)
NOTE: Until you create these custom functions, Particle Build will say your app has errors when you try to verify the code if you include the names of these functions inside your loop()
function. So in the meantime, you can either leave the loop()
function empty, or you can type two forward slashes directly before the name of each custom function listed inside the loop()
function to temporarily make them into comments. You will need to revise the loop()
function to match the code above once you've created the custom functions.
You will need to create the following custom functions:
checkButtons()
should read each button and call tempUp()
function if red button pushed and call tempDown()
function if blue button pushed
readTemp()
should update roomTemp
with new reading from RHT03 sensor
compareTemp()
should compare roomTemp
with setTemp
to decide whether system should be heating, cooling, or off (be sure to update systemStatus
and turn correct LEDs on or off)
displayTemp()
should use Micro OLED to display roomTemp
, setTemp
, and systemStatus
(add other text and adjust font size if needed to make information clear and easy to read)
tempUp()
should increase setTemp
by 1 but not allow it to go higher than maxTemp
tempDown()
should decrease setTemp
by 1 but not allow it to go lower than minTemp
Here is part of the code for your checkButtons()
function:
For help with your readTemp()
function, look at the code examples in the RHT03 sensor reference.
Here is part of the code for your compareTemp()
function:
For help with your displayTemp()
function, look at the code examples in the Micro OLED reference.
Remember that tempUp()
and tempDown()
are functions that your web app can call, so the code for these two functions is slightly different (they must return an integer value and accept a String value).
As an example, here is the complete code for your tempUp()
function:
Then you can copy and modify the code above to create your tempDown()
function.
IMPORTANT: If necessary, go back to your setup()
function to make sure your Particle.function
statements do not have two slashes before them. Also be sure that your loop()
function matches the code provided earlier.
Create a new HTML file (index.html), CSS file (style.css), and JavaScript file (code.js) using a code editor (such as Editey in Google Drive, etc.). Make sure the files are blank. Rename the folder containing the files as: Smart Thermostat
The pictures show screenshots for how the web app could possibly look (during four different states: connecting, cooling, off, heating). However, your web app doesn't have to look exactly like this – you can design your own screen layout as long as the necessary information and functions are present.
If necessary, refer to the System Features towards the top of this page to verify what the web app should do.
You should copy and modify the HTML used in the Smart Lightbulb web app.
In the <body>
, you should have a <div>
element to display the current thermostat information. Assign id="thermostat"
and class="off"
to this <div>
element.
This <div>
should contain <p>
elements to list the room temperature, temperature setting, and system status (Off, Heating, Cooling). Be sure to give each <p>
element a unique id name, so you can update their HTML using jQuery statements in your code.js and change their style using CSS declarations in your style.css
Be sure to include two <button>
elements to allow the user to increase and decrease the temperature setting: one should have onclick="raiseTemp();"
and the other should have onclick="lowerTemp();"
(these will run custom functions that you'll create in your code.js)
If necessary, here is a HTML reference for additional help on HTML element tags.
If you want, you can borrow and modify some of the CSS used in the Smart Lightbulb web app.
Add CSS declarations to style properties for your #thermostat
. For example, the CSS below will make it into a circle (by setting border-radius: 50%
).
Create a class for each system status: .off
, .heating
, .cooling
Each of these classes should set a background-color
that represents the system status.
You can add CSS declarations for other elements or id names to customize the layout and appearance of your web app, so it is easier and more enjoyable to use.
If necessary, here is a CSS reference for additional help on CSS syntax to declare style properties.
You should copy and modify the JavaScript used in the Smart Lightbulb web app.
It may be helpful to use the information and code examples in this Particle Cloud reference.
IMPORTANT: Remember to assign your Photon device id and access token to the JavaScript global variables for myDevice
and myToken
Be sure the webpage window is set to run the checkThermostat
function at an interval of every 200 milliseconds.
Your JavaScript code should have the following custom functions:
raiseTemp()
function should contain particle.callFunction
statement to call "tempUp"
function (with argument of "adjust"
) on your Photon device
lowerTemp()
function should contain particle.callFunction
statement to call "tempDown"
function (with argument of "adjust"
) on your Photon device
checkThermostat()
function should contain three separate particle.getVariable
statements to get current values for setTemp
, roomTemp
, and systemStatus
and use these to update the content and appearance of your web app
In each particle.getVariable
statement, the value of the requested Photon variable gets temporarily stored in a local variable called data.body.result
that you can use.
By referring to id names, jQuery statements (which always start with $
) can easily change the text inside an HTML element. For example, if the webpage contained <p id="#set-temp">
element, you could update its content with jQuery to display the word "Set " followed by the value stored in data.body.result
:
Here's how that jQuery statement would be used inside a particle.getVariable
statement:
You can also use if
and else if
statements to check the data.body.result
value, and then use jQuery statements to easily add or remove CSS classes:
If necessary, here is a JavaScript reference and a jQuery reference for additional help on their syntax and functions. Because jQuery is a JavaScript library, JavaScript statements can be combined together with jQuery statements.
After creating the code for the other custom functions in your JavaScript, test your web app with your Photon device. If everything is working, then congratulations...
If you have time, add a third button to the device and web app that allows the user to change the system mode (Off, Heat, Cool). For example, in the "Heat" mode, only the heating system (red LED) should be turned on or off by the device. You will have to modify your Photon app to make the device operate properly in each mode. Your device and web app should display both the system mode and system status. For example, the mode might be "Heat" but the status would be "Heat OFF" if the current room temperature is at or above the desired temperature setting.