Home Temperature Monitor

Made by Ben Smith

Develop and deploy a temperature monitor which provides ambient feedback to those in the home, detailed data and control via the Particle REST API, and data logging/visualization via Ubidots.com.

Created: January 24th, 2016



As with many apartments in the northeast United Stated, in my apartment there is no thermostat and both heating and AC are manually controlled. This results in a problem regularly faced by my wife in our apartment: when she turns the radiators on, the only signal that the home has sufficiently warmed up is when the home becomes uncomfortably hot. At this point, even with the radiators turned off, the home stays in an uncomfortable temperature range for a significant period of time. Both my wife and I are sensitive to home temperature, so preventing this overheating would reduce stress for both of us. Ideally, being able to close the radiators before the home temperature reaches an uncomfortable level would fulfill this need.


The goal of this project is to provide an ambient glanceable indicator if the home is too cold (blue LED), too hot (red LED), or just right (green LED). For control, set-point configuration would be completed through the Particle REST API. Lastly, logging the data in Ubidots provides a historical view of temperatures over time.



Process Step 1: Reading from the Temperature Sensor

Initially, work on this project began be developing a circuit and support code to gather temperature data from a Dallas DS18B20 direct to digital temperature sensor. This was completed utilizing readily available libraries from Github (OneWire.h and DS18B20.h). Example code was reviewed for guidance from the code posted by krvarma (https://github.com/krvarma/Dallas_DS18B20_SparkCore). This step involved significant challenges in locating and utilizing libraries which would compile in the Particle Dev desktop environment.

Process Step 2: Incorporating the dimmable RGB LED and Set-point Controls

Next, an RGB LED was incorporated to provide the ambient in-situ feedback. This was wired to the Particle Photon in a traditional manor. Additionally, code for cloud variables and functions for setting and displaying the high and low temperature set-points was incorporated. Further, a potentiometer was installed to reduce the brightness of the RGB LED when desired.

Process Step 3: Posting to Ubidots for Visualization

Lastly, the configuration of the Ubidots.com data storage and HTTP posting was completed. This step involved including the HTTPClient library and associated code to publish data points to Ubidots. In this case, the setup guide on Ubidots was used for sample code and instruction (http://ubidots.com/docs/devices/particle.html). Additionally, code to limit the frequency of data posting to Ubidots (one data point per 20 seconds) was implemented.



Ultimately, the above process yielded a fully functional working prototype which was operating and logged temperature from 10pm Sunday 1/24 through 7:30am Thursday 1/28. With the Ubidots data logging, we witnessed that the temperature over this 4 day period ranged from a high of 79F (radiators on) to a low of 61F (windows open). At those times both my wife and I were prompted into action (closing/opening windows and turning on/off the radiators) by the indicator LED. The LED became a low cognitive effort method for us to judge if the apartment temperature was in our mutually agreed temperature range. 

Thought this device is fully functional, additional development would be necessary to encase the prototype to blend in better with the home environment.

Note: In the code posted below, my personal Ubidots DeviceID and Variable Token have been replaced with XXXX and YYYY respectively.

#include "DS18B20.h"
#include "OneWire.h"
#include "HttpClient.h"

//Ubidots platform variables for reference
#define TOKEN "YYYY"

//OneWire Bus variables
DS18B20 ds18b20 = DS18B20(A0);
char szInfo[64];

//Variables for actual temperature and setpoints
double celsius = 0.0;
double fahrenheit = 0.0;
int highTempSet = 80;
int lowTempSet = 60;

//RGB LED pins and default values
int redPin = D0;
int greenPin = D1;
int bluePin = D2;
int redValue = 255;
int greenValue = 255;
int blueValue = 255;

//Potentiometer pins and LED brightness variables
int pothighPin = A2;
int potreadPin = A3;
int potlowPin = A4;
int potValue = 0;
int ledbrightness = 255;

//Initilize HttpClient
HttpClient http;
unsigned int nextTime = 0;

http_header_t headers[] = {
    { "Content-Type", "application/json" },
    { NULL, NULL } // NOTE: Always terminate headers will NULL

http_request_t request;
http_response_t response;

void setup()
  //Serial.begin(9600); //Debugging messages

  //Pot pinmodes, high/low pins
  pinMode(potlowPin, OUTPUT);
  digitalWrite(potlowPin, LOW);
  pinMode(pothighPin, OUTPUT);
  digitalWrite(pothighPin, HIGH);
  pinMode(potreadPin, INPUT);

  //Declare cloud variables to monitor
  //Particle.variable("celsius", celsius);
  Particle.variable("fahrenheit", fahrenheit);
  Particle.variable("highTempSet", highTempSet);
  Particle.variable("lowTempSet", lowTempSet);

  //Function for setting temperature setpoints via cloud
  Particle.function("setTempHigh", setTempHigh);
  Particle.function("setTempLow", setTempLow);

  //Assign pinModes
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);

  //HTTP setup
  request.hostname = "things.ubidots.com";
  request.port = 80;
  request.path = "/api/v1.6/variables/XXXX/values?token=YYYY";

void loop()
  //Checking OneWire devices
    //Serial.println("No more addresses.");


  //Checking if sensor upload to Ubidots is due
  if (nextTime > millis()) {


  //Pull current temperatures from ds18b20 library functions
  celsius = ds18b20.getTemperature();
  fahrenheit = ds18b20.convertToFahrenheit(celsius);

  //Check against setpoints and setting LED values
  if (fahrenheit >= highTempSet)
    analogWrite(redPin, ledbrightness);
    analogWrite(greenPin, 255);
    analogWrite(bluePin, 255);
  else if (fahrenheit <= lowTempSet)
    analogWrite(redPin, 255);
    analogWrite(greenPin, 255);
    analogWrite(bluePin, ledbrightness);
    analogWrite(redPin, 255);
    analogWrite(greenPin, ledbrightness);
    analogWrite(bluePin, 255);

  //Adjust HTTP post body
  request.body = "{\"value\":" + String(fahrenheit) + "}";

  // Post request
  http.post(request, response, headers);

  //Set delay before next cycle
  nextTime = millis() + 20000;

int setTempHigh(String command)
  int input = command.toInt();
  if (input <= lowTempSet)
    return -1;
  highTempSet = input;
  return 1;

int setTempLow(String command)
  int input = command.toInt();
  if (input >= highTempSet)
    return -1;
  lowTempSet = input;
  return 1;

int setBrightness()
  potValue = analogRead(potreadPin);
  ledbrightness = map(potValue, 0, 4095, 255, 0);
Click to Expand


Ultimately, this project was a great exercise in iterative development and exercising the strength of online documentation/resources. Learning the basics of the HTTPClient library for the purposes of posting data to Ubidots was especially rewarding. Further, exploring the pros and cons of online data management options (Particle Publish, Ubidots, Xively, etc…) was insightful to the public vs private key data posting methods. 
The only lingering challenge, though unnecessary to complete this project, is that I am as yet unable to address multiple DS18B20 temperature sensors on a single one-wire bus. There are limited examples of this practice online, particularly for the Particle/Spark platform. Further instruction or sample code to address multiple one-wire bus devices would help resolve this challenge.
Share this Project


49-713 Designing for the Internet of Things

· 4 members

This course charts the emergence of the now "connected world" to explore the possibilities for future products and connected spaces.

Focused on

Develop and deploy a temperature monitor which provides ambient feedback to those in the home, detailed data and control via the Particle REST API, and data logging/visualization via Ubidots.com.