Hi folks, thanks for your interest.
I am currently trying to use a Uno board with W5100 ethernet control a bank of 4 relays channels, via a hosted webpage.
The webpage is very basic, and works perfectly. I don't need any help with this.
The 3 buttons have three functions, as follows:
Door Toggle - momentarily closes Relay 1 to toggle the door opener
- turns on Relay 2 until a timer expires (currently 5 seconds for testing)
Inside light - turns on Relay 2, which runs a strip of LEDs inside the garage, until a timer expires
Outside light - turns on Relay 3, which runs a strip of LEDs outside the garage, until a timer expires
The basic code is there and it works fine, if I use the Delay command to drive the relays. But I don't want to use Delay, because it means that I can't press other buttons while the Delay is active. So I am trying to use millis instead, and it's not working!
I'm getting some weird behaviour - the timers clearly aren't working as required.
Relay 1 works as expected (uses Delay)
Relay 2 turns on when the webpage button is pressed, but never switches off again
Relay 3 seems to turn on really quickly and off again - but the code for both buttons is the same?
Can anyone see what's wrong with this code? I have spent hours reading about millis and syntax, I am reading the outputs from the serial monitor and I just don't seem to be able to nail down what's going wrong.
//3 button GET server code to control relays
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html
//for use with W5100 based ethernet shields
#include <SPI.h>
#include <Ethernet.h>
// assign relay codes to pins
#define RELAY1 6
#define RELAY2 7
#define RELAY3 8
#define RELAY4 9
unsigned long timerIn = 0; // long variable to store Timer 1 value
unsigned long timerOut = 0; // long variable to Store Timer 2 value
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = {
192, 168, 1, 150 }; // ip in lan
byte gateway[] = {
192, 168, 1, 1 }; // internet access via router
byte subnet[] = {
255, 255, 255, 0 }; //subnet mask
EthernetServer server(80); //server port
String readString;
//////////////////////
void setup()
{
// set up relay pins
pinMode(RELAY1, OUTPUT); // Set relay pins to output
pinMode(RELAY2, OUTPUT); // Repeat for relays 2 to 4
pinMode(RELAY3, OUTPUT);
pinMode(RELAY4, OUTPUT);
// initialise relays: note HIGH = relay off, LOW = relay on
digitalWrite(RELAY1, HIGH); // Set initial position of relay 1 output
pinMode(RELAY1, OUTPUT); // Write position to digital pin (prevents accidental toggle on startup)
digitalWrite(RELAY2, HIGH); // Repeat for relays 2 to 4
pinMode(RELAY2, OUTPUT);
digitalWrite(RELAY3, HIGH);
pinMode(RELAY3, OUTPUT);
digitalWrite(RELAY4, HIGH);
pinMode(RELAY4, OUTPUT);
Ethernet.begin(mac, ip, gateway, subnet); //start Ethernet
server.begin();
Serial.begin(9600); //enable serial data print
Serial.println("Initialisation complete"); //check that setup has completed (in serial monitor)
}
void loop(){
// Create a client connection
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char HTTP request
if (readString.length() < 100) {
//store characters to string
readString += c;
//Serial.print(c);
}
//if HTTP request has ended
if (c == '\n') {
//Webpage code (title and buttons)
Serial.println(readString); //print to serial monitor for debuging
client.println("HTTP/1.1 200 OK"); //send new page
client.println("Content-Type: text/html");
client.println();
client.println("<HTML>");
client.println("<HEAD>");
client.println("<meta name='apple-mobile-web-app-capable' content='yes' />");
client.println("<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />");
client.println("<link rel='stylesheet' type='text/css' href='http://homeautocss.net84.net/a.css' />");
client.println("<TITLE>Arduino Controller</TITLE>");
client.println("</HEAD>");
client.println("<BODY>");
client.println("<H1>Arduino Controller</H1>");
client.println("<hr />");
client.println("
");
client.println("<a href=\"/?buttonleft\"\">Door Toggle</a>");
client.println("<a href=\"/?buttoncentre\"\">Inside</a>");
client.println("<a href=\"/?buttonright\"\">Outside</a>
");
client.println("</BODY>");
client.println("</HTML>");
delay(1);
//stopping client
client.stop();
//Door Toggle button
if (readString.indexOf("?buttonleft") >0) //checks for 'left' button press - used to open garage door via momentary grounding
{
digitalWrite(RELAY1,LOW); // Turns on Relay 1 to toggle door
Serial.println("Left button pressed"); // serial monitor output confirmation
digitalWrite(RELAY2,LOW); // Turns on Relay 2 to toggle inside light
timerIn = millis(); // Sets timerIn to current millis to start timer
Serial.print("Indoor light timer = ");
Serial.println(timerIn); // serial monitor output confirmation
delay(500); // Wait 0.5 seconds for momentary grounding on Relay 1
digitalWrite(RELAY1,HIGH); // Turns Relay 1 Off - door toggle operation complete
Serial.println("Door toggle complete"); // serial monitor output confirmation
// note Relay 2 needs to be switched off using timerIn routine
readString=""; //clear string for next check
}
//Inside Light button operation
else if (readString.indexOf("?buttoncentre") >0) //checks for 'centre' button press - used to turn on inside light for preset period
{
digitalWrite(RELAY2,LOW); // Turns on Relay 2
Serial.println("Centre button pressed"); // serial monitor output confirmation
timerOut = millis(); // Sets timerOut to current millis to start timer
Serial.print("Indoor light timer = ");
Serial.println(timerIn); // serial monitor output confirmation
// note Relay 2 needs to be switched off using timerIn routine
readString=""; //clear string for next check
}
//Outside Light button operation
else if (readString.indexOf("?buttonright") >0) //checks for 'right' button press
{
digitalWrite(RELAY3,LOW); // Turns on Relay 3
Serial.println("Right button toggled"); // serial monitor output confirmation
timerOut = millis(); // Sets timerOut to current millis
Serial.print("Outdoor light timer = ");
Serial.println(timerIn); // serial monitor output confirmation
// note Relay 3 can also be switched off using timerOut routine
readString=""; //clear string for next check
}
// Relays switched off if timers have expired
else if (millis() >= timerIn + 3000)
{
digitalWrite(RELAY2,HIGH); // Turns Relay 2 Off
Serial.println("Inside timer expired"); // confirm toggle
}
else if (millis() >= timerOut + 3000)
{
digitalWrite(RELAY3,HIGH); // Turns Relay 3 Off
Serial.println("Outside timer expired"); // confirm toggle
}
else{
readString=""; //Clearing string for next read - probably not required, but left here just in case
}
}
}
}
}
}
All help greatly appreciated.