Justin HarrellJohn R McAlpine V Mac
Published © GPL3+

AC Unit Temperature Switch - 3171 Project

This project reads the temperature in a room and switches the window AC unit on when it's hot and off when it's cool.

IntermediateShowcase (no instructions)8 hours343
AC Unit Temperature Switch - 3171 Project

Things used in this project

Hardware components

Photon
Particle Photon
×2
General Purpose Transistor NPN
General Purpose Transistor NPN
×1
Adafruit BMP280
×1

Software apps and online services

ThingSpeak API
ThingSpeak API

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Optional of course, but not a bad idea to solder the connections to the A/C

Story

Read more

Schematics

A/C Switcher Photon + Transistor

Temp Sensor Schematic

The BMP280 isn't shown on Fritzing, but for additional help, see the generalized code for ASCII drawings.

Code

Generic BMP280 Publisher

C/C++
// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_BME280/Adafruit_BME280.h"

/***************************************************************************
  This is a library for the BME280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME280 Breakout
  ----> http://www.adafruit.com/products/2650

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution

  This file was modified by Markus Haack (https://github.com/mhaack)
  in order to work with Particle Photon & Core.
 ***************************************************************************/


#define BME_SCK D4
#define BME_MISO D3
#define BME_MOSI D2
#define BME_CS D5

#define SEALEVELPRESSURE_HPA (1013.25)

//This Sketch measure differential pressure across the air filter in the house HVAC

/*                                    +-----+
 *                          +----------| USB |----------+
 *                          |          +-----+       *  |
 *                          | [ ] VIN           3V3 [ ] |
 *                          | [ ] GND           RST [ ] |
 *                          | [ ] TX           VBAT [ ] |
 *                          | [ ] RX  [S]   [R] GND [ ] |
 *                          | [ ] WKP            D7 [*] |
 *                          | [ ] DAC +-------+  D6 [*] |
 *                          | [ ] A5  |   *   |  D5 [*] |
 *                          | [ ] A4  |Photon |  D4 [*] |P1 PWR
 *                          | [ ] A3  |       |  D3 [*] |P2 PWR
 *                          | [ ] A2  +-------+  D2 [*] |
 *                      P1  | [*] A1             D1 [*] |SCL BME 0x76
 *                      P2  | [*] A0             D0 [*] |SDA BME 0x76
 *                          |                           |
 *                           \    []         [______]  /
 *                            \_______________________/
 *
 *
 */

/*
   This sample code demonstrates the normal use of a BME280 connected to Thingspeak
*/


Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

Timer timer(10000, checkEnvironment); // call this function every 10 seconds
Timer timer2(10000, serialDebug); // call this function every 10 seconds
Timer timer3(15000, updateThingspeak);

//global Vars

int caladdress = 0;
double bme280temp = 0;
double bme280baro = 0;
double bme280humidity = 0;
double bme280altitude = 0;
float analog1 = 0;
float analog2 = 0;
float analog3 = 0;
int count = 0;



const String key = "YOUR_KEY_HERE"; //thingspeak write key

//ApplicationWatchdog wd(5000, System.reset); //5 second application watchdog
SYSTEM_MODE(SEMI_AUTOMATIC);



ApplicationWatchdog wd(60000, System.reset);


void setup() {
  Serial.begin(230400);
  Serial.println(F("BME280 test"));

  /*if (!bme.begin(0x76)) {  //0x76 is the i2c address of the sensor
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }*/
  
  
  Particle.publish("DEBUG", "starting...");

  if (bme.begin(0x76)) {  //0x76 is the i2c address of the sensor
    Particle.publish("DEBUG", "starting the environment timer...");
    timer.start(); //initialize timer
    timer2.start();//initialize timer2
    timer3.start();//initialize timer2
  }
  else {
    Particle.publish("WARN", "Could not find a valid BMP280 sensor, check wiring!");
  }

  Particle.publish("DEBUG", "started!");
 
  Particle.connect(); 
  Particle.variable("bme280temp", bme280temp);
  Particle.variable("bme280hum", bme280humidity);
  Particle.variable("bme280bar", bme280baro);
  Particle.variable("bme280alt", bme280altitude);
  
  }

void loop() {
    digitalWrite(D7,!digitalRead(D7)); //blink D7
    wd.checkin(); //watchdog checkin
    
    if (System.buttonPushed() > 2000) { //trigger a wifi disconnect if you hold for over 2 seconds.
        //RGB.color(255, 255, 0); // YELLOW
        if (Particle.connected() == false) {  //if not connected, delay, 5000ms before attempting reconnect.  without delay was causing gps to fail.
            Serial.println("Connecting to wifi");
		    Particle.connect();
		    delay(1000);
        } else {
            //Particle.disconnect();
            WiFi.off();
            delay(1000);
        }   
    }
    analog1 = analogRead(A0);
    analog2 = analogRead(A1);
    analog3 = analogRead(A2);
}



void serialDebug() {
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");

    Serial.print("Pressure = ");

    Serial.print(bme.readPressure() / 100.0F);
    Serial.println(" hPa");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");

    Serial.println();
}

void checkEnvironment() {

  Particle.publish("RSSI", String(WiFi.RSSI()));
  //Particle.publish("DEBUG", "checking the environment...");

  //read sensor
  bme280temp = cToF(bme.readTemperature());
  bme280baro = pToHg(bme.readPressure());
  bme280altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
  bme280humidity = bme.readHumidity();

  //publish data
  
  //commented out to not overload particle publish.  only 4 allowed in a burst    
  //Particle.publish("environment/temperature2", String(bme280temp));
  //Particle.publish("environment/pressure2", String(bme280baro));
  //Particle.publish("environment/altitude2", String(bme280altitude));
  //Particle.publish("environment/humidity2", String(bme280humidity));
}

float cToF(float c) {
  return c * 9/5 + 32;
}

float pToHg(float p) {
  return p/3389.39;
}

/*******************************************************************************
 * Function Name  : updateThingspeak
 * Description    : sends variables to ts
 * Input          : doorstatus global variables
 * Output         : sends data to ts
 * Return         : void
                    
 *******************************************************************************/
bool updateThingspeak() 
{
    //delay (2000);
    count++;
    Serial.print("Updating Thingspeak:");
    Serial.print(count);
    
    int rssival = WiFi.RSSI();
    //sprintf(publishString,"%d",rssival);
    //bool success = Particle.publish("RSSI",publishString);
    
    //sprintf(publishString, "%1.4f", checkbattery());

      bool success = Particle.publish("thingSpeakWrite_All", +
     "{ \"1\": \"" + String(rssival) + "\"," +
       "\"2\": \"" + String(bme280temp) + "\"," +
       "\"3\": \"" + String(bme280humidity) + "\"," +
       "\"4\": \"" + String(bme280baro) + "\"," +
       "\"5\": \"" + String(bme280altitude) + "\"," +
       "\"6\": \"" + String(analog1) + "\"," +
       "\"7\": \"" + String(analog2) + "\"," +
       "\"8\": \"" + String(analog3) + "\"," +     
       "\"k\": \"" + key + "\" }", 60, PRIVATE);
    return success; //if sent, then turn of the send flag, otherwise let it try again.
    
}

Thingspeak Schema (JSON)

JSON
Choose the JSON option for creating a webhook in the Particle Console
{
    "event": "thingSpeakWrite_",
    "url": "https://api.thingspeak.com/update",
    "requestType": "POST",
    "form": {
        "api_key": "{{k}}",
        "field1": "{{1}}",
        "field2": "{{2}}",
        "field3": "{{3}}",
        "field4": "{{4}}",
        "field5": "{{5}}",
        "field6": "{{6}}",
        "field7": "{{7}}",
        "field8": "{{8}}",
        "lat": "{{a}}",
        "long": "{{o}}",
        "elevation": "{{e}}",
        "status": "{{s}}"
    },
    "mydevices": true,
    "noDefaults": true
}

High-Frequency Temperature Simulator

C/C++
This is just for simulating a rising and falling temperature for troubleshooting your setup.
#include "Particle.h"

float temp = 69.0000;
float adjust = 0.0;
int acOn = 0;
const String key = "YOUR_WRITE_KEY_HERE";
void setup()
{
    	
}
  
void loop()
{
    if(temp < 72 && acOn == 0) 
        adjust = random(400000)/1000000.0;
        
    else if(temp < 74 && acOn == 0)
        adjust = random(510000)/1000000.0;
    
    else
    adjust = -1.0*random(600000,1100000)/1000000.0;
    
    
    temp = temp + adjust;
    
    if(temp < 70)
        acOn = 0;
    else if(temp > 74)
        acOn = 1;
        
    Particle.publish("thingSpeakWrite_All", +
     "{ \"1\": \"" + String(temp) + "\"," +
       "\"2\": \"" + String(adjust) + "\"," +    
       "\"k\": \"" + key + "\" }", 60, PRIVATE);
    Particle.publish("AC_Simulator", String(acOn));
    Particle.process();
    delay(600000);
}

Subscribe Photon Code

C/C++
int led = D7;
int acON = 0;
int grog = D0;

void setup() {
    Particle.subscribe("AC_Simulator", myHandler);
    pinMode(led, OUTPUT);
    pinMode(grog, OUTPUT);
};

void myHandler(const char *event, const char *data) {
    if(strcmp(data, "0") == 0){
        if(acON == 1) {
            digitalWrite(led, HIGH);
            digitalWrite(grog, HIGH);
            delay(1000);
            digitalWrite(led, LOW);
            digitalWrite(grog, 0);
            acON = 0;
        };
        
    };
    if(strcmp(data, "1") == 0){
        if(acON == 0) {
            digitalWrite(led, HIGH);
            digitalWrite(grog, HIGH);
            delay(1000);
            digitalWrite(led, LOW);
            digitalWrite(grog, LOW);
            acON = 1;
        };
        
    };
    Particle.publish("DEBUG", "0", 60, PRIVATE);
    delay(5000);
    
};

Credits

Justin Harrell

Justin Harrell

1 project • 0 followers
Occasional builder of functional things.
John R McAlpine V Mac

John R McAlpine V Mac

12 projects • 49 followers
www.MACSBOOST.com Assistant Teaching Professor at UNC Charlotte MEGR3171 Instrumentation, Motorsports Research
Thanks to John McAlpine.

Comments