Have a try with this one
SYSTEM_MODE(SEMI_AUTOMATIC)
SYSTEM_THREAD(ENABLED)
#include <math.h>
#include "PietteTech_DHT/PietteTech_DHT.h"
#include "MDNS/MDNS.h"
#include "WebServer/WebServer.h"
// system defines
#define DHTTYPE DHT11 // Sensor type DHT11/21/22/AM2301/AM2302
#define DHTPIN 11 // Analog pin A1 for communications
//#define DHT_SAMPLE_INTERVAL 30000 // Sample every 30 seconds
#define WEBDUINO_FAVICON_DATA ""
#define WEBDUINO_FAIL_MESSAGE ""
#define POST_NAME_LENGTH 32
#define POST_VALUE_LENGTH 32
MDNS mdns;
WebServer webserver("", 80);
// All pages
P(Page_start) = "<!DOCTYPE html><html><head><title>SharpNode</title><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><meta charset=\"UTF-8\">";
P(Page_css) = "<style type=\"text/css\">html,body{font-family:sans-serif;}fieldset{margin-left:auto;margin-right:auto;max-width:480px;border-radius:8px;}legend{font-weight:bold;color:#444;}input.cmn-toggle-yes-no+label{padding:2px;width:60px;height:30px;white-space:wrap;overflow:hidden;text-overflow:ellipsis;text-align:center;font-size:12px;text-transform:uppercase}input.cmn-toggle-yes-no+label:before,input.cmn-toggle-yes-no+label:after{display:block;position:absolute;top:0;left:0;bottom:0;right:0;color:#fff;font-family:Roboto Slab,serif;text-align:center;line-height:30px;}input.cmn-toggle-yes-no+label:before{color:#fff;background-color:#444;content:attr(data-name);-moz-border-radius:5px 5px 5px 5px;-webkit-border-radius:5px 5px 5px 5px; border-radius:5px 5px 5px 5px;-webkit-transition:-webkit-transform 0.5s;-moz-transition:-moz-transform 0.5s;-o-transition:-o-transform 0.5s;transition:transform 0.5s;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden;}input.cmn-toggle-yes-no+label:after{background-color:#00a65a;content:attr(data-name);-moz-border-radius:5px 5px 5px 5px;-webkit-border-radius:5px 5px 5px 5px;border-radius:5px 5px 5px 5px;-webkit-transition:-webkit-transform 0.5s;-moz-transition:-moz-transform 0.5s;-o-transition: -o-transform 0.5s; transition: transform 0.5s;-webkit-transform: rotateY(180deg);-moz-transform: rotateY(180deg);-ms-transform: rotateY(180deg); -o-transform: rotateY(180deg);transform: rotateY(180deg);-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden; -o-backface-visibility:hidden; backface-visibility: hidden;}input.cmn-toggle-yes-no:checked + label:before{ -webkit-transform: rotateY(180deg);-moz-transform: rotateY(180deg); -ms-transform: rotateY(180deg);-o-transform: rotateY(180deg); transform:rotateY(180deg);}input.cmn-toggle-yes-no:checked+label:after{-webkit-transform: rotateY(0);-moz-transform:rotateY(0);-ms-transform:rotateY(0);-o-transform:rotateY(0);transform:rotateY(0);}.cmn-toggle{position:absolute;margin-left:-9999px;visibility:hidden;}.cmn-toggle+label{display:block;position:relative;cursor:pointer;outline:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.switch{padding:4px 2px 0px 50px;float:right;}#status{text-align:center}#status.success{font-color:#00a65a;}.app-box {display: block;height:44px;width:230px;float:left;border:1px solid #ccc}.app-box-icon { display:block; margin:2px;float:left; height:40px; width:100px;font-size: 18px; text-align: center; line-height: 40px; background: rgba(0, 0, 0, 0.2);}.app-box-content{padding:2px;}.temphum { text-align:center;}@media screen and (max-width:480px) {.app-box{display:blck;width:100%;float:none}.switch{float:right;}}</style>";
P(Page_end) = "</body></html>";
// Form-specific
P(Form_css) = "<style type=\"text/css\">p{clear:both;width:100%;line-height:1.5em;}label{width:49%;text-align:right;display:inline-block;line-height:1.5em;float:left;margin-left:-1em;}select,input[type=\"text\"]{width:49%;text-align:left;float:right;}#c{text-align:left;float:left;margin-left:2em;}</style>";
P(Form_settings) = "<fieldset><legend>SharpNode Local</legend><div id=\"status\" class=\"success\">Want to control online? goto <b><a href=\"http://sharpnode.com/dashboard\">Dashboard</a></b></div><hr/><div class=\"app-box\"><span class=\"app-box-icon\">Switch-1</span><div class=\"app-box-content\"><div class=\"switch\"><input id=\"switch-one\" class=\"cmn-toggle cmn-toggle-yes-no\" type=\"checkbox\" onclick=\"bindSwiches('switch-one')\"><label for=\"switch-one\" data-name=\"Switch\"></label></div></div></div><div class=\"app-box\"><span class=\"app-box-icon\">Switch-2</span><div class=\"app-box-content\"><div class=\"switch\"><input id=\"switch-two\" class=\"cmn-toggle cmn-toggle-yes-no\" type=\"checkbox\" onclick=\"bindSwiches('switch-two')\"><label for=\"switch-two\" data-name=\"Switch\"></label></div></div></div><div class=\"app-box\"><span class=\"app-box-icon\">Switch-3</span><div class=\"app-box-content\"><div class=\"switch\"><input id=\"switch-three\" class=\"cmn-toggle cmn-toggle-yes-no\" type=\"checkbox\" onclick=\"bindSwiches('switch-three')\"><label for=\"switch-three\" data-name=\"Switch\"></label></div></div></div><div class=\"app-box\"><span class=\"app-box-icon\">Switch-4</span><div class=\"app-box-content\"><div class=\"switch\"><input id=\"switch-four\" class=\"cmn-toggle cmn-toggle-yes-no\" type=\"checkbox\" onclick=\"bindSwiches('switch-four')\"><label for=\"switch-four\" data-name=\"Switch\"></label></div></div></div><div class=\"app-box\"><span class=\"app-box-icon\">Switch-5</span><div class=\"app-box-content\"><div class=\"switch\"><input id=\"switch-five\" class=\"cmn-toggle cmn-toggle-yes-no\" type=\"checkbox\" onclick=\"bindSwiches('switch-five')\"><label for=\"switch-five\" data-name=\"Switch\"></label></div></div></div><div class=\"app-box\"><span class=\"app-box-icon\">Switch-6</span><div class=\"app-box-content\"><div class=\"switch\"><input id=\"switch-six\" class=\"cmn-toggle cmn-toggle-yes-no\" type=\"checkbox\" onclick=\"bindSwiches('switch-six')\"><label for=\"switch-six\" data-name=\"Switch\"></label></div></div></div><div style=\"clear:both\"></div><hr/><div class=\"temphum\"><b>Temp:</b> <span id=\"temp\"></span>°C <b>Humidity:</b><span id=\"humd\"></span>%<br/><input id=\"btn-refresh\" type=\"button\" value=\"Refresh\" onclick=\"window.location.reload();\"></div></fieldset>";
P(Form_javascript1) = "<script type=\"text/javascript\">";
P(Form_javascript2) = "function setCookie(e){var t=new Date;t.setTime(t.getTime()+31536e6);var s='expires='+t.toGMTString();document.cookie='status='+e+'; '+s}function getCookie(e){for(var t=e+'=',s=document.cookie.split(';'),c=0;c<s.length;c++){for(var i=s[c];' '==i.charAt(0);)i=i.substring(1);if(0==i.indexOf(t))return i.substring(t.length,i.length)}return''}function switchBack(){var e=getCookie('status');e.length>0&&(e=JSON.parse(e)),switches.forEach(function(t){document.getElementById(t).checked=e[t],console.log(t+':'+e[t])}),document.getElementById('temp').innerHTML=temp,document.getElementById('humd').innerHTML=humd}function bindSwiches(e){var t,s,c;if(c=e,console.log(c),1==document.getElementById(c).checked)switch(c){case switches[0]:t='a',s='1';break;case switches[1]:t='b',s='1';break;case switches[2]:t='c',s='1';break;case switches[3]:t='d',s='1';break;case switches[4]:t='e',s='1';break;case switches[5]:t='f',s='1'}else switch(c){case switches[0]:t='a',s='0';break;case switches[1]:t='b',s='0';break;case switches[2]:t='c',s='0';break;case switches[3]:t='d',s='0';break;case switches[4]:t='e',s='0';break;case switches[5]:t='f',s='0'}var i={};switches.forEach(function(e){1==document.getElementById(e).checked?i[e]=!0:i[e]=!1}),i=JSON.stringify(i),setCookie(i);var n='<form id=\"dynForm\" method=\"POST\"><input type=\"hidden\" name=\"'+t+'\" value=\"'+s+'\"></form>';document.body.innerHTML+=n,document.getElementById('dynForm').submit()}window.onload=function(e){switchBack()};var switches=['switch-one','switch-two','switch-three','switch-four','switch-five','switch-six'];";
P(Form_javascript3) = "</script></head><body>";
// Fail page
P(Fail_message) = "<p>Failed to send switch command</p>";
void web_fail(WebServer &server, WebServer::ConnectionType type, char *, bool);
void web_index(WebServer &server, WebServer::ConnectionType type, char *, bool);
// Temperature and Humidity (Assign appropriate function to set actual value)
int temp = 32;
int humd = 56;
// Lib instantiate
void dht_wrapper();
PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
void dht_wrapper() { DHT.isrCallback(); }
// name the pins
const int pinCount = 6;
const int ctrlPin[pinCount] = { A2, A3, A4, A5, A6, A7 };
const int statPin[pinCount] = { D2, D3, D4, D5, D6, D7 };
//status variables
//int s[pinCount] = { 0, 0, 0, 0, 0, 0 };
int status;
//PIR variables
const int inputPin = A0;
int motionCounter = 0;
bool available;
void setup()
{
WiFi.on();
WiFi.connect();
waitUntil(WiFi.ready);
bool mdns_success = mdns.setHostname("sharpnode");
if(mdns_success)
{
mdns.addService("tcp", "http", 80, "SharpNode Local");
mdns.begin();
}
webserver.setDefaultCommand(&web_index);
webserver.setFailureCommand(&web_fail);
webserver.addCommand("index.html", &web_index);
webserver.begin();
//Register our Particle function here
Particle.function("led", ledControl);
Particle.function("sharpnode", sharpnode);
// PArticle variables
Particle.variable("status", status);
for (int i=0; i < pinCount; i++)
{
pinMode(ctrlPin[i], OUTPUT);
pinMode(statPin[i], INPUT_PULLDOWN);
//digitalWrite(ctrlPin[i], EEPROM.read(pinCount-i-1)); // why does this have to be the other way round??
digitalWrite(ctrlPin[i], EEPROM.read(i));
}
pinMode(RX, OUTPUT);
digitalWrite(RX, EEPROM.read(6));
Particle.connect();
waitFor(Particle.connected, 30000); // wait up to 30sec for cloud
}
void loop()
{
static uint32_t msLastConnect;
static int prevPIR = LOW;
int currPIR = digitalRead(inputPin);
int web_len = 64;
char web_buff[web_len];
if (!Particle.connected() && millis() - msLastConnect > 60000) // only try connect once per minute
{
msLastConnect = millis();
Particle.connect();
}
mdns.processQueries();
webserver.processConnection(web_buff, &web_len);
if (currPIR != prevPIR) // only react on state change
{
prevPIR = currPIR;
if(currPIR)
{
motionCounter++; // increment motion counter
available = (motionCounter <= 2);
if(Particle.connected())
{
if (available)
{
Particle.publish("motion_nodetect","Motion not detected!"); //publish to conf_avail webhook
}
else
{
Particle.publish("motion_detect","Motion Detected!"); //publish to conf_inuse webhook
motionCounter = 2; // reset motion counter
}
delay(1000); // to ensure publish rate limit
}
}
}
}
//Sharpnode fn consists temp, humidity and IP
int sharpnode(String string){
// Check if we need to start the next sample
if (string == "start")
{
status = 0;
for(int i = 0; i < pinCount; i++)
{
//s[i] = 1+digitalRead(statPin[i]); // LOW = 1 (1+0) HIGH = 2 (1+1)
// why 1 & 2 instead of 0 & 1? %06d would also show leading zeroes
status += digitalRead(statPin[i]) * pow(10, i);
}
//status = (s6*100000)+(s5*10000)+(s4*1000)+(s3*100)+(s2*10)+(s1*1); //RMD tells relay1 status & LMD tells relay6 status
DHT.acquire();
uint32_t ms = millis();
while(DHT.acquiring() && millis() - ms < 100) Particle.process(); // has sample completed?
if (!DHT.acquiring())
{
char buf[128];
snprintf(buf, sizeof(buf), "{ \"status\":\"%06d\",\"temperature\":\"%.2f\",\"humidity\":\"%.2f\", \"ip\":\"%s\"}", status, DHT.getCelsius(), DHT.getHumidity(), WiFi.localIP().toString().c_str());
Particle.publish("sharpnode1", buf, PRIVATE);
return 1; // signal success
}
else
{
return 0; // signal fail
}
}
return -1; // signal wrong command
// always return useful information - makes debugging easier ;-)
}
// This function gets called whenever there is a matching API request
// the command string format is l<led number>,<state>
// for example: l1,HIGH or l1,LOW
// l2,HIGH or l2,LOW
int ledControl(String command)
{
int state = 0;
int pinNumber = (command.charAt(1) - '0') - 1;
//Sanity check to see if the pin numbers are within limits
if (pinNumber < 0 || pinNumber > 7) return -1;
// find out the state of the led
if(command.substring(3,7) == "HIGH") state = 1;
else if(command.substring(3,6) == "LOW") state = 0;
else return -1;
return eepromWrite(pinNumber,state);
}
int eepromWrite(int pinNumber,int state)
{
switch(pinNumber) //pinNumber will impact on pin
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
EEPROM.write(pinNumber,state);
//digitalWrite(ctrlPin[pinCount-pinNumber-1],state); // why wrong way round?
digitalWrite(ctrlPin[pinNumber],state);
break;
case 6:
EEPROM.write(6,state);
digitalWrite(RX,state); //for PIR ON/OFF
break;
//case 7:
// EEPROM.write(10,state);
// digitalWrite(pinNumber,state);
// break;
default:
return -1; // signal fail (wrong pinNumber)
}
return pinNumber; // signal success
}
// index.html
void web_index(WebServer &server, WebServer::ConnectionType type, char *, bool)
{
// variable type and size define
URLPARAM_RESULT rc;
char name[POST_NAME_LENGTH];
char value[POST_VALUE_LENGTH];
server.httpSuccess();
server.printP(Page_start);
server.printP(Page_css);
server.printP(Form_css);
server.printP(Form_javascript1);
server.printP("var temp=\""+String(temp)+"\";");
server.printP("var humd=\""+String(humd)+"\";");
server.printP(Form_javascript2);
server.printP(Form_javascript3);
server.printP(Form_settings);
server.printP(Page_end);
// read first parameter and thier value (Loop removed to work fast)
server.readPOSTparam(name, POST_NAME_LENGTH, value, POST_VALUE_LENGTH);
int pinNr = name[0] - 'a'; // take first character as index
eepromWrite(pinNr, atoi(value));
}
// Bad requests
void web_fail(WebServer &server, WebServer::ConnectionType type, char *, bool)
{
server.httpFail();
server.printP(Page_start);
server.printP(Fail_message);
server.printP(Page_end);
}
I’ve taken the liberty to flip the order in which the data is stored in EEPROM, since I don’t see much point in having the order inverted between pin numbers and byte position of the respective data.
I’m also not sure, why you’re using motionCounter = 2
and motionCouter <= 2
- the way I understood the code, there is not much difference to a mere boolean since I’d only ever expect to see 2 or 3 as the possible values for motionCounter
(apart from the two very first motion events) - there never is a reset to 0
and you only increment from 2
to 3
and the reset to 2
.