KellyKeeton dot Com v3.0 reverse engineering life

6Aug/1369

WebPower an Arduino-Webduino Relay Switcher

In a quest to operate my ham radio shack remotely, one thing I needed to accomplish was remote power for various devices. I have looked into multiple solutions however they are expensive and normally don't fit the bill just as I need them to. My requirements for this project..
1) Cheap, 2) Easy, 3) Flexible

I had a few spare Arduino

Arduino
's sitting around with a few EthernetPiggy boards. So thats the cheap part, priced out on ebay for $20 you can pick up the pair of boards from China, double check! Additionally I looked into some of the pre-made units. For example West Mountian Radios Rigrunner.
West Mountian Radios Rigrunner.
Real nice unit, but the price is a little hot and with a limit of four ports and 40A on the DC circuit I am a bit limited in flexibility. Then you have the AC only version, the web power switch
AC only version, the web power switch
Also the most affordable way to go about it I have found. Same with the OpenSource Hardware Project
OpenSource Hardware Project
WebPower Strip, however the quality manufactured version is highly preferred to this messy looking thing.

So back to the Arduino, I had it here in a junk box, I also had some 2-Channel Relay boards.. that are Optioisoloated real nice units. sitting in the junk box (more on why this is cool later)

After some toying around I came to the conclusion that the Webduino Library was the best for the situation, allowing POST and Auth with no effort from myself. About 30 hours of programming later, some help from jQuery.. I have a version 1.0!.

WebPower Screenshot

The app will allow you to operate form any browser or cell phone. You can quickly change power on and off to multiple relays (5 by default code) The code also allows Pulse Width Relay and Latch relay settings. Pulse width would be to interface with something like a Solid State unit that has no easy way to power on and off by switching line voltage.

Additionally the relay's can be DC relays at XXAmps that you choose, the AC can be traditional or Solid state relays, its a mix and match pick and build as you go platform!

The other option about this I like is back to those 2-relay units.. I can build switching boxes around my ham radio shack, putting the relay as close to the load as possible, while keeping the brains away.. thus preventing RFI, and EMI from the load into the Arduino!

Hooking up any relay you want is rather simple.. if its not a solid state unit, but uses a coil I recommend this method.
drive relay

For Solid State Relays, simply connect to the Arduino directly, optionally insurance is a Metal Oxide Varistor(MOV) across the load side of the Relay (the high voltage) to prevent inductive blow back.

Other Minor features are the code can handle web-authentication to keep accidents from happening, the code can quickly be adapted to NO/NC HIGH/ON HIGH/OFF relay configurations. The PWM can be adjusted quickly, its capable of being on the internet and uses POST, there is no server or other hardware required, runs on the Arduino 100% (which has limitations, but hey its cheap hardware). I look forward to any feedback and hope this code is useful to you in some way!

If you find this valuable please donate!

The source code below.

/* WebPower 1.30
WebPower (c)2013 Kelly Keeton http://www.kellykeeton.com/
code modified used from http://brwry.com/2012/04/storing-settings-between-brews/
 
This application will run on a Arduino with a WizArd compatible ethernet shield.
The Arduino will server up a jQuery enhanced website using webduino for switching on and off relays
The relays can be connected to any number of applications. Most Specific it was intended
for remote automation of utility main's power for home automation.
 
You will need the webduino library in your Arduino /library folder to compile;
built in Arduino 1.5.4 and webduino 1.7 (you will need to restart IDE to load)
 
https://github.com/sirleech/Webduino
 
The application also has functionality for Push Button, which is essentially a pulse rather
then a latch of a relay, this is useful for hooking up to items that need turned on and off
with a time delay on the power button.
 
This code assumes the use of a 2x2 or 1x4 optio-isolator relay module. for a max of 7 relays
(I am out of memory in default code to add more) Any use of high voltage or damage to your hardware is not my fault.
I assume no risk or responsibility for the quality of this code.
 
To enable auth look below and change the settings accordingly. you will need to base 64 encode your creds.
 
Currently I am not saving the Port Name to EEPROM, if you have suggestions on how to accomplish
this quickly let me know, I just haven’t done it yet.. until then you can edit the relayUse array below
change 'Undefined' To your port name after reboot, Port1,Port2... etc.
 
To use this, enter the following USLs into your browser.
Replace "host" with the IP address assigned to the Arduino. (variables below)
 
http://host/
 
These URLs brings up a display of the values READ on digital pins
This is done with a call to defaultCmd.
 
http://host/webpower
 
This URL also brings up a display of the values READ on digital pins
But it's done as a form, by the "formCmd" function,
and the digital pins are shown as radio buttons you can change.
When you click the "Submit" button, it does a POST that sets the
digital pins, re-reads them, and re-displays the form.
 
http://host/settings
 
This URL will assign the pins to relays, by default all relays are disabled
this pin to relay information is stored on your Arduino EEPROM
Note: 255 is the default and that means the Item is not active.
 
ChangeLog:
1.00 Initial release
1.01 Changes in documentation and increased pin use to 7 with some memory cleanup, refresh
1.02 BugFixes and corrections to documentation
1.10 New Features Added a Analog Pin reading and print to screen to monitor device LED's ect (for pulsed relays mostly)
 Also added physical "on/off" buttons for local control.. increment and decrement on off with a rocker switch
 Memory enhancments (put more values to EEPROM Pwrite)
1.20 added logic so that latch relays dont get confusing for on/off to enhance latch relays you should use external sensors
 analog sensors are commented out in the 'void displayPins' below (advanced editing no documentaion)
1.21 updated status cache control per olli's suggestions
1.30 some modifications from the comments on the blog from Dan and Bill
 
*/
#define WEBDUINO_FAIL_MESSAGE "<h1>Request Failed</h1>"
#define WEBDUINO_SERVER_HEADER "Server: WebPower/"
#define WEBDUINO_AUTH_REALM "WebPower"
#define WEBDUINO_SERIAL_DEBUGGING 0
#define PREFIX ""
#include "SPI.h"
#include "Ethernet.h"
#include "WebServer.h"
#include <EEPROM.h>
 /* CHANGE THIS TO MATCH YOUR HOST NETWORK. Most home networks are in
 * the 192.168.0.XXX or 192.168.1.XXX subrange. Pick an address
 * that's not in use and isn't going to be automatically allocated by
 * DHCP from your router. */
static uint8_t ip[] = {10,42,42,55};
static uint8_t gateway[] = {10,42,42,1};
static uint8_t subnet[] = {255,255,255,0};
static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
 /* The following should be updated as required
 * The relayUse array human object names for the Relay Function
 */
String relayUse[] = {"Undefined","Undefined","Undefined","Undefined","Undefined","Undefined","Undefined"}; //defaults for pin names. EEPROM write not emplimented for this yet.
boolean invertOO = true; //if your using different hardware setup or relay boards your HIGH might be ON or OFF(or NO/NC) just switch this (global settings)
#define THEME "a" //options a-e see http://jquerymobile.com/demos/1.2.1/docs/pages/pages-themes.html
 //the following variables are normally not changed proceed undocumented
 //
const int PulseTime = 500; // time in miliseconds for pulse high width:global setting
WebServer webserver(PREFIX, 80); // port webserver will listen on HTTP default is port 80
const char* AUTHENTICATION = "YWRtaW46YWRtaW4="; //admin:admin Base64-encoded
boolean AUTHENABLED = false; //use Auth on Switching and settings Page
#define MAXrelay 7 //the upper limit of PINS that will be used (memory constraints)
boolean relayAtBoot = LOW; // for high or low state at boot of code, typically not changed as invert deals
boolean HardwareControl = true; // enable hardware buttons for ON off
#define AnalogONpin A0 //pin for analog on button
#define AnalogOFFpin A1 //pin for analog off button
boolean AnalogEnabled = true; // enable printing the output of analog pins to the root webpage used for reading device LED woth optioresistor for "on off" status etc..
#define Analog1Pin A2 //pin for analog reading
#define Analog2Pin A3 //pin for analog reading
#define Analog1UpperValue 900 //the upper value for analog reading after this point will flip to "on" vs off
#define Analog2UpperValue 900 //the upper value for analog reading after this point will flip to "on" vs off
boolean Analog1 = false; //false = off
boolean Analog2 = false; //false = off
unsigned long previousMillis = 0;
P(htmlHead) =
"<!DOCTYPE html><html><head>"
"<title>WebPower</title>"
"<meta name='viewport' content='width=device-width, initial-scale=1'>"
"<META HTTP-EQUIV='CACHE-CONTROL' CONTENT='NO-CACHE'>"
"<link rel='stylesheet' href='http://code.jquery.com/mobile/1.2.1/jquery.mobile-1.2.1.min.css' />"
"<script src='http://code.jquery.com/jquery-1.8.3.min.js'></script>"
"<script src='http://code.jquery.com/mobile/1.2.1/jquery.mobile-1.2.1.min.js'></script>"
"</head><body>"
"<div data-role='page' data-theme='"THEME"'>"
"<div data-role='header'><a href='/'>PowerStatus</a><center>WebPower</center><a href='/webpower'>SwitchPower</a></h1></div><!-- /header -->"
"<div data-role='content'>";
P(htmlFooter) = "<!-- /content --></div><!-- /page --></body></html>";
P(endrefresh)="<button id='PageRefresh'>Refresh</button><script type='text/javascript'>$('#PageRefresh').click(function() {location.reload();});</script>";
// the following are system variables
static uint8_t relayPinAddressStart = 255; //default pis status for EEPROM
static uint8_t relayTypeAddressStart = 0; //default pin type for EEPROM
uint8_t relayPin[] = {9,8,7,6,5,4,3}; //the default pins to relay (stored in EEPROM after you change in web)
uint8_t relayType[] = {0,0,0,0,0,0,0}; //the default pin type relay-0 or PWM-1 (stored in EEPROM after you change in web)
uint8_t aio = 1;
uint8_t aif = 1;
P(analog1ON) = "Analog Sensor 1 <font color='green'>ON</font>";
P(analog2ON) = "Analog Sensor 2 <font color='green'>ON</font>";
P(formStart) = "<form action='" PREFIX "/webpower' method='post'><center>";
P(formEnd) = "<input type='submit' value='Submit'/><input type='reset' value='Reset'></form>";
P(spacer) = "<fieldset data-role='controlgroup' data-type='horizontal'>";

template<class T> // no-cost stream operator as described at http://arduiniana.org/libraries/streaming/
inline Print &operator <<(Print &obj, T arg)
{
 obj.print(arg);
 return obj;
}
 
void outputPins(WebServer &server, WebServer::ConnectionType type, bool addControls = false) //main web routine
{
server.httpSuccess();
server.printP(htmlHead);
 
if (addControls)
 {
 server.printP(formStart);
 }
 for (int i = 1; i <= MAXrelay; ++i)
 {
 if (relayPin[i-1] >= 0 && relayPin[i-1] <= 53)
 {
 if (relayType[i-1] == 0)
 {
 String displayName;
 if (relayUse[i-1].equalsIgnoreCase("Undefined")){
 displayName = String("LatchRelay-" + String(i,DEC) + " ");
 }
 else {
 displayName = String(relayUse[i-1] + " ");
 }
 displayPins(server, relayPin[i-1], relayType[i-1], displayName, addControls);
 }
 else if (relayType[i-1] == 1)
 {
 String displayName;
 if (relayUse[i-1].equalsIgnoreCase("Undefined")){
 displayName = String("PulseRelay-" + String(i,DEC) + " ");
 }
 else {
 displayName = String(relayUse[i-1] + "* ");
 }
 displayPins(server, relayPin[i-1], relayType[i-1], displayName, addControls);
 }
 }
 }
//display analog controls
if (AnalogEnabled && Analog1 ) {
 server.printP(analog1ON);
}
if (AnalogEnabled && Analog2 ) {
 server.printP(analog2ON);
}
server << "</center></p>";
 
if (addControls)
 {
 server.printP(formEnd);
 }
 else
 {
 server.printP(endrefresh);
 }
server.printP(htmlFooter);
}
 
void settingsPage(WebServer &server, WebServer::ConnectionType type) //settings only page
{
 if(!server.checkCredentials(AUTHENTICATION) && AUTHENABLED)
 {
 server.httpUnauthorized(); //not authenticated
 }
 else //authenticated
 {
server.httpSuccess();
server.printP(htmlHead);
server << "<form action='" PREFIX "/settings' method='post'>";
char pinName[4];
 
for (int i = 1; i <= MAXrelay; ++i)
 {
 server << "<label>Relay Port " << i << "<input type='text' name='u" << i << "' value='" << relayUse[i-1] << "'>" << " Pin: <input type='text' name='h" << i << "' value='" << relayPin[i-1] << "'></label><br/>";
 pinName[0] = 'e';
 itoa(i, pinName + 1, 10);
 server.radioButton(pinName, "0", "Latched Relay(LR)", !relayType[i-1]);
 server << " ";
 server.radioButton(pinName, "1", "Pulse Relay(PR)", relayType[i-1]);
 server << "<br/>";
 }
server << "<input type='submit' value='Submit'/></form>";
server.printP(htmlFooter);
 }
}
void settingsCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) //settings post handler
{
 if (type == WebServer::POST)
 {
 bool repeat;
 char name[MAXrelay*3], value[MAXrelay*3];
 do
 {
 repeat = server.readPOSTparam(name, MAXrelay*3, value, MAXrelay*3);
 int pin = strtoul(name + 1, NULL, 10);
 int val = strtoul(value, NULL, 10);
 String valueString = String(value);
 
 if (name[0] == 'h') //pinNumber
 {
 if (EEPROM.read(relayPinAddressStart+pin-1) == val)
 {
 //do nothing no change in value
 } else {
 if (relayPin[pin-1] > 0 && relayPin[pin-1] <=53)
 {
 digitalWrite(relayPin[pin-1], LOW); //make sure pin is off before overwritting it
 }
 relayPin[pin-1] = val;
 EEPROM.write(relayPinAddressStart+pin-1,val);
 }
 }
 if (name[0] == 'e') //relay type
 {
 if (EEPROM.read(relayTypeAddressStart+pin-1) == val)
 {
 //do nothing no change in value
 } else {
 relayType[pin-1] = val;
 EEPROM.write(relayTypeAddressStart+pin-1,val);
 }
 }
 if (name[0] == 'u') //relay common name
 {
 relayUse[pin-1] = valueString;
 }
 
}
 while (repeat);
 
server.httpSeeOther(PREFIX "/settings");
 }
 else
 settingsPage(server, type);
}
 
void webpowerCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) // generic post handler and pin writer
{
 if (type == WebServer::POST)
 {
 bool repeat;
 char name[MAXrelay], value[MAXrelay];
 do
 {
 repeat = server.readPOSTparam(name, MAXrelay, value, MAXrelay);
 if (name[0] == 'd')
 {
 int pin = strtoul(name + 1, NULL, 10);
 int val = strtoul(value, NULL, 10);
 int pinindex = -1;
 
 for( int a = 0; a<MAXrelay ; a++ )
 {
 if (pin == relayPin[a]) {
 pinindex = a;
 break;
 }
 }
 if (relayType[pinindex] == 0)
 {
 if (invertOO){ digitalWrite(pin, !val); } else { digitalWrite(pin, val); }
 }
 else
 {
 if (val){
 if (invertOO){ digitalWrite(pin, !val); } else { digitalWrite(pin, val); }
 delay(PulseTime);
 if (invertOO){ digitalWrite(pin, val); } else { digitalWrite(pin, !val); }
 }
 }
 }
 }
 while (repeat);
 
server.httpSeeOther(PREFIX "/webpower");
 }
 else
 
 if(!server.checkCredentials(AUTHENTICATION) && AUTHENABLED)
 {
 server.httpUnauthorized(); //not authenticated
 }
 else //authenticated
 {
 outputPins(server, type, true);
 }
}
 
void defaultCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) //default web page loader
{
 outputPins(server, type, false);
}
 
void displayPins(WebServer &server, int pin, int type, String label, bool addControls) //print the pin status
{
 int val;
 if (invertOO){val = !digitalRead(pin); } else { val = digitalRead(pin);}
 server << label;
 if (addControls)
 {
 char pinName[4];
 server.printP(spacer);
 pinName[0] = 'd';
 itoa(pin, pinName + 1, 10);
 
 if (type == 0)
 {
 //normal relay
 server.radioButton(pinName, "1", "On", val);
 server << " ";
 server.radioButton(pinName, "0", "Off", !val);
 server << "</fieldset>";
 }
 else if (type == 1)
 {
 //latch relay
 server.radioButton(pinName, "1", "Switch", val);
 server << "</fieldset>";
 }
 
 }
 else
 {
 
 if (type == 0)
 {
 //normal relay
 if (invertOO){
 server << (!val ? "<font color='red'>OFF</font>" : "<font color='green'>ON</font>");
 }
 else
 {
 server << (val ? "<font color='red'>OFF</font>" : "<font color='green'>ON</font>");
 }
 }
 else if (type == 1)
 {
 //latch relay - recomended that you monitor the analog sensor here and use to print status
server << "<font color='red'>n/a</font>";
 //if (AnalogEnabled && Analog1 ) {server.printP(analog1ON);}
 }
 
}
 server << "<br/>";
}
 
void setup()
{
 Serial.begin(9600);
 // set pins 0-9 for digital input
 for (int i = 2; i <= MAXrelay; ++i)
 {
 pinMode(i, OUTPUT);
 }

//Initialize pins - this should be changed if other then UNO
 for (int i = 2; i <= MAXrelay; ++i)
 {
 if (invertOO){
 digitalWrite(i, !relayAtBoot);
 }
 else {
 digitalWrite(i, relayAtBoot);
 }
 
 }
 //start web
 Ethernet.begin(mac, ip);
 webserver.begin();
 webserver.setDefaultCommand(&defaultCmd);
 webserver.addCommand("webpower", &webpowerCmd);
 webserver.addCommand("settings", &settingsCmd);
 Serial.print("server at "); Serial.println(Ethernet.localIP()); //debug to serial if server is 0.0.0.0 web boot failed check sheld connections
 for (int i = 0; i < sizeof(relayPin); i++){
 relayPin[i] = EEPROM.read(relayPinAddressStart + i);
 }
 for (int i = 0; i < sizeof(relayType); i++){
 relayType[i] = EEPROM.read(relayTypeAddressStart + i);
 }
 if (HardwareControl) {
 digitalWrite(AnalogONpin, LOW);
 digitalWrite(AnalogOFFpin, LOW);
 }
 if (AnalogEnabled) {
 digitalWrite(Analog1Pin, INPUT);
 digitalWrite(Analog2Pin, INPUT);
 }
}
 
void loop()
{
 // process incoming connections one at a time forever
 webserver.processConnection();
 
//physical on/off control
 if (HardwareControl) {
 int aon = analogRead(AnalogONpin);
 int aoff = analogRead(AnalogOFFpin);
 if (aon > 1015){;
 //Turn On relays incrementally
 if (relayPin[aio-1] > 0 && relayPin[aio-1] <= 53){
 if (invertOO){ digitalWrite(relayPin[aio-1], LOW); } else { digitalWrite(relayPin[aio-1], HIGH); }
 delay(400); //cheap antibounce
 aif = aio; //keep them synched
 if (aio == sizeof(relayPin)){aio=1;} else { aio++;}
 }
 }
 if (aoff > 1015){;
 //if long delay press power down all relays
 if(previousMillis > 8) //3 second press of button (400 second delay below*8) bug here for over 8 relays
 {
 Serial.println("do");
 previousMillis = 0;
 for (int i = 0; i < sizeof(relayPin); i++){
 {
 if (invertOO){ digitalWrite(relayPin[aif-1], HIGH); } else { digitalWrite(relayPin[aif-1], LOW); }
 aif=1;aio=1; //reset hardware switching
 }
 }
 }
 else { previousMillis++;}
 //Turn Off relays incrementally
 if (relayPin[aif-1] > 0 && relayPin[aif-1] <= 53){
 if (invertOO){ digitalWrite(relayPin[aif-1], HIGH); } else { digitalWrite(relayPin[aif-1], LOW); }
 delay(400); //cheap antibounce
 aio= aif; //keep them synched
 if (aif == sizeof(relayPin)){aif=1;previousMillis = 0;} else { aif--;}
 }
 if(aif<1){aif=1;}
 }
 }
 
//analog reading
 if (AnalogEnabled) {
 int a1 = analogRead(Analog1Pin);
 int a2 = analogRead(Analog2Pin);
 //Serial.println(a1 + ":" + a2); //debug print for tuning the AnalogUpperValue settings
 if (a1 > Analog1UpperValue){;Analog1 = true;}else {Analog1 = false;}
 if (a2 > Analog2UpperValue){;Analog2 = true;}else {Analog2 = false;}
 }
}
//EOF
Comments (69) Trackbacks (2)
  1. Error: variable or field ‘displayPins’ declared void

    • Check that you copy and paste correctly.. also check your requirements.. it requires WebDuino.. I just cut and paste this into a new sketch and it verify and built with no issues.

      You will need the webduino libary in your arduino/library folder to compile;
      built in Arduino 1.0.5 and webduino 1.7
      https://github.com/sirleech/Webduino

  2. Hi thanks for the brilliant code I have being playing with it for the last few days, and I have a few queries. I have being unable to get passed the Authentication as it askes for the USER and Password, is there a user name somewhere I cannot find ??, I understand the password side ok, also is their a way of storing the relay state ( in EEPROM I suspect) in case of power off as they default to all OFF or all ON either which could be pain full depending on what it is controlling. I am using an UNO and it is limited on memory and will have some Leonardo’s arriving soon and I have a mega available to play with, I have some equipment in the attic which I have to reset every so often and its a pain to get to, I was hoping to deploy this system to do the job.
    Yours
    Shane O Brien
    From Ireland

    • I am glad that you can use the code! I didn’t code in EEPROM write for the state on power on and off but will look into that the next time I sit down and code on it a bit.
      Yes moving from the UNO platform will give more memory and allow more things, the UNO is rather tapped out right now I am fighting keeping the code running in the requirements of the UNO but might have to branch.

      As for the username and password its admin/admin by default.. you need to UUENCODE64 the clear text of ‘username:password’ (put your values in when you encode it) to change it in the value listed in the IDE. Hope that helps with that.

  3. I have tried to compile this using Arduino IDE v1.5.3 but get this error:
    Arduino: 1.5.3 (Windows XP), Board: “Arduino Uno”

    sketch_oct03a.ino: In function ‘void outputPins(WebServer&, WebServer::ConnectionType, bool)’:
    sketch_oct03a:153: error: call of overloaded ‘String(int&, int)’ is ambiguous
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:73: note: candidates are: String::String(double, int)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:72: note: String::String(float, int)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:71: note: String::String(long unsigned int, unsigned char)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:70: note: String::String(long int, unsigned char)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:69: note: String::String(unsigned int, unsigned char)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:68: note: String::String(int, unsigned char)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:67: note: String::String(unsigned char, unsigned char)
    sketch_oct03a:164: error: call of overloaded ‘String(int&, int)’ is ambiguous
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:73: note: candidates are: String::String(double, int)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:72: note: String::String(float, int)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:71: note: String::String(long unsigned int, unsigned char)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:70: note: String::String(long int, unsigned char)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:69: note: String::String(unsigned int, unsigned char)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:68: note: String::String(int, unsigned char)
    \\psf\Home\Documents\Arduino\hardware\arduino\avr\cores\arduino/WString.h:67: note: String::String(unsigned char, unsigned char)
    sketch_oct03a.ino: At global scope:
    sketch_oct03a:443: error: expected unqualified-id before ‘-‘ token

    This report would have more information with
    “Show verbose output during compilation”
    enabled in File > Preferences.

    Do you have any suggestions as to what the problem may be?
    Thanks

    • Please make sure that you copy the source raw and that there is nothing that you dont expect.. also make sure that you copy just the code and not any HTML that might have jumped in there.
      Additionally make sure that you have the includes and Arduino IDE working correctly and installed per public documentation. It appears if you have some issues with that. Can you compile other sketches successfully? The error’s tat you gave do not reflect my code directly the error line sketch_oct03a.ino: In function β€˜void outputPins(WebServer&, WebServer::ConnectionType, bool)’: suggests that you didnt follow the install of webduino correctly? I have only tested with the following.. and would recommend that you use the following revisions of code for 100% success. I will try using 1.5.3 as soon as I can to compile and build.. i know there is a lot of new hardware coming out that uses this.

      You will need the webduino library in your Arduino /library folder to compile;
      built in Arduino 1.0.5 and webduino 1.7

      https://github.com/sirleech/Webduino
      – See more at: http://kellykeeton.com/2013/08/06/webpower/#sthash.aiJ2ksDv.dpuf

    • I just tested compile of the code in
      Arduino 1.5.4 and webduino 1.7
      with success on compile

  4. I’m trying to do exactly the same thing for a project of mine and your code would be very helpfull, but i can see the link for it at this page!
    Please help!

  5. Awesome sketch !!! i really love it. that’s exactly what i was looking for. just a little bug on my side. when i set an entry as pulse relay, it’s always on… any idea how to set if off by default ?

    i love the interface !!! great job !!!

    • yes I haven’t thought of a good way to do this yet.. the idea is that you can use a analog sensor to detect a light (like a power LED) or a voltage to then display if the equipment is on or not.. the problem is even a pulse might not turn on gear.. or what if you accidentally press it a few times? I am personally switching high power equipment so I needed 100% trusty data.. and if I show a Pulse as “on or OFF” that is not true.. thinking about it now.. I might remove the ON/OFF from the pulse all together!

  6. Sorry, my two cents… the default relay status was on the code… really well build !!!

    any idea how to change the button. i just want the pulse option.

    regards,

    Franck

    • thanks glad you like it.. can you explain more – I think your idea is the same enhancement I just put on your last post. I will work on this as a feature enhancement ASAP (to remove the ON/OFF text in the case of PULSE relay action) so its just a “click”

  7. Source code link does not expand. No source code available.

  8. Thank You for this good sketch, I like it !

    Greetings from The Netherlands

  9. Hey Kelly,

    thank you so much for sharing your code. That’s exactly what I searched for. I built my relay box two years ago, but never had time to really use it. The last days, I continued and worked on the software.
    I had problems with arduino freezes when sending request too fast. As there was no webduino when I started, I had to do all the HTTP-stuff by my own and probably there is the bug… doesn’t matter.

    I found your project and really really like your mobile jquery-design. That’s why I dropped my own software and tried to adjust your code to my hardware. And I like your settings page. In my software, the description tags are hard coded.
    My hardware has 8 relays. The relays are not connected directly to the arduino, but are connected using a shift register to save pins. In addition, I have 8 buttons with 8 status LEDs to manually switch a relay on/off and show if a relay is switched on.

    As you explicitly requested feedback:
    ( I don’t know, if the following issues occur for you as well or are the fault of my adjustments) πŸ˜‰

    – I wondered, that the status page didn’t refresh automatically whereas the SwitchPower-Page correctly shows changes. Maybe because Post-Forms are not cached by the browser?
    In the meta-tags, the http-equiv=pragma is for proxy servers? Maybe, there a http-equiv=cache-control missing? I tried and it seemed to work, but couldn’t test that good because of other issues πŸ˜‰

    – the HTML-tags get a little bit mixed. The is always sent, but is missing on the status page. And there is a but no starting

    – the relayUse-Strings are not stored in EEPROM? I wondered a little, that I can set them via settings page, but they are not saved. I think, I will add it. Should be easy. Or is there a reason for this?

    – Do you have experience with tracing output via Serial.print during network processing? I’m facing hanging requests/responses from time to time. I suspect my Serial-outputs for tracing purposes. Maybe they are blocking when their buffer is full? I have to investigate on this today. It was too late yesterday night πŸ™‚
    Any other idea maybe?

    – how is your experience with stability over a longer time period? Is the arduino reliable?

    best regards from Heidelberg, Germany… olli

    • Hello olli, thanks for the comments.. I have looked into the change from pragma to http-equiv=cache-control and I also see better performance. I have updated this in the code branch. Thanks.
      I will continue testing with this new change and see how it works out!

      can you explain the HTML tags a little more. I think my website truncated the text you put in.. I can email you direct for a followup.

      I chose not to code up the relayUse string at this time.. from my storing a undefined string of text is a fair bit of code and I havent taken on the task yet of storing them on the EEPROM.. yes its obnoxious.. My cheater is that in the advanced variable section you will see the array with the relay names. if you hard code that array it will save it in the code… not perfect but since people need to compile the code to use it.. I went with that lazy code.

      the arduino is not a powerful unit for sure. ideally the raspberry PI units are better suited for this but I was cheap.. the biggest thing I find with the ethernet shield is that its connectors can be poor. if you monitor serial you should see your IP address print .. if you see the IP 0.0.0.0 likely a physical connection with the shield. (I solved this was I hard soldered the ethernet shield to the arduino)

      no its not crazy stable, but I have had my unit running for a month at a time with no issues.. normally I tinker with something – I would love to hear experiences with stability.

      that is great your modifying the code, As I havent had the need for more then 4 relays I havent taken the time to switch it over to using a bit-register but its nothing complicated with the foundation I have here I tried to make it with that in mind for users.

      • Hi Kelly,

        I played around with the refresh a little more and I found out, that it is jquery, that caches the status page. I added a data-cache=’never’ to the data-role=’page’ section.

        Sorry about the html-tags. Of course they are not displayed πŸ˜‰
        It was a end-p and a end-center. No big thing…

        I found my freezing bug. It was the known issue, that the SD module was active. I set pin4 to HIGH at the beginning and the freezes went away. I still get some freezes, but I’m still working on it. It seems, that they only occur, if my girl friend calls the web page from her android mobile. Using my desktop-firefox or my iphone, the freezes don’t seem to occur. Strange issue…

        Regarding relayUse: I removed the String-object-Array and replaced it by a char *-Array. That way I could reduce the object-overhead and it was easy to store the description texts to EEPROM.

        Could you send me an email for your mail address? Then I can send you my current code. It contains of course all the adjustments to my hardware, but you can copy the coding for EEPROM storage and whatever you like.
        I made some adjustments to the UI. I moved the refresh and the reset button to the title header. And I used plain old tables to better align all items. I’m not that used to stylesheets, that’s why I chose tables πŸ˜‰

        best regards, Olli

        • short update… I found my dumb freezing bug. It seemed, that I somehow removed the pinMode(4, OUTPUT) statement and that’s why my freezes came back πŸ˜‰

          • awesome.. I have been reviewing your code to inject the EEPROM use of the relay names into it.

          • Hi Kelly,

            nice to hear, that you review my code. Should be easy to understand and integrate, I hope. Otherwise feel free to ask.
            I had to add the “eyecatcher” at the beginning to detect, if the EEPROM contains plausible values or if I better reset the strings to default value. That might not be the best option, but it works so far πŸ˜‰

            The last days, I tried to integrate a protection to unintentionally switch off computers. I added an icmp ping and if I get a response, I won’t allow to switch the relais. But the include of the ping-lib cost so much memory, that I had issues to get it stable.

            best regards, olli

          • Hi Olli,

            I read all posts, and I like you ideas (use a shift register to save pins and switch a relay on/off manually and show if a relay is switched on), can you share you code?, or send me if a Kelly don’t want in your web, you ideas and you dedication are really fantastics!

            thank you so much,
            Antoni.

            Pd.
            Sorry for my english.

  10. Hello,
    from January 1, 2014 I turn on my arduino one and am connected with a browser
    I get the screen, but I make the log no longer displays the buttons.
    Activating a console dfebug in the browser I get a lot of errors of interpretation of the commands in the. Jquery.mobile css site.

    It happens only to me or to other people? I state that has always worked until December 31 ….

    Thanks for any suggestions in solving the problem.

    Greetings and Happy New Year

    • I am not sure what your experiencing.. there is no date relation to the year or time.. I am calling jquery library direct from the public resource. To use this code you do need access to the internet from the browser that you would be using the webpower code from. any errors would not be in my code that I am aware of at this time. I just logged into my personal home system and have no issues in any browser platform (IE/Chrome/FFox) – if you can trap a specific error I can try and assist.

  11. Where is the code for webpower 2.1 i cant find it.This page has the old Version 1.21

  12. Can you please point me to the link of the new updated Version 2.1.

  13. Thank you for your effort and contribution to us all … this is exacly what I need for my project. BIG THANKS!

  14. Maybe I’m an idiot and need really broken down instructions, but I cannot get the code to compile. I get a bunch of errors related to WebServer.h.
    I’ve copied only the code between and including the “/* WebPower 1.21” line to the “//EOF”. No html tags. Pasted that into notepad and saved as test_sketch.ino.
    In my libraries folder I created a folder named “Webduino” and put the files from the github website there. The files are keywords.txt, readme.md and WebServer.h. I did not download the example files.
    When I open the test_sketch.ino in the IDE (Arduino 1.0.1) and go to Sketch > Import Library, the Webduino name shows up in the list.
    I have compiled a different sketch using a different library (“Ethernet”) in the same directory without any problems.
    I guess I’m missing something basic but i can’t figure it out.
    Any help would be appreciated!

    • my directory structure is
      arduino-1.5.4\libraries\Webduino
      arduino-1.5.4\webpower3

      try loading a example file from webduino and test that its working correctly?

      • Thanks for the quick response. Example files had the same problem, but it turns out I right clicked the link for WebServer.h and saved that instead of the actual code it links to.
        I fixed that, so no WebServer.h errors now, instead there’s an error for the ” ” on line 133.

    • put the WebServer.h file from the Webduino folder in the webserver folder. I had to do that for some reason.

  15. I take it out and the code compiles just fine. No one has had this problem before?

  16. Hello, I tried to compile the code and got the following error:
    Expected constructor, destructor, or type conversion before ‘,’ token

    It points to line 131:
    P(spacer) = “”;

     

    Any idea why this is happening? I looked it up online and didn’t get sufficient answers.
    Thanks in advance,
    Dor

  17. Any help?Please! i’ve put in comment some HTML rows,but still got these errors
    sketch_may14a.ino:71:23: error: WebServer.h: No such file or directory
    sketch_may14a:78: error: variable or field ‘displayPins’ declared void
    sketch_may14a:78: error: ‘WebServer’ was not declared in this scope
    sketch_may14a:78: error: ‘server’ was not declared in this scope
    sketch_may14a:78: error: expected primary-expression before ‘int’
    sketch_may14a:78: error: expected primary-expression before ‘int’
    sketch_may14a:78: error: expected primary-expression before ‘label’
    sketch_may14a:78: error: expected primary-expression before ‘bool’
    sketch_may14a:90: error: ‘WebServer’ does not name a type
    sketch_may14a:141: error: variable or field ‘outputPins’ declared void
    sketch_may14a:141: error: ‘WebServer’ was not declared in this scope
    sketch_may14a:141: error: ‘server’ was not declared in this scope
    sketch_may14a:141: error: ‘WebServer’ has not been declared
    sketch_may14a:141: error: expected primary-expression before ‘bool’

  18. if i take out the html part,should i use it to build a kind of webpage ? or what sould i do? please e-mail me how do i have to make this sketch work. Kind regards

  19. line 153 above should be >=
    if (relayPin[i-1] >= 0 && relayPin[i-1] <= 53)

  20. PulseTime should be int ?

  21. Hi. Maybe a silly question (arduino and programming rookie!) but the start of the sketch references 3 addresses;

    “”
    “”
    “”

    If this arduino plus its controlling device are not ‘online’, what will happen? Or another angle, if these are needed files, can they be hosted locally offline on the arduino sd card perhaps?…

    Thanks very much sorting out my muddled understanding πŸ™‚

  22. ..this code uses too much RAM. After fiddling with it for a while, I got everything to work. The settings page is overkill ( I removed it and the eeprom feature, but will add eeprom back in my code, without a settings page) and the “Undefined” if statements for labels are over-kill. pinModes need to be corrected too.

    // Sets proper outputs based on MAXrelay
    for (int i = 9; i >= MAXrelay; i–) {
    pinMode(i, OUTPUT);
    }

    // Sets proper Initialize pins
    for (int i = 9; i >= MAXrelay; i–) {
    if (invertOO){
    digitalWrite(i, !relayAtBoot);
    }else{
    digitalWrite(i, relayAtBoot);
    }
    }

  23. Sorry,the error was from row 133:  
    I also made the sketch to work with 8 relays with no problems. If anyone else need it,e-mail me.
    Thanks again!

  24. This is exactly what I was looking for. Congratulations!
    I donΒ΄t understand fully the code since it is very high level for me.
    I just get only one compiling error:

    132: error: expected constructor, destructor, or type conversion before ‘;’ token

    this is in line with code  

    Any help?. Thanks in advance

  25. I donΒ΄t know why but in my question above has disappeared “& n b s p ;” following “this is the line code ….” Now I write it between ” ” and with a space between each character, but in the sketch it is written with no space in between and without ” “

  26. Hi Kelly love your sketch but im doing something wrong but not sure what i have loaded the libraries in from your link but cant get past this using 1.5.3 ide i upgraded to fix this please could you have a quick look and tell me what i have done

    Arduino: nightly (Windows 7), Board: “Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)”

    WEBRELAY_2.ino:73:23: fatal error: WebServer.h: No such file or directory
    compilation terminated.

    This report would have more information with
    “Show verbose output during compilation”
    enabled in File > Preferences.

    i have copied library over and even changed the name to webserver so have both libraries i cannot find what to do kindest regards Dean

  27. getting the same error on line 133(&nbsp), took it out of the code but now I dont get all the buttons

  28. Hi,

    this project sounds very nice. Is it possible to download the code?

    Thanks a lot.

  29. Could you maybe add the ability to add a delay to one of the pins?

    like this?

    https://www.youtube.com/watch?v=saKqxqGffz4

  30. Beautiful work, very well written. thank you


Leave a comment