Web-controlled Window Air Conditioner Using an Arduino

/Web-controlled Window Air Conditioner Using an Arduino
Web-controlled Window Air Conditioner Using an Arduino2018-08-01T13:39:08+00:00

Project Description

Web-controlled Window Air Conditioner Using an Arduino

by Chris



Overview

It’s done. It works. The internet of things has come to my little apartment in New York City. After about a week of tinkering, soldering, and piecing together bits of code from here and there, I can now load a web page from any browser, see the current temperature in my apartment (and a graph of the last 12 hours), and turn the AC unit on or off with the click of a button. This was accomplished with an Arduino, the open-source prototyping platform and the community of artists, techies and hackers behind it. I’ll show you what it looks like, then I’ll show you how I put it all together (my code is at the bottom if you want to try it yourself! The End Results: The screenshots below are from the web server that is running on the arduino. It simply presents the temperature reading, the ON/OFF state of the Air Conditioner, and a graph from cosm.com of the last 24 hours of temperature readings. The readings are pushed up to cosm.com every 10 seconds. (The screenshots have some wild temperature fluctuations because I was hacking a bit, but the steady temperature you see for most of the day is accurate. The AC was off all day, but it was cool and rainy here in New York City today) This setup does require a dynamic dns name, and port forwarding on my router, which is not the sexiest way to do a remote control connection. It works, and I’ll leave the websockets and pusher.com connections for a later date.

Source

define APIKEY "INSERT API KEY HERE" // your cosm api key

define FEEDID INSERT FEEDID HERE // your feed ID

define USERAGENT "Cosm Arduino Example" // user agent is the project name//sets pin 7 to output, we flash an LED on pin 7 whenever the program uploads data

int ledPin = 7;//mac and ip address for the ethernet shield to use
byte mac

[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,8, 20);

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

//Initialize an ethernet client for the cosm uploader
EthernetClient cosm;

IPAddress server2(216,52,233,121); // numeric IP for api.cosm.com

unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000; //delay between updates to Cosm.com
//sets reference voltage to 3.3 volts instead of the default 5. The Ethernet sheild was drawig too much power, and was messing up the readings
void setup()
{
Serial.begin(9600); // open up serial port connection to PC
pinMode(8, OUTPUT); // Set digital pin 8 as output

// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();

analogReference(EXTERNAL);
}

void loop()
{
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
String buffer = ""; // Declare the buffer variable

while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.print(c); // Send every character read to serial port
buffer+=c; // Assign to the buffer

// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == 'n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();

// read the analog sensor:
float voltage = getVoltage(A0); //getting the voltage reading from the temperature sensor

//convert the voltage we just read into degrees farenheit
int temperature = tempCalc(voltage);

//these lines create the text of the web page
client.print("The indoor temperature is ");
client.print(temperature);
client.print(" degrees farenheit. ");
client.println("<br />");

//read analog pin 1, connected to the power LED on the Air Conditioner circuit board. Reading when off is always greater than 900, reading when on is always greater than 900.
int aread = analogRead(A1);
if (aread>900) {
client.print(" The AC is OFF");
}else{
client.print(" The AC is ON");
}
client.println("<br />");
client.print("Air Conditioner Remote Control by Chris");

client.println("<br />");

//Creates an HTML form with hidden input, and submit button that reloads the page with "?status=1" in the URL
client.print("<FORM action="http://YOUR EXTERNAL URL/" >");
client.print("<P> <INPUT type="hidden" name="status" value="1">");
client.print("<P> <INPUT type="submit" value="Power"> </FORM>");

//Creates an HTML form with a refresh button that reloads the page without any variables
client.print("<FORM action="http://YOUR EXTERNAL URL/" >");
client.print("<P> <INPUT type="submit" value="Refresh"> </FORM>");
client.print("<img src = 'https://api.cosm.com/v2/feeds/61098/datastreams/sensor1.png?width=500&height=250&colour=%230000cc&duration=1day&legend=Degrees%20Farenheit&title=Apartment%20Temperature&show_axis_labels=true&detailed_grid=true&scale=auto&timezone=UTC'>");

break;
}
if (c == 'n') {
// you're starting a new line
currentLineIsBlank = true;
buffer=""; // Clear the buffer at end of line
} else if (c == 'r') {
//if "?status=1" is found at the end of the URL, pulse pin 8 for 500ms, which will power the unit on or off
if(buffer.indexOf("GET /?status=1")>=0){
digitalWrite(8,HIGH); // Catch ON status and set LED
delay(500);
digitalWrite(8,LOW);

}

}
else {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}// End AC Control Section

//following code sends the temperature readings to a cosm.com feed every 10 seconds

float voltage = getVoltage(A0); //getting the voltage reading from the temperature sensor
//convert the reading into degrees farenheit
int temperature = tempCalc(voltage);

// if there's incoming data from the net connection.
// send it out the serial port. This is for debugging
// purposes only:
if (cosm.available()) {
char c = cosm.read();
Serial.print(c);
}

if (!cosm.connected() && lastConnected) {
Serial.println();
Serial.println("disconnecting.");
Serial.println(temperature);
float Aread = analogRead(A0);
Serial.print("Analog Reading from 0-1023: "); Serial.println(Aread);
float voltageCalc = Aread * 0.0032541666666667;
Serial.print("Millivolt Calculation: "); Serial.println(voltageCalc);
cosm.stop();
}

// if you're not connected, and ten seconds have passed since
// your last connection, then connect again and send data:
if(!cosm.connected() && (millis() - lastConnectionTime > postingInterval)) {
sendData(temperature);
}
// store the state of the connection for next time through
// the loop:
lastConnected = cosm.connected();

} //End Loop
// this method makes a HTTP connection to the server:
void sendData(int thisData) {
// if there's a successful connection:
if (cosm.connect(server2, 80)) {
Serial.println("connecting...");
// send the HTTP PUT request:
cosm.print("PUT /v2/feeds/");
cosm.print(FEEDID);
cosm.println(".csv HTTP/1.1");
cosm.println("Host: api.cosm.com");
cosm.print("X-ApiKey: ");
cosm.println(APIKEY);
cosm.print("User-Agent: ");
cosm.println(USERAGENT);
cosm.print("Content-Length: ");

// calculate the length of the sensor reading in bytes:
// 8 bytes for "sensor1," + number of digits of the data:
int thisLength = 8 + getLength(thisData);
cosm.println(thisLength);

// last pieces of the HTTP PUT request:
cosm.println("Content-Type: text/csv");
cosm.println("Connection: close");
cosm.println();

// here's the actual content of the PUT request:
cosm.print("sensor1,");
cosm.println(thisData);

//flash the LED for 1 second!
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);

}
else {
// if you couldn't make a connection:
Serial.println("connection failed");
Serial.println();
Serial.println("disconnecting.");
cosm.stop();
}
// note the time that the connection was made or attempted:
lastConnectionTime = millis();
}

/*
* getVoltage() - returns the voltage on the analog input defined by
* pin... using an odd calculation based on trial and error, comparing calculated temperatures to an external digital thermometer.
It should be 3.3v/1024/1000, but this is what gets us accurate readings. You may need to tweak this.
*/
float getVoltage(int pin){
return (analogRead(pin) * 0.0032541666666667
); //converting from a 0 to 1023 digital range
}

int getLength(int someValue) {
// there's at least one byte:
int digits = 1;
// continually divide the value by ten,
// adding one to the digit count for each
// time you divide, until you're at 0:
int dividend = someValue /10;
while (dividend > 0) {
dividend = dividend /10;
digits++;
}
// return the number of digits:
return digits;
}

//function to convert analog reading into degrees farenheit
int tempCalc(float reading) {
//convert analog reading to degrees celcius
float temp = (reading - .5) * 100;
//convert degrees celsius to farenheit
temp = ((temp * 9) / 5) + 32;

return temp;

Learn More

Goto Original


0 44 0

Leave a Reply