/*
Arduino Server
Author: Devin Pentecost
Date: July 5 2012
Last Edited: July 5 2012
Based off and borrowed from code by Randy Sarafan
http://www.instructables.com/id/Arduino-Ethernet-Shield-Tutorial/?ALLSTEPS
IP Address finding was made possible by the Arduino Forum Thread at:
http://arduino.cc/forum/index.php/topic,54378.0.html
More information can be found in the documentation.
To use:
http://%IP%/$%DURATION%
%IP% is the Arduino's IP Address
%DURATION% is the duration in ms
Note: Arduino has integer limits of -32768 to +32767
*/
#include <SPI.h>
#include <Ethernet.h>
//#define DEBUG_SERIAL
#define DEBUG_PRINT_TIME
//#define DEBUG_PRINT_IP
//#define DEBUG_NO_OUTPUT
//Some globals. All preference changes should be available here
static const int MIN_TIME = 0;
static const int MAX_TIME = 10000;
//IP Address. Use comma instead of period!
#define IP_ADDRESS 192,168,1,250
byte gateway[] = {
192, 168, 1, 1 };
byte subnet[] = {
255, 255, 255, 0 };
static const int R0_PIN = 8;
static const int R1_PIN = 9;
//////////////////////////////////////////////////////////////
//Prototypes
void activateBothRelays(void);
void activateRelay0(void);
void activateRelay1(void);
void deactivateBothRelays(void);
void deactivateRelay0(void);
void deactivateRelay1(void);
void checkUnlockRequest(void);
//Some vars
boolean incoming = 0;
unsigned long inputTime = 0;
boolean thisTime = 0;
byte requestIP[4];
//For keeping track of the unlock process. We have an array
//It contains whether or not it is running, set, as well as start/end times
unsigned long unlockRequest[4] = {
0, 0, 0, 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(IP_ADDRESS);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
void setup()
{
//Setup pins
pinMode(R0_PIN, OUTPUT);
pinMode(R1_PIN, OUTPUT);
digitalWrite(R0_PIN, HIGH);
digitalWrite(R1_PIN, HIGH);
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
#ifdef DEBUG_SERIAL
Serial.begin(9600);
#endif
}
void loop()
{
//We want to see if there is anything we need to take into account for the
checkUnlockRequest();
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
String time = "";
//Request the IP and store it
client.getIPAddress(&requestIP[0]);
while (client.connected()) {
if (client.available()) {
char c = client.read();
#ifdef DEBUG_SERIAL
Serial.print(c);
#endif
// 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) {
#ifndef DEBUG_NO_OUTPUT
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: application/json");
client.println("Connnection: close");
client.println();
//Output JSON
client.print("{");
client.print("\"timeRequested\":");
client.print(inputTime);
client.print(",\"requestIgnored\":");
client.print(!thisTime);
if(thisTime) thisTime = 0;
#ifdef DEBUG_PRINT_IP
client.print(",\"requestIP\":\"");
client.print(requestIP[0]);
for(int i = 1; i < 4; ++i){
client.print(".");
client.print((int)requestIP[i]);
}
client.print("\"");
#endif
#ifdef DEBUG_PRINT_TIME
client.print(",\"START.CURRENT.END\":\"");
client.print(unlockRequest[2]);
client.print(".");
client.print(millis());
client.print(".");
client.print(unlockRequest[3]);
client.print("\"");
#endif
client.println("}");
#endif
break;
}
//reads URL string from $ to first blank space
if(incoming && c == ' '){
incoming = 0;
//Are we not already requesting?
if(!unlockRequest[0]){
//We are done with the number parsing. We can change it to an int!
char charArray[time.length()+1];
time.toCharArray(charArray, time.length()+1);
inputTime = atoi(charArray);
//Put it in range
if(inputTime < MIN_TIME) inputTime = MIN_TIME;
if(inputTime > MAX_TIME) inputTime = MAX_TIME;
#ifdef DEBUG_SERIAL
Serial.print("\nInput Time: ");
Serial.println(inputTime);
#endif
//We want to tell ourselves we are requesting an open
//Mark the current time and the requested time
unlockRequest[0] = 1;
unlockRequest[1] = 0;
unlockRequest[2] = millis();
unlockRequest[3] = unlockRequest[2] + inputTime;
//Get this party started
thisTime = 1;
checkUnlockRequest();
}
}
if(c == '
){
incoming = 1;
}
//Checks for the URL Duration
if(incoming == 1){
if(c >= '0' && c <= '9'){
//Add to the time string
time += c;
}
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
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();
}
}
/*
activateBothRelays
Author: Devin Pentecost
Activates both of the relays
*/
void activateBothRelays(void){
//Enable both relays
digitalWrite(R0_PIN, LOW);
digitalWrite(R1_PIN, LOW);
#ifdef DEBUG_SERIAL
Serial.println("Both On");
#endif
}
/*
activateRelay0
Author: Devin Pentecost
Activates Relay 0 for a time, in ms
*/
void activateRelay0(int time){
//Enable relay 0
digitalWrite(R0_PIN, LOW);
#ifdef DEBUG_SERIAL
Serial.println("R0 On");
#endif
}
/*
activateRelay1
Author: Devin Pentecost
Activates Relay 0
*/
void activateRelay1(void){
//Enable relay 1
digitalWrite(R1_PIN, LOW);
#ifdef DEBUG_SERIAL
Serial.println("R1 On");
#endif
}
/*
deactivateBothRelays
Author: Devin Pentecost
Deactivates both of the relays
*/
void deactivateBothRelays(void){
//Disable both relays
#ifdef DEBUG_SERIAL
Serial.println("Both Off");
#endif
digitalWrite(R0_PIN, HIGH);
digitalWrite(R1_PIN, HIGH);
}
/*
deactivateRelay0
Author: Devin Pentecost
Deactivates Relay 0 for a time, in ms
*/
void deactivateRelay0(void){
//Disable R0
#ifdef DEBUG_SERIAL
Serial.println("R0 Off");
#endif
digitalWrite(R0_PIN, HIGH);
}
/*
deactivateRelay1
Author: Devin Pentecost
Deactivates Relay 0 for a time, in ms
*/
void deactivateRelay1(void){
//Disable R1
#ifdef DEBUG_SERIAL
Serial.println("R1 Off");
#endif
digitalWrite(R1_PIN, HIGH);
}
/*
checkUnlockRequest
Author: Devin Pentecost
Checks the unlock request and acts accordingly
*/
void checkUnlockRequest(void){
//Is the unlock request active?
if(unlockRequest[0]){
//We are requesting an unlock.
//Is it not already unlocked?
if(!unlockRequest[1]){
//Time to activate the request
unlockRequest[1] = 1;
//For now, we activate both of them
activateBothRelays();
}
else{
//Check and see if we are actually done
//Are we past the end of the request (Or somehow before the start?)
if( (millis() < unlockRequest[2]) || (millis() > unlockRequest[3]) ){
//Set ourselves as done with the request
unlockRequest[0] = 0;
}
}
}
else{
//We are not requesting an unlock.
//Is it already unlocked?
if(unlockRequest[1]){
//Time to deactivate the request
unlockRequest[1] = 0;
//For now, we deactivate both of them
deactivateBothRelays();
//Clear away old data
unlockRequest[2] = 0;
unlockRequest[3] = 0;
}
}
//Done
return;
}