Remote Thermostat Controller

Nnenna Nwaigwe

Overview

A large rectangular wooden box with a blue rectangular LCD display which reads "Temperature: 50 degrees Fahrenheit" and small circular knob protruding from it (top middle), mess of multi-colored wires (middle), small black rectangular servo motor with a fin attachment (bottom left), and another small rectangular LCD display that reads "Temperature: 50 degrees Fahrenheit" (bottom right).

Final (Incomplete) Remote Thermostat Controller

Project Summary: For this project I attempted to create a device that could fit around my dorm room's existing analog thermostat and adjust its temperature setting based on a temperature input sent to it by a remote.

Remote Transmitter (Front View)

Remote Transmitter (Back View)

Remote Transmitter (Interior)

Remote Transmitter In Use

Thermostat Adjuster (Top View)

NnennaToo.MOV

In the video, I flip the remote power switch to ON and begin to rotate its temperature knob to the right to increase it's temperature setting. I then press down on the temperature knob to send this temperature input to a servo motor, which rotates to an angle between 0° and 180° depending on this temperature input. Similarly, I rotate another temperature knob that is directly attached to the servo motor left to increase the temperature setting and press down on the knob to send this temperature input to the servo motor.

Process

First radio transmission!

First (and Only) iteration of Remote Thermostat before construction of final prototype.

Testing final prototype circuitry with Arduino Pro Micro.

Final Thermostat Receiver using original Arduino microcontroller due to issues with the Arduino Pro Micro.

Ideation Process:

Discussion

words words words

Technical Information

Block Diagram

Remote Transmitter Schematic

Thermostat Receiver Schematic

Code

Remote Transmitter Code

/*

* Transmitter example code used written by

* Dejan Nedelkovski, www.HowToMechatronics.com

*

* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/

*/


#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

#include <ezButton.h>

#include <Encoder.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>


//Power Switch

ezButton powerSwitch(6);

const int SWITCHPIN = 6;


//Encoder

Encoder remoteEnc(3, 2);

int lastTemp;

int temp;

const int BUTTONPIN = 5;


//Radio

RF24 remote(7, 8);  // CE, CSN

const byte address[6] = "THERM";


//LCD

const int LCDTIMER = 200;

int NEXTTIMETORUN = 0;

LiquidCrystal_I2C screen(0x27, 16, 2);


//Custom Characters

byte Thermometer[8] = {

  0b01110,

  0b01110,

  0b01110,

  0b01110,

  0b01110,

  0b11111,

  0b11111,

  0b01110,

};


void setup() {

  Serial.begin(9600);


  //Power Switch Setup

  powerSwitch.setDebounceTime(100);



  //Remote Setup

  remote.begin();

  remote.openWritingPipe(address);

  remote.setPALevel(RF24_PA_MIN);

  remote.stopListening();

 

   //LCD Display Setup

  screen.begin(16, 2);

  screen.display();

  screen.backlight();

  screen.init();

  screen.home();

  screen.createChar(0, Thermometer);

}


void loop() {

  powerSwitch.loop();

  int switchState = !(powerSwitch.getState());

  if (switchState == 1) {

    int buttonState = !(digitalRead(BUTTONPIN));


    if (remoteEnc.read() > 90) {

      remoteEnc.write(90);

    } else if (remoteEnc.read() < 50) {

      remoteEnc.write(50);

    }


    int temp = remoteEnc.read();

    if (temp != lastTemp) {

      lastTemp = temp;

    }

    Serial.print("Temperature: ");

    Serial.println(temp);


    if (buttonState == 1) {

      remote.write(&temp, sizeof(temp));

    }

    if ((millis() - NEXTTIMETORUN) >= LCDTIMER) {

      //screen.clear();

      screen.setCursor(0, 0);

      screen.print("Temperature:");

      screen.setCursor(0, 1);

      screen.print(temp);

      screen.print((char)223);

      screen.print("F");

      screen.write(byte(0));

    }

  }

}

Remote Receiver

/*

* Receiver example code used written by

* Dejan Nedelkovski, www.HowToMechatronics.com

*

* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/

*/


#include <SPI.h>

#include <nRF24L01.h>

#include <RF24.h>

#include <Servo.h>

#include <Encoder.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>


//Radio

RF24 thermo(7, 8);  // CE, CSN

const byte address[6] = "THERM";

int remoteTemp;


//Servo

const int MOTORPIN = 6;

Servo motor;


//Encoder

Encoder wallEnc(3, 2);

int lastWallTemp;

int temp;

const int BUTTONPIN = 5;


//LCD

const int LCDTIMER = 200;

int NEXTTIMETORUN = 0;

LiquidCrystal_I2C screen(0x27, 16, 2);


//Custom Characters

byte Thermometer[8] = {

  0b01110,

  0b01110,

  0b01110,

  0b01110,

  0b01110,

  0b11111,

  0b11111,

  0b01110,

};


byte Smiley[8] = {

  0b00000,

  0b00000,

  0b00000,

  0b01010,

  0b00000,

  0b10001,

  0b01010,

  0b01110,

};


void setup() {

  Serial.begin(9600);


  //LCD Display Setup

  screen.begin(16, 2);

  screen.display();

  screen.backlight();

  screen.init();

  screen.home();

  screen.createChar(0, Thermometer);

  screen.createChar(1, Smiley);


  //Servo Motor Setup

  motor.attach(MOTORPIN);


  //Thermostat Wall Mount Setup

  thermo.begin();

  thermo.openReadingPipe(1, address);

  thermo.setPALevel(RF24_PA_MIN);

  thermo.startListening();

}


void loop() {

  //Check to see if you can read messages from remote

  if (thermo.available()) {

    thermo.read(&remoteTemp, sizeof(remoteTemp));

    int newTemp = map(remoteTemp, 50, 90, 0, 180);

    motor.write(newTemp);

  }


  //Read wall encoder position

  if (wallEnc.read() > 90) {

    wallEnc.write(90);

  } else if (wallEnc.read() < 50) {

    wallEnc.write(50);

  }

  int wallTemp = wallEnc.read();

  if (wallTemp != lastWallTemp) {

    lastWallTemp = wallTemp;

  }


  //Check if wall encoder button is pressed

  int buttonState = !(digitalRead(BUTTONPIN));

  if (buttonState == 1) {

    int newTemp = map(wallTemp, 50, 90, 0, 180);

    motor.write(newTemp);

  }


  if ((millis() - NEXTTIMETORUN) >= LCDTIMER) {

    screen.setCursor(0, 0);

    screen.print("Temperature:");

    screen.setCursor(0, 1);

    screen.print(wallTemp);

    screen.print((char)223);

    screen.print("F");

    screen.write(byte(0));

  }

}