MBED Thermostat

ECE 4180 Final Presentation

This program toggles a relay based on ambient temperature. The project allows the user to input a desired temperature via Bluetooth and includes an LCD screen to display to the user both ambient and desired temperatures. The idea is to hook up a space heater or fan to make this a kind of self regulating heating or cooling system.

Import

Import programThermostat

relay toggled by TMP36 and user-input pot temperature

Demo

Schematic

https://os.mbed.com/media/uploads/mknudson3/4180_project2.0_bb_ble.png

Parts

Code

main.cpp

#include "mbed.h"
#include "rtos.h"
#include "uLCD_4DGL.h"
 
#define DEBOUNCE_TIME 10 // 10 * 0.5 (main loop) = 5 seconds
 
uLCD_4DGL uLCD(p9,p10,p17); // serial tx, serial rx, reset pin;
 
BusOut leds(LED1, LED2, LED3, LED4);
DigitalOut relay(p21);
AnalogIn tmp36(p19);
AnalogIn pot(p20);
RawSerial  tooth(p28,p27);
 
volatile int currTemp, desiredTemp;
bool isHeating;
Mutex desiredTempLock;
 
bool setOrange;
bool setGray;
 
void setLCDGraphics(int temp) {
    if(setOrange) {
        uLCD.circle(64,64,61,WHITE);
        uLCD.filled_circle(64,64,60,0xF2A007);
        uLCD.locate(2,5);
        uLCD.text_width(1);
        uLCD.text_height(1);
        uLCD.text_mode(TRANSPARENT);
        uLCD.color(WHITE);
        uLCD.printf("mbed Thermostat\r\n\r\n     ");
        uLCD.text_width(4);
        uLCD.text_height(4);
        uLCD.printf("%d\r\n",currTemp);
        uLCD.text_width(1);
        uLCD.text_height(1);
        uLCD.locate(6,10);
        uLCD.printf("\r\n\r\n   Heating to:%d", desiredTemp);
    }
    else if(setGray) {
        uLCD.circle(64,64,61,WHITE);
        uLCD.filled_circle(64,64,60,0x969AE0);
        uLCD.locate(2,5);
        uLCD.text_width(1);
        uLCD.text_height(1);
        uLCD.text_mode(TRANSPARENT);
        uLCD.color(WHITE);
        uLCD.printf("mbed Thermostat\r\n\r\n     ");
        uLCD.text_width(4);
        uLCD.text_height(4);
        uLCD.printf("%d\r\n",currTemp);
        uLCD.text_width(1);
        uLCD.text_height(1);
        uLCD.locate(6,10);
        uLCD.printf("\r\n\r\n   Cooling to:%d", desiredTemp);
    }
    else if(!setOrange && !setGray) {
        uLCD.circle(64,64,61,WHITE);
        uLCD.filled_circle(64,64,60,0x255ECF);
        uLCD.locate(2,5);
        uLCD.text_width(1);
        uLCD.text_height(1);
        uLCD.text_mode(TRANSPARENT);
        uLCD.color(WHITE);
        uLCD.printf("mbed Thermostat\r\n\r\n     ");
        uLCD.text_width(4);
        uLCD.text_height(4);
        uLCD.printf("%d\r\n",currTemp);
        uLCD.text_width(1);
        uLCD.text_height(1);
        uLCD.locate(6,10);
        uLCD.printf("\r\n\r\n     Set to:%d", desiredTemp);
    }
}
 
//void compareTemp(void const *args) {
void compareTemp() {
    while(true) {
        if(currTemp > desiredTemp) {
            setGray = true;
            setOrange = false;
        }
        else if(currTemp < desiredTemp) {
            setOrange = true;
            setGray = true;
        }
        else if(currTemp == desiredTemp) {
            setOrange = false;
            setGray = false;
        }
        setLCDGraphics(currTemp);
        Thread::wait(5000);
    }
}
 
// Helper function
// convert tmp36 reading to degrees fahrenheit
int tmp2f() {
    return (tmp36 * 3.3 - 0.5) * 180 + 32;
}
 
void attemptToggle(Timer* timer, bool conditional) {
    if (!*timer) {
        timer->start();
    } else if (!conditional) {
        timer->stop();
        timer->reset();
    } else if (*timer >= DEBOUNCE_TIME) {
        timer->stop();
        timer->reset();
        isHeating = !isHeating;
    }
}
void bluetooth() {
    while(1){
        if (!tooth.readable()) Thread::yield();
        char bnum=0;
        char bhit=0;
        if (tooth.getc()=='!') {
            if (tooth.getc()=='B') { //button data packet
                bnum = tooth.getc(); //button number
                bhit = tooth.getc(); //1=hit, 0=release
                if (tooth.getc()==char(~('!' + 'B' + bnum + bhit))) { //checksum OK?
                    switch (bnum) {
                        case '5': //up arrow
                            if (bhit=='1') {
                                desiredTempLock.lock();
                                desiredTemp++;
                                desiredTempLock.unlock();
                            }
                            break;
                        case '6': //button 6 down arrow
                            if (bhit=='1') {
                                desiredTempLock.lock();
                                desiredTemp--;
                                desiredTempLock.unlock();
                            }
                            break;
                    }
                }
            }
        }
        Thread::wait(10);
    }
}
 
Thread bluetooth_thread;
Thread uLCD_thread;
int main() {
    
    desiredTemp = 72;
    
    bluetooth_thread.start(bluetooth);
 
    uLCD.display_control(LANDSCAPE);
    uLCD.cls();
    uLCD.baudrate(3000000); //jack up baud rate
    wait(1.0);
    uLCD.cls();
 
    uLCD_thread.start(compareTemp);
    
    bool shouldHeat = false;
    isHeating = false;
    
    Timer tMain, on, off;
    tMain.start();
    while(1) {
        if (tMain.read_ms() > 500) {
            tMain.reset();
            currTemp = tmp2f();
            shouldHeat = currTemp < desiredTemp;
            if (isHeating) attemptToggle(&off, !shouldHeat);
            if (!isHeating) attemptToggle(&on, shouldHeat);
            
            leds = relay = isHeating;
        }
    }
}
{{https://os.mbed.com/media/uploads/mknudson3/4180_project2.0_bb_ble.png}}

Team Members

  • Michael Knudson
  • Niket Patel
  • Chris Vanchev


Please log in to post comments.