Wouldn’t it be great to power stuff on and off without having to get off the couch, or even having to be in the same room? How about turning on an alarm with a distance sensor?
There are four methods to turn this powerbar on/off
While most of the other projects on this site are defined as having a single purpose, this project is more of a ‘seed’ – it can be used in many different ways, to satisfy many different needs. Other than its conventional switch, there are four methods to turn this powerbar on/off:
- Infrared
- Temperature
- Ethernet
- Proximity
Essentials:
Using its I/O pins, the Arduino detects the various inputs from the external components – an infrared receiver, a temperature sensor, an Ethernet shield, and a distance sensor. When the condition is met – for example, the remote control button is pushed, temperature is high enough, distance is close enough – the Arduino sends 5V to the relay (located inside the powerbar), which activates the powerbar. The relay is rated for 10A.
This project started out with one sensor (the IR receiver) – dictating the state of the powerbar. But then another sensor was added which lent more capabilities to the project, and soon others followed. Not all the sensors are required to make the powerBar function; it is up to the end user which method to use. For example, you probably don’t need a distance sensor to warm up your engine block. Or an ethernet shield if you are simply turning on a fan across the room. But I have used all of these at one time or another: ethernet to power a light while I’m on vacation, IR to turn on a fan across the room in the middle of the night, proximity to surprise people… And other sensors are waiting: why not a moisture detector to prevent a flood in your basement?
Here it is in action, using IP, IR, and motion to turn on and off:
CODE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
/* http://creativetechnical.ca/powerbar/ Allows you to turn on/off anything connected to a powerbar. Methods of control include proximity, temperature, Ethernet, and IR. Who's in charge? Remote tells Arduino to react to different sensors (distance or temperature). Ethernet will work regardless. Remote on/off will work regardless. To use on 'External' network (WAN), router must be provisioned as such. Note: Compiles with Arduino 1.0.5-r2, but not 1.6.7. Circuit: Ethernet shield attached to pins 10, 11, 12, 13 TSOP 4038 (IR receiver) attached to pin 7 TMP36 (temperature sensor) attached to pin A3 Connect a relay to pin 2/GND //////////////////////////////////////////////////////////////////////////////////////////////////// Credit to Ken Shirriff: http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html Using Apple Remote: 2011287688 + 2011279496 - 2011242632 play 2011238536 << 2011291784 >> 2011250824 menu */ #include <IRremote.h> #include <SPI.h> #include <Ethernet.h> #include <NewPing.h> int tempsensorPin = 3; //analog pin 3 receives data from TMP36 //the resolution is 10 mV / degree centigrade with a //500 mV offset to allow for negative temperatures int RECV_PIN = 7; //pin 7 receives raw data from TSOP 4038 (IR receiver) int relayTrigger = 2; //pin 2 triggers the relay on or off IRrecv irrecv(RECV_PIN); decode_results results; #define PLAY 2011242632 //pushing 'play' on remote gives me this value; it makes more sense when replaced with PLAY #define MENU 2011250824 //pushing 'menu' on remote gives me this value; it makes more sense when replaced with MENU #define TRIGGER_PIN 9 //pin 9 tied to trigger pin on the ultrasonic sensor. #define ECHO_PIN 8 //pin 8 tied to echo pin on the ultrasonic sensor. #define MAX_DISTANCE 200 //Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm. NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); //NewPing setup of pins and maximum distance. boolean incoming = 0; // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 }; IPAddress ip(192,168,0,111); //<<< ENTER YOUR LOCAL IP ADDRESS HERE!!! // Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80); //setup runs once, at start/////////////////////////////////////////////////// void setup() { Ethernet.begin(mac, ip); //start the Ethernet connection and the server: server.begin(); Serial.begin(9600); //Open serial monitor at 9600 baud to see ping, IR & temperature results. irrecv.enableIRIn(); //Start the IR receiver pinMode(relayTrigger, OUTPUT); //set pin for output digitalWrite(relayTrigger, LOW); //open relay contacts } ///////////////////////////////////////////////////////////////////////////// void onRelay() { digitalWrite(relayTrigger, HIGH); } ///////////////////////////////////////////////////////////////////////////// void offRelay() { digitalWrite(relayTrigger, LOW); } ///////////////////////////////////////////////////////////////////////////// //loop runs forever////////////////////////////////////////////////////////// void loop() { if (irrecv.decode(&results)) { Serial.print("Remote Code: "); Serial.println(results.value); //Open serial monitor, and view remote codes. I used 'play' on Apple remote = 2011242632 irrecv.resume(); //Receive the next value } if (results.value == PLAY) //If Apple remote button 'play' is pushed, then: { onRelay(); //trigger the relay, turn powerbar on results.value = 0; //if we don't replace PLAY (2011242632) in results.value, the relay will keep switching on } if (results.value == MENU) //If Apple remote button 'menu' is pushed, then: { offRelay(); //turn powerbar off results.value = 0; //if we don't replace 'menu' in results.value, the relay will keep switching off } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //ETHERNET// // listen for incoming clients EthernetClient client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); // 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 //reads URL string from $ to first blank space if(incoming && c == ' ') { incoming = 0; } if(c == '$') { incoming = 1; } //Checks for the URL string $1 or $2 if(incoming == 1) { Serial.println(c); if(c == '1') { Serial.println("ON"); digitalWrite(2, HIGH);//onRelay(); client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html><h1>Device On</h1><br>"); client.println("<h2>Internal:</h2>"); client.println("<p><a href='http://192.168.0.111:80'>Connect via 192.168.0.111:80</a><br>"); client.println("<a href='http://192.168.0.111:80/$1'>Turn On</a><br>"); client.println("<a href='http://192.168.0.111:80/$2'>Turn Off</a><br><br>"); client.println("<h2>External:</h2>"); client.println("<p><a href='http://70.72.36.29:1515'>Connect via 70.72.36.29:1515</a><br>"); client.println("<a href='http://70.72.36.29:1515/$1'>Turn On</a><br>"); client.println("<a href='http://70.72.36.29:1515/$2'>Turn Off</a><br></html>"); // give the web browser time to receive the data delay(1); // close the connection: client.stop(); } if(c == '2') { Serial.println("OFF"); digitalWrite(2, LOW);//offRelay(); client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html><h1>Device Off</h1><br>"); client.println("<h2>Internal:</h2>"); client.println("<p><a href='http://192.168.0.111:80'>Connect via 192.168.0.111:80</a><br>"); client.println("<a href='http://192.168.0.111:80/$1'>Turn On</a><br>"); client.println("<a href='http://192.168.0.111:80/$2'>Turn Off</a><br><br>"); client.println("<h2>External:</h2>"); client.println("<p><a href='http://70.72.36.29:1515'>Connect via 70.72.36.29:1515</a><br>"); client.println("<a href='http://70.72.36.29:1515/$1'>Turn On</a><br>"); client.println("<a href='http://70.72.36.29:1515/$2'>Turn Off</a><br></html>"); // give the web browser time to receive the data delay(1); // close the connection: client.stop(); } } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html><h1>Select From Below:</h1><br>"); client.println("<h2>Internal:</h2>"); client.println("<p><a href='http://192.168.0.111:80'>Connect via 192.168.0.111:80</a><br>"); client.println("<a href='http://192.168.0.111:80/$1'>Turn On</a><br>"); client.println("<a href='http://192.168.0.111:80/$2'>Turn Off</a><br><br>"); client.println("<h2>External:</h2>"); client.println("<p><a href='http://70.72.36.29:1515'>Connect via 70.72.36.29:1515</a><br>"); client.println("<a href='http://70.72.36.29:1515/$1'>Turn On</a><br>"); client.println("<a href='http://70.72.36.29:1515/$2'>Turn Off</a><br></html>"); // give the web browser time to receive the data delay(1); // close the connection: client.stop(); } else if (c != '\r') { // 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(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// //TEMPERATURE SENSOR// //getting the voltage reading from the temperature sensor int reading = analogRead(tempsensorPin); // reading = constrain(reading, 0, 500); // Serial.print(reading); Serial.println(" = reading"); if (reading >= 200) //readings of 150-170 are normal, throw away spikes { Serial.println("SPIKE"); } else { // converting that reading to voltage float voltage = reading * 5.0; voltage /= 1024.0; // print out the voltage // Serial.print(voltage); Serial.println(" volts"); // now print out the temperature float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree with 500 mV offset //to degrees ((voltage - 500mV) times 100) Serial.print(temperatureC); Serial.println(" degrees C"); if (results.value == 2011238536) //<< LEFT // If this button is pushed, temperature sensor dictates powerBar state { if (temperatureC >= 29) //is greater than 29 { onRelay(); } else { offRelay(); } } } delay(200); //////////////////////////////////////////////////////////////////////////////////////////////////////////// //Distance sensor// delay(100); // Wait 100ms between pings (about 10 pings/sec). 29ms should be the shortest delay between pings. unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS). Serial.print("Distance from object: "); Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range) Serial.println("cm"); // Serial.print("Remote Code: "); // Serial.println(results.value); if (results.value == 2011291784) // >> RIGHT // If this button is pushed, the distance sensor dictates powerBar state { if ((uS / US_ROUNDTRIP_CM > 0) && (uS / US_ROUNDTRIP_CM < 30)) { onRelay(); delay(500); } if ((uS / US_ROUNDTRIP_CM == 0) || (uS / US_ROUNDTRIP_CM > 40)) { offRelay(); delay(500); } } } |