From 4d7f6ca875121517d009e9317ffd4edffcb47479 Mon Sep 17 00:00:00 2001 From: livello Date: Thu, 22 Mar 2018 20:42:21 +0300 Subject: [PATCH 1/7] refactoring. help cmd improved. Removed newline from freeMem periodical print. --- lighthub/inputs.cpp | 6 +- lighthub/item.cpp | 1468 ++++++++++++++++++++++--------------------- lighthub/main.cpp | 773 ++++++++++++----------- lighthub/main.h | 12 +- lighthub/owTerm.cpp | 251 ++++---- platformio.ini | 4 +- 6 files changed, 1271 insertions(+), 1243 deletions(-) diff --git a/lighthub/inputs.cpp b/lighthub/inputs.cpp index 075232d..a6f9420 100644 --- a/lighthub/inputs.cpp +++ b/lighthub/inputs.cpp @@ -23,7 +23,7 @@ e-mail anklimov@gmail.com #include "item.h" #include -extern PubSubClient client; +extern PubSubClient mqttClient; Input::Input(char * name) //Constructor { @@ -121,11 +121,11 @@ void Input::Changed (int val) if (val) { //send set command - if (!scmd) client.publish(emit->valuestring,"ON"); else if (strlen(scmd->valuestring)) client.publish(emit->valuestring,scmd->valuestring); + if (!scmd) mqttClient.publish(emit->valuestring,"ON"); else if (strlen(scmd->valuestring)) mqttClient.publish(emit->valuestring,scmd->valuestring); } else { //send reset command - if (!rcmd) client.publish(emit->valuestring,"OFF"); else if (strlen(rcmd->valuestring)) client.publish(emit->valuestring,rcmd->valuestring); + if (!rcmd) mqttClient.publish(emit->valuestring,"OFF"); else if (strlen(rcmd->valuestring)) mqttClient.publish(emit->valuestring,rcmd->valuestring); } } diff --git a/lighthub/item.cpp b/lighthub/item.cpp index 71cec63..5631a0e 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -22,9 +22,11 @@ e-mail anklimov@gmail.com #include "aJSON.h" #ifdef _dmxout + #include "dmx.h" #include "FastLED.h" -#endif + +#endif #include #include @@ -32,92 +34,95 @@ e-mail anklimov@gmail.com #define dimPar SERIAL_8E1 #define fmPar SERIAL_8N1 -short modbusBusy=0; -extern aJsonObject * modbusitem; +short modbusBusy = 0; +extern aJsonObject *modbusitem; int modbusSet(int addr, uint16_t _reg, int _mask, uint16_t value); -extern PubSubClient client; + +extern PubSubClient mqttClient; //extern const char* outprefix; -const char outprefix[] PROGMEM = "/myhome/s_out/"; +const char outprefix[] PROGMEM = "/myhome/s_out/"; -static unsigned long lastctrl = 0; -static aJsonObject * lastobj = NULL; +static unsigned long lastctrl = 0; +static aJsonObject *lastobj = NULL; -int txt2cmd (char * payload) -{ - int cmd=-1; - - // Check for command - if (strcmp(payload,"ON")==0) cmd=CMD_ON; - else if (strcmp(payload,"OFF")==0) cmd=CMD_OFF; - else if (strcmp(payload,"REST")==0) cmd=CMD_RESTORE; - else if (strcmp(payload,"TOGGLE")==0) cmd=CMD_TOGGLE; - else if (strcmp(payload,"HALT")==0) cmd=CMD_HALT; - else if (*payload=='-' || (*payload>='0' && *payload<='9')) cmd=0; - else if (*payload=='{') cmd=-2; - - return cmd; +int txt2cmd(char *payload) { + int cmd = -1; + + // Check for command + if (strcmp(payload, "ON") == 0) cmd = CMD_ON; + else if (strcmp(payload, "OFF") == 0) cmd = CMD_OFF; + else if (strcmp(payload, "REST") == 0) cmd = CMD_RESTORE; + else if (strcmp(payload, "TOGGLE") == 0) cmd = CMD_TOGGLE; + else if (strcmp(payload, "HALT") == 0) cmd = CMD_HALT; + else if (*payload == '-' || (*payload >= '0' && *payload <= '9')) cmd = 0; + else if (*payload == '{') cmd = -2; + + return cmd; } -const short defval[4] = {0,0,0,0}; //Type,Arg,Val,Cmd +const short defval[4] = {0, 0, 0, 0}; //Type,Arg,Val,Cmd -Item::Item(aJsonObject * obj)//Constructor -{ - itemArr= obj; - Parse(); -} - -void Item::Parse() +Item::Item(aJsonObject *obj)//Constructor { - if (isValid()) - { - // Todo - avoid static enlarge for every types - for (int i=aJson.getArraySize(itemArr);i<4;i++) aJson.addItemToArray(itemArr,aJson.createItem(int(defval[i]))); //Enlarge item to 4 elements. VAL=int if no other definition in conf - - - itemType = aJson.getArrayItem(itemArr,I_TYPE)->valueint; - itemArg = aJson.getArrayItem(itemArr,I_ARG); - itemVal = aJson.getArrayItem(itemArr,I_VAL); + itemArr = obj; + Parse(); +} + +void Item::Parse() { + if (isValid()) { + // Todo - avoid static enlarge for every types + for (int i = aJson.getArraySize(itemArr); i < 4; i++) + aJson.addItemToArray(itemArr, aJson.createItem( + int(defval[i]))); //Enlarge item to 4 elements. VAL=int if no other definition in conf + + + itemType = aJson.getArrayItem(itemArr, I_TYPE)->valueint; + itemArg = aJson.getArrayItem(itemArr, I_ARG); + itemVal = aJson.getArrayItem(itemArr, I_VAL); + - Serial.print(F(" Item:")); - Serial.print(itemArr->name);Serial.print(F(" T:")); - Serial.print(itemType);Serial.print(F(" ="));Serial.println(getArg()); - } + Serial.print(itemArr->name); + Serial.print(F(" T:")); + Serial.print(itemType); + Serial.print(F(" =")); + Serial.println(getArg()); + } } -Item::Item(char * name) //Constructor +Item::Item(char *name) //Constructor { - if (name) - itemArr= aJson.getObjectItem(items, name); - else itemArr=NULL; - -Parse(); + if (name) + itemArr = aJson.getObjectItem(items, name); + else itemArr = NULL; + + Parse(); } -uint8_t Item::getCmd() -{ - aJsonObject *t = aJson.getArrayItem(itemArr,I_CMD); - if (t) - return t->valueint; - else return -1; +uint8_t Item::getCmd() { + aJsonObject *t = aJson.getArrayItem(itemArr, I_CMD); + if (t) + return t->valueint; + else return -1; } -void Item::setCmd(uint8_t cmd) -{ - aJsonObject *t = aJson.getArrayItem(itemArr,I_CMD); - if (t) - t->valueint=cmd; +void Item::setCmd(uint8_t cmd) { + aJsonObject *t = aJson.getArrayItem(itemArr, I_CMD); + if (t) + t->valueint = cmd; } int Item::getArg(short n) //Return arg int or first array element if Arg is array -{ if (!itemArg) return -1; - if (itemArg->type==aJson_Int) return itemArg->valueint; - else if (itemArg->type==aJson_Array) return aJson.getArrayItem(itemArg,n)->valueint; - else return -2; +{ + if (!itemArg) return -1; + if (itemArg->type == aJson_Int) return itemArg->valueint; + else if (itemArg->type == aJson_Array) return aJson.getArrayItem(itemArg, n)->valueint; + else return -2; } + /* int Item::getVal(short n) //Return Val from Value array { if (!itemVal) return -1; @@ -132,16 +137,16 @@ int Item::getVal(short n) //Return Val from Value array */ long int Item::getVal() //Return Val if val is int or first elem of Value array -{ if (!itemVal) return -1; - if (itemVal->type==aJson_Int) return itemVal->valueint; - else if (itemVal->type==aJson_Array) - { - aJsonObject *t = aJson.getArrayItem(itemVal,0); - if (t) return t->valueint; - else return -3; - } - else return -2; +{ + if (!itemVal) return -1; + if (itemVal->type == aJson_Int) return itemVal->valueint; + else if (itemVal->type == aJson_Array) { + aJsonObject *t = aJson.getArrayItem(itemVal, 0); + if (t) return t->valueint; + else return -3; + } else return -2; } + /* void Item::setVal(short n, int par) // Only store if VAL is array defined in config to avoid waste of RAM { @@ -156,15 +161,16 @@ void Item::setVal(short n, int par) // Only store if VAL is array defined in c void Item::setVal(long int par) // Only store if VAL is int (autogenerated or config-defined) { - if (!itemVal || itemVal->type!=aJson_Int) return; - Serial.print(F(" Store "));Serial.print(F(" Val="));Serial.println(par); - itemVal->valueint=par; + if (!itemVal || itemVal->type != aJson_Int) return; + Serial.print(F(" Store ")); + Serial.print(F(" Val=")); + Serial.println(par); + itemVal->valueint = par; } -boolean Item::isValid () -{ - return (itemArr && (itemArr->type==aJson_Array)); +boolean Item::isValid() { + return (itemArr && (itemArr->type == aJson_Array)); } @@ -185,402 +191,401 @@ void analogWrite(int pin, int val) #endif -boolean Item::getEnableCMD(int delta) -{ - return ((millis()-lastctrl>(unsigned long) delta) );//|| (itemArr!=lastobj)); +boolean Item::getEnableCMD(int delta) { + return ((millis() - lastctrl > (unsigned long) delta));//|| (itemArr!=lastobj)); } -int Item::Ctrl(short cmd, short n, int * Par, boolean send) -{ +int Item::Ctrl(short cmd, short n, int *Par, boolean send) { - Serial.print(F("Cmd="));Serial.println(cmd); - //va_list vl; - - int _Par[3]={0,0,0}; - if (Par==NULL) Par=_Par; - - int iaddr=getArg(); - HSVstore st; - //Store Parameter(s) into json VAL + Serial.print(F("Cmd=")); + Serial.println(cmd); + //va_list vl; + + int _Par[3] = {0, 0, 0}; + if (Par == NULL) Par = _Par; + + int iaddr = getArg(); + HSVstore st; + //Store Parameter(s) into json VAL - switch (cmd) - { - int t; - case CMD_TOGGLE: - if (isActive()) cmd=CMD_OFF; else cmd=CMD_ON; - break; - - case CMD_RESTORE: - if (itemType!=CH_GROUP) //individual threating of channels. Ignore restore command for groups - switch (t=getCmd()) - { - case CMD_HALT: //previous command was HALT ? - Serial.print(F("Restored from:"));Serial.println(t); - cmd=CMD_ON; //turning on - break; - default: - return -3; - }//switch old cmd - } //switch cmd - - switch (cmd) - { - case 0: //no command - - setCmd(CMD_SET); - - switch (itemType) - { - - case CH_RGBW: //only if configured VAL array - if (!Par[1]) itemType=CH_WHITE; - case CH_GROUP: //Save for groups as well - case CH_RGB: - st.h=Par[0]; - st.s=Par[1]; - st.v=Par[2]; - setVal(st.aslong); - //SendCmd(0,3,Par); // Send back triplet ? - break; - - case CH_PWM: - case CH_VC: - case CH_DIMMER: - case CH_MODBUS: - SendCmd(0,1,Par); // Send back parameter for channel above this line - case CH_THERMO: - case CH_VCTEMP: - setVal(Par[0]); // Store value - - }//itemtype - - lastctrl=millis(); //last controlled object ond timestamp update - lastobj =itemArr; - - break; - - case CMD_ON: - if (getCmd()!=CMD_ON) - - { - short params=0; - //retrive stored values - st.aslong=getVal(); - if (st.aslong>0) //Stored smthng + switch (cmd) { + int t; + case CMD_TOGGLE: + if (isActive()) cmd = CMD_OFF; + else cmd = CMD_ON; + break; - switch (itemType) - { - //case CH_GROUP: - case CH_RGBW: - case CH_RGB: - Par[0]=st.h; - Par[1]=st.s; - Par[2]=st.v; - params=3; - SendCmd(0,params,Par); // Send restored triplet - break; - - - case CH_DIMMER: //Everywhere, in flat VAL - case CH_MODBUS: - case CH_VC: - case CH_VCTEMP: - case CH_PWM: - - Par[0]=st.aslong; - params=1; - SendCmd(0,params,Par); // Send restored parameter - break; - case CH_THERMO: - Par[0]=st.aslong; - params=0; - SendCmd(CMD_ON); // Just ON (switch) - break; - default: - SendCmd(cmd); // Just send ON - }//itemtype - else - {// Default settings - Serial.print(st.aslong); - Serial.println(F(": No stored values - default")); - - switch (itemType) - { + case CMD_RESTORE: + if (itemType != CH_GROUP) //individual threating of channels. Ignore restore command for groups + switch (t = getCmd()) { + case CMD_HALT: //previous command was HALT ? + Serial.print(F("Restored from:")); + Serial.println(t); + cmd = CMD_ON; //turning on + break; + default: + return -3; + }//switch old cmd + } //switch cmd + + switch (cmd) { + case 0: //no command + + setCmd(CMD_SET); + + switch (itemType) { + + case CH_RGBW: //only if configured VAL array + if (!Par[1]) itemType = CH_WHITE; + case CH_GROUP: //Save for groups as well + case CH_RGB: + st.h = Par[0]; + st.s = Par[1]; + st.v = Par[2]; + setVal(st.aslong); + //SendCmd(0,3,Par); // Send back triplet ? + break; + + case CH_PWM: + case CH_VC: + case CH_DIMMER: + case CH_MODBUS: + SendCmd(0, 1, Par); // Send back parameter for channel above this line + case CH_THERMO: + case CH_VCTEMP: + setVal(Par[0]); // Store value + + }//itemtype + + lastctrl = millis(); //last controlled object ond timestamp update + lastobj = itemArr; + + break; + + case CMD_ON: + if (getCmd() != CMD_ON) { + short params = 0; + //retrive stored values + st.aslong = getVal(); + if (st.aslong > 0) //Stored smthng + + switch (itemType) { + //case CH_GROUP: + case CH_RGBW: + case CH_RGB: + Par[0] = st.h; + Par[1] = st.s; + Par[2] = st.v; + params = 3; + SendCmd(0, params, Par); // Send restored triplet + break; + + + case CH_DIMMER: //Everywhere, in flat VAL + case CH_MODBUS: + case CH_VC: case CH_VCTEMP: - Par[0]=20; - break; - default: - Par[0]=100; - Par[1]=0; - Par[2]=100; - } - } - - - for (short i=0;i0) - { - Par[0]=0;Par[1]=0;Par[2]=0; - setCmd(cmd); - SendCmd(CMD_OFF); - Serial.println(F(" Halted")); - } - - - }//switch cmd + switch (itemType) { + case CH_VCTEMP: + Par[0] = 20; + break; + default: + Par[0] = 100; + Par[1] = 0; + Par[2] = 100; + } + } - - - switch (itemType) - { - - #ifdef _dmxout - case CH_DIMMER: //Dimmed light + for (short i = 0; i < params; i++) { + Serial.print(F("Restored: ")); + Serial.print(i); + Serial.print(F("=")); + Serial.println(Par[i]); + } - DmxWrite(iaddr, map(Par[0],0,100,0,255)); - - break; - - - case CH_RGBW: //Colour RGBW - { - int k; - DmxWrite(iaddr+3, k=map((100-Par[1])*Par[2],0,10000,0,255)); - Serial.print(F("W:"));Serial.println(k); - } - - - case CH_RGB: // RGB - - { - - CRGB rgb= CHSV(map(Par[0],0,365,0,255),map(Par[1],0,100,0,255),map(Par[2],0,100,0,255)); - - DmxWrite(iaddr, rgb.r); - DmxWrite(iaddr+1, rgb.g); - DmxWrite(iaddr+2, rgb.b); - - - break; } + setCmd(cmd); + } else { //Double ON - apply special preset - clean white full power + switch (itemType) { + case CH_RGBW: + Serial.println(F("Force White")); + itemType = CH_WHITE; + Par[1] = 0; //Zero saturation + Par[2] = 100; //Full power - - case CH_WHITE: - DmxWrite(iaddr, 0); - DmxWrite(iaddr+1, 0); - DmxWrite(iaddr+2, 0); - DmxWrite(iaddr+3, map(Par[2],0,100,0,255)); - break; - #endif + // Store + st.h = Par[0]; + st.s = Par[1]; + st.v = Par[2]; + setVal(st.aslong); - #ifdef _modbus - case CH_MODBUS: + //Send to OH + SendCmd(0, 3, Par); + break; + } //itemtype + } //else + + //Serial.print("Sa:");Serial.println(Par[1]); + if ((itemType == CH_RGBW) && (Par[1] == 0)) itemType = CH_WHITE; + + + break; //CMD_ON + + case CMD_OFF: + if (getCmd() != CMD_HALT) //if channels are halted - OFF to be ignored (restore issue) + { + Par[0] = 0; + Par[1] = 0; + Par[2] = 0; + setCmd(cmd); + SendCmd(cmd); + } + break; + + case CMD_HALT: + + if (isActive() > 0) { + Par[0] = 0; + Par[1] = 0; + Par[2] = 0; + setCmd(cmd); + SendCmd(CMD_OFF); + Serial.println(F(" Halted")); + } + + + }//switch cmd + + + + + switch (itemType) { + +#ifdef _dmxout + case CH_DIMMER: //Dimmed light + + DmxWrite(iaddr, map(Par[0], 0, 100, 0, 255)); + + break; + + + case CH_RGBW: //Colour RGBW { - - if ((itemArg->type == aJson_Array) && (aJson.getArraySize(itemArg)==3)) - { - int _addr= aJson.getArrayItem(itemArg,0)->valueint; - int _reg = aJson.getArrayItem(itemArg,1)->valueint; - int _mask= aJson.getArrayItem(itemArg,2)->valueint; - - modbusSet(_addr,_reg,_mask,map(Par[0],0,100,0,0x3f)); - } - break;} - #endif - + int k; + DmxWrite(iaddr + 3, k = map((100 - Par[1]) * Par[2], 0, 10000, 0, 255)); + Serial.print(F("W:")); + Serial.println(k); + } + + + case CH_RGB: // RGB + + { + + + CRGB rgb = CHSV(map(Par[0], 0, 365, 0, 255), map(Par[1], 0, 100, 0, 255), map(Par[2], 0, 100, 0, 255)); + + DmxWrite(iaddr, rgb.r); + DmxWrite(iaddr + 1, rgb.g); + DmxWrite(iaddr + 2, rgb.b); + + + break; + } + + + case CH_WHITE: + DmxWrite(iaddr, 0); + DmxWrite(iaddr + 1, 0); + DmxWrite(iaddr + 2, 0); + DmxWrite(iaddr + 3, map(Par[2], 0, 100, 0, 255)); + break; +#endif + +#ifdef _modbus + case CH_MODBUS: { + + if ((itemArg->type == aJson_Array) && (aJson.getArraySize(itemArg) == 3)) { + int _addr = aJson.getArrayItem(itemArg, 0)->valueint; + int _reg = aJson.getArrayItem(itemArg, 1)->valueint; + int _mask = aJson.getArrayItem(itemArg, 2)->valueint; + + modbusSet(_addr, _reg, _mask, map(Par[0], 0, 100, 0, 0x3f)); + } + break; + } +#endif + case CH_GROUP://Group { - //aJsonObject *groupArr= aJson.getArrayItem(itemArr, 1); - if (itemArg->type==aJson_Array) - { - aJsonObject *i =itemArg->child; - while (i) - { - Item it (i->valuestring); + //aJsonObject *groupArr= aJson.getArrayItem(itemArr, 1); + if (itemArg->type == aJson_Array) { + aJsonObject *i = itemArg->child; + while (i) { + Item it(i->valuestring); // it.copyPar(itemVal); - it.Ctrl(cmd,n,Par,send); //// was true - i=i->next; - } //while - } //if + it.Ctrl(cmd, n, Par, send); //// was true + i = i->next; + } //while + } //if } //case - break; - case CH_RELAY: - {int k; - pinMode(iaddr,OUTPUT); - digitalWrite(iaddr,k=((cmd==CMD_ON)?HIGH:LOW)); - Serial.print(F("Pin:"));Serial.print(iaddr);Serial.print(F("="));Serial.println(k); - break; - case CH_THERMO: - ///thermoSet(name,cmd,Par1); all cativities done - update temp & cmd - break; + break; + case CH_RELAY: { + int k; + pinMode(iaddr, OUTPUT); + digitalWrite(iaddr, k = ((cmd == CMD_ON) ? HIGH : LOW)); + Serial.print(F("Pin:")); + Serial.print(iaddr); + Serial.print(F("=")); + Serial.println(k); + break; + case CH_THERMO: + ///thermoSet(name,cmd,Par1); all cativities done - update temp & cmd + break; } - case CH_PWM: - {int k; - short inverse=0; - if (iaddr<0) {iaddr=-iaddr;inverse=1;} - pinMode(iaddr,OUTPUT); - //timer 0 for pin 13 and 4 - //timer 1 for pin 12 and 11 - //timer 2 for pin 10 and 9 - //timer 3 for pin 5 and 3 and 2 - //timer 4 for pin 8 and 7 and 6 - //prescaler = 1 ---> PWM frequency is 31000 Hz - //prescaler = 2 ---> PWM frequency is 4000 Hz - //prescaler = 3 ---> PWM frequency is 490 Hz (default value) - //prescaler = 4 ---> PWM frequency is 120 Hz - //prescaler = 5 ---> PWM frequency is 30 Hz - //prescaler = 6 ---> PWM frequency is <20 Hz - int tval = 7; // this is 111 in binary and is used as an eraser + case CH_PWM: { + int k; + short inverse = 0; + if (iaddr < 0) { + iaddr = -iaddr; + inverse = 1; + } + pinMode(iaddr, OUTPUT); + //timer 0 for pin 13 and 4 + //timer 1 for pin 12 and 11 + //timer 2 for pin 10 and 9 + //timer 3 for pin 5 and 3 and 2 + //timer 4 for pin 8 and 7 and 6 + //prescaler = 1 ---> PWM frequency is 31000 Hz + //prescaler = 2 ---> PWM frequency is 4000 Hz + //prescaler = 3 ---> PWM frequency is 490 Hz (default value) + //prescaler = 4 ---> PWM frequency is 120 Hz + //prescaler = 5 ---> PWM frequency is 30 Hz + //prescaler = 6 ---> PWM frequency is <20 Hz + int tval = 7; // this is 111 in binary and is used as an eraser #if defined(__AVR_ATmega2560__) - TCCR4B &= ~tval; // this operation (AND plus NOT), set the three bits in TCCR2B to 0 - TCCR3B &= ~tval; - tval=2; - TCCR4B|=tval; - TCCR3B|=tval; + TCCR4B &= ~tval; // this operation (AND plus NOT), set the three bits in TCCR2B to 0 + TCCR3B &= ~tval; + tval = 2; + TCCR4B |= tval; + TCCR3B |= tval; #endif - if (inverse) k=map(Par[0],100,0,0,255); - else k=map(Par[0],0,100,0,255); - analogWrite(iaddr,k); - Serial.print(F("Pin:"));Serial.print(iaddr);Serial.print(F("="));Serial.println(k); - break; + if (inverse) k = map(Par[0], 100, 0, 0, 255); + else k = map(Par[0], 0, 100, 0, 255); + analogWrite(iaddr, k); + Serial.print(F("Pin:")); + Serial.print(iaddr); + Serial.print(F("=")); + Serial.println(k); + break; } #ifdef _modbus case CH_VC: - - VacomSetFan(Par[0],cmd); - break; - - - case CH_VCTEMP: - { - Item it (itemArg->valuestring); - if (it.isValid() && it.itemType==CH_VC) - VacomSetHeat(it.getArg(),Par[0],cmd); - break; - } -#endif - - } // switch itemtype - // break; - - - - } -int Item::isActive() -{ - HSVstore st; - int val=0; + VacomSetFan(Par[0], cmd); + break; -if (!isValid()) return -1; + + case CH_VCTEMP: { + Item it(itemArg->valuestring); + if (it.isValid() && it.itemType == CH_VC) + VacomSetHeat(it.getArg(), Par[0], cmd); + break; + } +#endif + + } // switch itemtype + // break; + + + +} + +int Item::isActive() { + HSVstore st; + int val = 0; + + if (!isValid()) return -1; //Serial.print(itemArr->name); -int cmd=getCmd(); + int cmd = getCmd(); -if (itemType!=CH_GROUP) + if (itemType != CH_GROUP) // Simple check last command first -switch (cmd) -{ - case CMD_ON: - //Serial.println(" active"); - return 1; - case CMD_OFF: - case CMD_HALT: - case -1: ///// No last command - //Serial.println(" inactive"); - return 0; -} + switch (cmd) { + case CMD_ON: + //Serial.println(" active"); + return 1; + case CMD_OFF: + case CMD_HALT: + case -1: ///// No last command + //Serial.println(" inactive"); + return 0; + } // Last time was not a command but parameters set. Looking inside - st.aslong=getVal(); - -switch (itemType) -{ - case CH_GROUP: //make recursive calculation - is it some active in group - if (itemArg->type==aJson_Array) - { - Serial.println(F("Grp check: ")); - aJsonObject *i =itemArg->child; - while (i) - { - Item it (i->valuestring); - - if (it.isValid() && it.isActive()) {Serial.println(F("Active")); return 1;} - i=i->next; - } //while - return 0; - } //if - break; - - - case CH_RGBW: - case CH_RGB: + st.aslong = getVal(); - - val=st.v; //Light volume - break; - - case CH_DIMMER: //Everywhere, in flat VAL - case CH_MODBUS: - case CH_THERMO: - case CH_VC: - case CH_VCTEMP: - val=st.aslong; -} //switch -Serial.print(F(":="));Serial.println(val); - if (val) return 1; else return 0; + switch (itemType) { + case CH_GROUP: //make recursive calculation - is it some active in group + if (itemArg->type == aJson_Array) { + Serial.println(F("Grp check: ")); + aJsonObject *i = itemArg->child; + while (i) { + Item it(i->valuestring); + + if (it.isValid() && it.isActive()) { + Serial.println(F("Active")); + return 1; + } + i = i->next; + } //while + return 0; + } //if + break; + + + case CH_RGBW: + case CH_RGB: + + + val = st.v; //Light volume + break; + + case CH_DIMMER: //Everywhere, in flat VAL + case CH_MODBUS: + case CH_THERMO: + case CH_VC: + case CH_VCTEMP: + val = st.aslong; + } //switch + Serial.print(F(":=")); + Serial.println(val); + if (val) return 1; else return 0; } - + /* short thermoSet(char * name, short cmd, short t) @@ -648,316 +653,329 @@ POOL 2101x10 */ -void mb_fail(short addr, short op, int val, int cmd) -{ - Serial.println(F("Modbus op failed")); - +void mb_fail(short addr, short op, int val, int cmd) { + Serial.println(F("Modbus op failed")); + } extern ModbusMaster node; -int Item::VacomSetFan (int8_t val, int8_t cmd) -{ - int addr=getArg(); - Serial.print(F("VC#"));Serial.print(addr);Serial.print(F("="));Serial.println(val); +int Item::VacomSetFan(int8_t val, int8_t cmd) { + int addr = getArg(); + Serial.print(F("VC#")); + Serial.print(addr); + Serial.print(F("=")); + Serial.println(val); - if (modbusBusy) {mb_fail(1,addr,val,cmd);return -1;} - modbusBusy=1; - - uint8_t j, result; - uint16_t data[1]; + if (modbusBusy) { + mb_fail(1, addr, val, cmd); + return -1; + } + modbusBusy = 1; -modbusSerial.begin(9600,fmPar); -node.begin(addr,modbusSerial); + uint8_t j, result; + uint16_t data[1]; - if (val) { - node.writeSingleRegister(2001-1,4+1);//delay(500); - //node.writeSingleRegister(2001-1,1); - } - else node.writeSingleRegister(2001-1,0); - delay (50); - node.writeSingleRegister(2003-1,val*100); + modbusSerial.begin(9600, fmPar); + node.begin(addr, modbusSerial); + + if (val) { + node.writeSingleRegister(2001 - 1, 4 + 1);//delay(500); + //node.writeSingleRegister(2001-1,1); + } else node.writeSingleRegister(2001 - 1, 0); + delay(50); + node.writeSingleRegister(2003 - 1, val * 100); + + modbusBusy = 0; - modbusBusy=0; - } -#define a 0.1842 +#define a 0.1842 #define b -36.68 -int Item::VacomSetHeat(int addr,int8_t val, int8_t cmd) - { - - Serial.print(F("VC_heat#"));Serial.print(addr);Serial.print(F("="));Serial.print(val);Serial.print(F(" cmd="));Serial.println(cmd); - if (modbusBusy) {mb_fail(2,addr,val,cmd);return -1;} - modbusBusy=1; +int Item::VacomSetHeat(int addr, int8_t val, int8_t cmd) { -modbusSerial.begin(9600,fmPar); -node.begin(addr,modbusSerial); - - uint16_t regval; - - switch (cmd) - { - case CMD_OFF: - case CMD_HALT: - regval=0; - break; - - default: - regval=round(((float)val-b)*10/a); - } - - Serial.println(regval); - node.writeSingleRegister(2004-1,regval); - modbusBusy=0; - } - - -int Item::SendCmd(short cmd,short n, int * Par) - { - -/// ToDo: relative patches, configuration - - char addrstr[32]; - //char addrbuf[17]; - char valstr[16]=""; - - strcpy_P (addrstr,outprefix); - strncat (addrstr,itemArr->name,sizeof(addrstr)); //// - - - switch (cmd) - { - case CMD_ON: - strcpy(valstr,"ON"); - break; - case CMD_OFF: - case CMD_HALT: - strcpy(valstr,"OFF"); - break; - // TODO send Par - case 0: - case CMD_SET: - if (Par) - for (short i=0;i"));Serial.println(valstr); - client.publish(addrstr, valstr); - return 0; - } - - - - - - int modbusSet(int addr, uint16_t _reg, int _mask, uint16_t value) - { - - if (modbusBusy) {mb_fail(3,addr,value,0);return -1;}; - modbusBusy=1; - -modbusSerial.begin(9600,dimPar); -node.begin(addr,modbusSerial); - - -if (_mask) - {value <<= 8; value |= (0xff);} - else {value &= 0xff; value |= (0xff00);} - - Serial.print(addr);Serial.print(F("=>"));Serial.print(_reg,HEX);Serial.print(F(":"));Serial.println(value,HEX); - - node.writeSingleRegister(_reg,value); - modbusBusy=0; - } - - - -int Item::checkFM() - { - if (modbusBusy) return -1; - modbusBusy=1; - - uint8_t j, result; - int16_t data; - - - aJsonObject *out =aJson.createObject(); - char * outch; - char addrstr[32]; - - strcpy_P (addrstr,outprefix); - strncat(addrstr,itemArr->name,sizeof(addrstr)-1); - strncat(addrstr,"_stat",sizeof(addrstr)-1); - - // aJson.addStringToObject(out,"type", "rect"); - - -modbusSerial.begin(9600,fmPar); -node.begin(getArg(),modbusSerial); - - - result = node.readHoldingRegisters(2101-1, 10); - - // do something with data if read is successful - if (result == node.ku8MBSuccess) - { Serial.print(F(" FM Val :")); - for (j = 0; j < 10; j++) - { - data = node.getResponseBuffer(j); - Serial.print(data,HEX);Serial.print(F("-")); - + Serial.print(F("VC_heat#")); + Serial.print(addr); + Serial.print(F("=")); + Serial.print(val); + Serial.print(F(" cmd=")); + Serial.println(cmd); + if (modbusBusy) { + mb_fail(2, addr, val, cmd); + return -1; } - - // aJson.addNumberToObject(out,"gsw", (int) node.getResponseBuffer(1)); - aJson.addNumberToObject(out,"V", (int) node.getResponseBuffer(2)/100.); - // aJson.addNumberToObject(out,"f", (int) node.getResponseBuffer(3)/100.); - aJson.addNumberToObject(out,"RPM", (int) node.getResponseBuffer(4)); - aJson.addNumberToObject(out,"I", (int) node.getResponseBuffer(5)/100.); - aJson.addNumberToObject(out,"M", (int) node.getResponseBuffer(6)/10.); - // aJson.addNumberToObject(out,"P", (int) node.getResponseBuffer(7)/10.); - // aJson.addNumberToObject(out,"U", (int) node.getResponseBuffer(8)/10.); - // aJson.addNumberToObject(out,"Ui", (int) node.getResponseBuffer(9)); - aJson.addNumberToObject(out,"sw", (int) node.getResponseBuffer(0)); + modbusBusy = 1; - Serial.println(); - } else {Serial.print(F("Modbus pooling error=")); Serial.println(result,HEX); } + modbusSerial.begin(9600, fmPar); + node.begin(addr, modbusSerial); -if (node.getResponseBuffer(0) & 8) //Active fault - { - result = node.readHoldingRegisters(2111-1, 1); - if (result == node.ku8MBSuccess) aJson.addNumberToObject(out,"flt", (int) node.getResponseBuffer(0)); - } else aJson.addNumberToObject(out,"flt", 0); + uint16_t regval; -delay(50); -result = node.readHoldingRegisters(20-1, 4); - - // do something with data if read is successful - if (result == node.ku8MBSuccess) - { Serial.print(F(" PI Val :")); - for (j = 0; j < 4; j++) - { - data = node.getResponseBuffer(j); - Serial.print(data);Serial.print(F("-")); - + switch (cmd) { + case CMD_OFF: + case CMD_HALT: + regval = 0; + break; + + default: + regval = round(((float) val - b) * 10 / a); } - - int set = node.getResponseBuffer(0); - if (set) aJson.addNumberToObject(out,"set", set*a+b); - aJson.addNumberToObject(out,"t", (int) node.getResponseBuffer(1)*a+b); - // aJson.addNumberToObject(out,"d", (int) node.getResponseBuffer(2)*a+b); - int pwr= node.getResponseBuffer(3); - if (pwr>0) aJson.addNumberToObject(out,"pwr", pwr/10.); else aJson.addNumberToObject(out,"pwr",0); - - - Serial.println(); - } else {Serial.print(F("Modbus pooling error=")); Serial.println(result,HEX); } - - outch=aJson.print(out); - client.publish(addrstr, outch); - free (outch); - aJson.deleteItem(out); - - modbusBusy=0; - } - - - int Item::checkModbus() - { - if (modbusBusy) return -1; - modbusBusy=1; - - uint8_t result; - - uint16_t addr = getArg(0); - uint16_t reg = getArg(1); - short mask = getArg(2); - - int data; - - //node.setSlave(addr); - - modbusSerial.begin(9600,dimPar); - node.begin(addr,modbusSerial); - - - result = node.readHoldingRegisters(reg, 1); - - if (result == node.ku8MBSuccess) - { - data=node.getResponseBuffer(0); - Serial.print(F("Modbus Val: ")); Serial.println(data,HEX); - checkModbus(data); - } - else {Serial.print(F("Modbus pooling error=")); Serial.println(result,HEX); } - - modbusBusy=0; - -// Looking 1 step ahead for modbus item, which uses same register - Item nextItem(modbusitem->next); - if (modbusitem && nextItem.isValid() && nextItem.itemType==CH_MODBUS && nextItem.getArg(0)==addr && nextItem.getArg(1)==reg) - { - nextItem.checkModbus(data); - modbusitem=modbusitem->next; - if (!modbusitem) modbusitem=items->child; - } - + Serial.println(regval); + node.writeSingleRegister(2004 - 1, regval); + modbusBusy = 0; } -int Item::checkModbus(int data) - { - short mask = getArg(2); - int d=data; - if (mask) d>>=8; d&=0xff; - d=map(d,0,0x3f,0,100); - int cmd=getCmd(); - //Serial.println(d); - if (getVal()!=d || d && cmd==CMD_OFF || d && cmd==CMD_HALT) //volume changed or turned on manualy - { - if (d) - - { // Actually turned on - if (cmd==CMD_OFF || cmd==CMD_HALT) SendCmd(CMD_ON); //update OH with ON if it was turned off before - SendCmd(0,1,&d); //update OH with value - setCmd(CMD_ON); //store command - setVal(d); //store value - } - else { - if (cmd!=CMD_HALT && cmd!=CMD_OFF) - { - setCmd(CMD_OFF); // store command (not value) - SendCmd(CMD_OFF);// update OH - } - } - } //if data changed - } - -int Item::Pool() -{ - switch (itemType) - { - case CH_MODBUS: - checkModbus(); - break; - case CH_VC: - checkFM(); - } - } +int Item::SendCmd(short cmd, short n, int *Par) { + +/// ToDo: relative patches, configuration + + char addrstr[32]; + //char addrbuf[17]; + char valstr[16] = ""; + + strcpy_P(addrstr, outprefix); + strncat(addrstr, itemArr->name, sizeof(addrstr)); //// + + + switch (cmd) { + case CMD_ON: + strcpy(valstr, "ON"); + break; + case CMD_OFF: + case CMD_HALT: + strcpy(valstr, "OFF"); + break; + // TODO send Par + case 0: + case CMD_SET: + if (Par) + for (short i = 0; i < n; i++) { + char num[4]; + snprintf(num, sizeof(num), "%d", Par[i]); + strncat(valstr, num, sizeof(valstr)); + if (i != n - 1) { + strcpy(num, ","); + strncat(valstr, num, sizeof(valstr)); + } + } + break; + default: + return -1; + } + + Serial.print(addrstr); + Serial.print(F("->")); + Serial.println(valstr); + mqttClient.publish(addrstr, valstr); + return 0; +} + + +int modbusSet(int addr, uint16_t _reg, int _mask, uint16_t value) { + + if (modbusBusy) { + mb_fail(3, addr, value, 0); + return -1; + }; + modbusBusy = 1; + + modbusSerial.begin(9600, dimPar); + node.begin(addr, modbusSerial); + + + if (_mask) { + value <<= 8; + value |= (0xff); + } else { + value &= 0xff; + value |= (0xff00); + } + + Serial.print(addr); + Serial.print(F("=>")); + Serial.print(_reg, HEX); + Serial.print(F(":")); + Serial.println(value, HEX); + + node.writeSingleRegister(_reg, value); + modbusBusy = 0; +} + + +int Item::checkFM() { + if (modbusBusy) return -1; + modbusBusy = 1; + + uint8_t j, result; + int16_t data; + + + aJsonObject *out = aJson.createObject(); + char *outch; + char addrstr[32]; + + strcpy_P(addrstr, outprefix); + strncat(addrstr, itemArr->name, sizeof(addrstr) - 1); + strncat(addrstr, "_stat", sizeof(addrstr) - 1); + + // aJson.addStringToObject(out,"type", "rect"); + + + modbusSerial.begin(9600, fmPar); + node.begin(getArg(), modbusSerial); + + + result = node.readHoldingRegisters(2101 - 1, 10); + + // do something with data if read is successful + if (result == node.ku8MBSuccess) { + Serial.print(F(" FM Val :")); + for (j = 0; j < 10; j++) { + data = node.getResponseBuffer(j); + Serial.print(data, HEX); + Serial.print(F("-")); + + } + + // aJson.addNumberToObject(out,"gsw", (int) node.getResponseBuffer(1)); + aJson.addNumberToObject(out, "V", (int) node.getResponseBuffer(2) / 100.); + // aJson.addNumberToObject(out,"f", (int) node.getResponseBuffer(3)/100.); + aJson.addNumberToObject(out, "RPM", (int) node.getResponseBuffer(4)); + aJson.addNumberToObject(out, "I", (int) node.getResponseBuffer(5) / 100.); + aJson.addNumberToObject(out, "M", (int) node.getResponseBuffer(6) / 10.); + // aJson.addNumberToObject(out,"P", (int) node.getResponseBuffer(7)/10.); + // aJson.addNumberToObject(out,"U", (int) node.getResponseBuffer(8)/10.); + // aJson.addNumberToObject(out,"Ui", (int) node.getResponseBuffer(9)); + aJson.addNumberToObject(out, "sw", (int) node.getResponseBuffer(0)); + + Serial.println(); + } else { + Serial.print(F("Modbus pooling error=")); + Serial.println(result, HEX); + } + + if (node.getResponseBuffer(0) & 8) //Active fault + { + result = node.readHoldingRegisters(2111 - 1, 1); + if (result == node.ku8MBSuccess) aJson.addNumberToObject(out, "flt", (int) node.getResponseBuffer(0)); + } else aJson.addNumberToObject(out, "flt", 0); + + delay(50); + result = node.readHoldingRegisters(20 - 1, 4); + + // do something with data if read is successful + if (result == node.ku8MBSuccess) { + Serial.print(F(" PI Val :")); + for (j = 0; j < 4; j++) { + data = node.getResponseBuffer(j); + Serial.print(data); + Serial.print(F("-")); + + } + + int set = node.getResponseBuffer(0); + if (set) aJson.addNumberToObject(out, "set", set * a + b); + aJson.addNumberToObject(out, "t", (int) node.getResponseBuffer(1) * a + b); + // aJson.addNumberToObject(out,"d", (int) node.getResponseBuffer(2)*a+b); + int pwr = node.getResponseBuffer(3); + if (pwr > 0) aJson.addNumberToObject(out, "pwr", pwr / 10.); else aJson.addNumberToObject(out, "pwr", 0); + + + Serial.println(); + } else { + Serial.print(F("Modbus pooling error=")); + Serial.println(result, HEX); + } + + + outch = aJson.print(out); + mqttClient.publish(addrstr, outch); + free(outch); + aJson.deleteItem(out); + + modbusBusy = 0; +} + + +int Item::checkModbus() { + if (modbusBusy) return -1; + modbusBusy = 1; + + uint8_t result; + + uint16_t addr = getArg(0); + uint16_t reg = getArg(1); + short mask = getArg(2); + + int data; + + //node.setSlave(addr); + + modbusSerial.begin(9600, dimPar); + node.begin(addr, modbusSerial); + + + result = node.readHoldingRegisters(reg, 1); + + if (result == node.ku8MBSuccess) { + data = node.getResponseBuffer(0); + Serial.print(F("Modbus Val: ")); + Serial.println(data, HEX); + checkModbus(data); + } else { + Serial.print(F("Modbus pooling error=")); + Serial.println(result, HEX); + } + + modbusBusy = 0; + +// Looking 1 step ahead for modbus item, which uses same register + Item nextItem(modbusitem->next); + if (modbusitem && nextItem.isValid() && nextItem.itemType == CH_MODBUS && nextItem.getArg(0) == addr && + nextItem.getArg(1) == reg) { + nextItem.checkModbus(data); + modbusitem = modbusitem->next; + if (!modbusitem) modbusitem = items->child; + } + +} + + +int Item::checkModbus(int data) { + short mask = getArg(2); + int d = data; + if (mask) d >>= 8; + d &= 0xff; + d = map(d, 0, 0x3f, 0, 100); + int cmd = getCmd(); + //Serial.println(d); + if (getVal() != d || d && cmd == CMD_OFF || d && cmd == CMD_HALT) //volume changed or turned on manualy + { + if (d) { // Actually turned on + if (cmd == CMD_OFF || cmd == CMD_HALT) SendCmd(CMD_ON); //update OH with ON if it was turned off before + SendCmd(0, 1, &d); //update OH with value + setCmd(CMD_ON); //store command + setVal(d); //store value + } else { + if (cmd != CMD_HALT && cmd != CMD_OFF) { + setCmd(CMD_OFF); // store command (not value) + SendCmd(CMD_OFF);// update OH + } + } + } //if data changed +} + +int Item::Pool() { + switch (itemType) { + case CH_MODBUS: + checkModbus(); + break; + case CH_VC: + checkFM(); + } +} diff --git a/lighthub/main.cpp b/lighthub/main.cpp index a51cad4..7804433 100644 --- a/lighthub/main.cpp +++ b/lighthub/main.cpp @@ -78,14 +78,18 @@ Config webserver #include "stdarg.h" #if defined(__AVR__) + #include "HTTPClient.h" #include #include + #define wdt_en() wdt_enable(WDTO_8S) #define wdt_dis() wdt_disable() #define wdt_res() wdt_reset() #else + #include + #endif #if defined(WATCH_DOG_TICKER_DISABLE) @@ -95,15 +99,21 @@ Config webserver #endif #if defined(__SAM3X8E__) + #include - DueFlashStorage EEPROM; + +DueFlashStorage EEPROM; + #include + #define wdt_res() watchdogReset() #define wdt_en() #define wdt_dis() #else + #include + #endif #if defined(__ESP__) @@ -118,18 +128,24 @@ Config webserver #ifdef Wiz5500 #include #else + #include + #endif EthernetClient ethClient; #endif #ifdef _owire + #include "owTerm.h" + #endif #if defined(_dmxin) || defined(_dmxout) || defined (_artnet) + #include "dmx.h" + #endif #ifndef PIO_SRC_REV @@ -141,7 +157,9 @@ EthernetClient ethClient; #include "inputs.h" #ifdef _artnet + #include + extern Artnet *artnet; #endif @@ -159,27 +177,27 @@ extern Artnet *artnet; //char* subprefix=("/myhome/in/#"); #define inprefix "/myhome/in/" -const char outprefix[] PROGMEM = "/myhome/s_out/"; +const char outprefix[] PROGMEM = "/myhome/s_out/"; #define subprefix "/myhome/in/#" -aJsonObject *root = NULL; -aJsonObject *items = NULL; -aJsonObject *inputs = NULL; +aJsonObject *aJsonObjectRoot = NULL; +aJsonObject *items = NULL; +aJsonObject *inputs = NULL; -aJsonObject *mqttArr = NULL; +aJsonObject *mqttArr = NULL; aJsonObject *modbusArr = NULL; -aJsonObject *owArr = NULL; +aJsonObject *owArr = NULL; aJsonObject *dmxArr = NULL; -unsigned long modbuscheck=0; -unsigned long incheck =0; -unsigned long lanCheck =0; -unsigned long thermocheck=0; +unsigned long modbuscheck = 0; +unsigned long incheck = 0; +unsigned long lanCheck = 0; +unsigned long thermocheck = 0; -aJsonObject * modbusitem= NULL; +aJsonObject *modbusitem = NULL; bool owReady = false; -int lanStatus = 0; +int lanStatus = 0; #ifdef _modbus ModbusMaster node; @@ -188,36 +206,39 @@ ModbusMaster node; byte mac[6]; -PubSubClient client(ethClient); +PubSubClient mqttClient(ethClient); -void watchdogSetup(void){} //Do not remove - strong re-definition WDT Init for DUE +void watchdogSetup(void) {} //Do not remove - strong re-definition WDT Init for DUE // MQTT Callback routine -void callback(char* topic, byte* payload, unsigned int length) { - payload[length]=0; - Serial.print(F("[")); +void callback(char *topic, byte *payload, unsigned int length) { + payload[length] = 0; + Serial.print(F("\n[")); Serial.print(topic); Serial.print("] "); int fr = freeRam(); - if (fr<250) {Serial.println(F("OOM!"));return;} + if (fr < 250) { + Serial.println(F("OOM!")); + return; + } #define sublen 20 - char subtopic[sublen]=""; + char subtopic[sublen] = ""; int cmd = 0; - for (int i=0;ibegin(); #endif @@ -352,21 +367,21 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1; case 2: // IP Ready, config loaded, Connecting broker & subscribeArming Watchdog wdt_res(); { - short n=0; - int port=1883; - char empty=0; - char * user = ∅ - char * pass = ∅ + short n = 0; + int port = 1883; + char empty = 0; + char *user = ∅ + char *password = ∅ - if (!client.connected() && mqttArr && ((n=aJson.getArraySize(mqttArr))>1)) { - char *c=aJson.getArrayItem(mqttArr,0)->valuestring; - char *servername=aJson.getArrayItem(mqttArr,1)->valuestring; - if (n>=3) port=aJson.getArrayItem(mqttArr,2)->valueint; + if (!mqttClient.connected() && mqttArr && ((n = aJson.getArraySize(mqttArr)) > 1)) { + char *client_id = aJson.getArrayItem(mqttArr, 0)->valuestring; + char *servername = aJson.getArrayItem(mqttArr, 1)->valuestring; + if (n >= 3) port = aJson.getArrayItem(mqttArr, 2)->valueint; - if (n>=4) user=aJson.getArrayItem(mqttArr,3)->valuestring; - if (n>=5) pass=aJson.getArrayItem(mqttArr,4)->valuestring; + if (n >= 4) user = aJson.getArrayItem(mqttArr, 3)->valuestring; + if (n >= 5) password = aJson.getArrayItem(mqttArr, 4)->valuestring; - client.setServer(servername,port); + mqttClient.setServer(servername, port); Serial.print(F("Attempting MQTT connection to ")); Serial.print(servername); @@ -376,47 +391,53 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1; Serial.print(user); Serial.print(F(" ...")); - if (client.connect(c,user,pass)) { - Serial.print(F("connected as "));Serial.println(c); + if (mqttClient.connect(client_id, user, password)) { + Serial.print(F("connected as ")); + Serial.println(client_id); // ... and resubscribe - client.subscribe(subprefix); + mqttClient.subscribe(subprefix); restoreState(); // if (_once) {DMXput(); _once=0;} - lanStatus=3; + lanStatus = 3; } else { Serial.print(F("failed, rc=")); - Serial.print(client.state()); + Serial.print(mqttClient.state()); Serial.println(F(" try again in 5 seconds")); - lanCheck=millis()+5000; - lanStatus=-12; + lanCheck = millis() + 5000; + lanStatus = -12; } } break; } case 3: //operation - if (!client.connected()) lanStatus=2; + if (!mqttClient.connected()) lanStatus = 2; break; //Awaiting address - case -10: if (millis()>lanCheck) - lanStatus=0; + case -10: + if (millis() > lanCheck) + lanStatus = 0; break; //Reconnect - case -12: if (millis()>lanCheck) + case -12: + if (millis() > lanCheck) - lanStatus=2; + lanStatus = 2; break; // read or Re-read config case -11: - if (loadConfig(0,NULL)) lanStatus=2; - else {lanCheck=millis()+5000;lanStatus=-10;} + if (loadConfigFromEEPROM(0, NULL)) lanStatus = 2; + else { + lanCheck = millis() + 5000; + lanStatus = -10; + } break; - case -14: ; + case -14:; // do notghing with net } @@ -424,9 +445,8 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1; { #ifndef __ESP__ wdt_dis(); - if (lanStatus>0) - switch (Ethernet.maintain()) - { + if (lanStatus > 0) + switch (Ethernet.maintain()) { case 1: //renewed fail Serial.println(F("Error: renewed fail")); @@ -470,28 +490,29 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1; } #ifdef _owire -void Changed (int i, DeviceAddress addr, int val) -{ - char addrstr[32]="NIL"; + +void Changed(int i, DeviceAddress addr, int val) { + char addrstr[32] = "NIL"; char addrbuf[17]; - char valstr[16]="NIL"; + char valstr[16] = "NIL"; char *owEmit = NULL; char *owItem = NULL; //PrintBytes(addr,8); // Serial.print("Emit: "); - SetBytes(addr,8,addrbuf);addrbuf[17]=0; + SetBytes(addr, 8, addrbuf); + addrbuf[17] = 0; //Serial.println(addrbuf); aJsonObject *owObj = aJson.getObjectItem(owArr, addrbuf); - if (owObj) - { + if (owObj) { owEmit = aJson.getObjectItem(owObj, "emit")->valuestring; - if (owEmit) - { - strncpy(addrbuf,owEmit,sizeof(addrbuf)); - Serial.print(owEmit);Serial.print("=");Serial.println(val); + if (owEmit) { + strncpy(addrbuf, owEmit, sizeof(addrbuf)); + Serial.print(owEmit); + Serial.print("="); + Serial.println(val); } owItem = aJson.getObjectItem(owObj, "item")->valuestring; } else Serial.println(F("Not find")); @@ -536,191 +557,198 @@ void Changed (int i, DeviceAddress addr, int val) } */ - if ((val==-127) || (val==85)) - { + if ((val == -127) || (val == 85)) { // Serial.print("Temp err ");Serial.println(t); return; } - strcpy_P (addrstr,outprefix); - strncat (addrstr,addrbuf,sizeof(addrstr)); + strcpy_P(addrstr, outprefix); + strncat(addrstr, addrbuf, sizeof(addrstr)); //snprintf(addrstr,sizeof(addrstr),"%s%s",F(outprefix),addrbuf); - sprintf(valstr,"%d",val); - client.publish(addrstr, valstr); + sprintf(valstr, "%d", val); + mqttClient.publish(addrstr, valstr); - if (owItem) - { - thermoSetCurTemp(owItem,val); ///TODO: Refactore using Items interface + if (owItem) { + thermoSetCurTemp(owItem, val); ///TODO: Refactore using Items interface } } + #endif -void modbusIdle(void) ; +void modbusIdle(void); void _handleHelp(int arg_cnt, char **args) //(char* tokens) { - Serial.println(F("Use the commands: 'help' - this text\n'save' - save config in NVRAM\n'get' - get config from pre-configured URL\n'load' - load config from NVRAM\n'kill' - test watchdog")); + Serial.println(F("Use the commands: 'help' - this text\n" + "'set de:ad:be:ef:fe:00' set and store MAC-address in EEPROM\n" + "'save' - save config in NVRAM\n" + "'get' - get config from pre-configured URL\n" + "'load' - load config from NVRAM\n" + "'kill' - test watchdog")); } -void _kill(int arg_cnt, char **args) -{ - for (short i=17;i>0;i--) {delay(1000);Serial.println(i);}; +void _kill(int arg_cnt, char **args) { + for (short i = 17; i > 0; i--) { + delay(1000); + Serial.println(i); + }; } #define EEPROM_offset 32+6 -void parseConfig() -{ int mc,incnt; +void parseConfigFromParsedJSON() { + int arrayItemValue, itemsCount; //DMX out is configured - aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx"); + aJsonObject *dmxoutArr = aJson.getObjectItem(aJsonObjectRoot, "dmx"); #ifdef _dmxout - if (dmxoutArr && aJson.getArraySize(dmxoutArr)==2) - { - DMXoutSetup(mc=aJson.getArrayItem(dmxoutArr,1)->valueint,aJson.getArrayItem(dmxoutArr,0)->valueint); + if (dmxoutArr && aJson.getArraySize(dmxoutArr) == 2) { + DMXoutSetup(arrayItemValue = aJson.getArrayItem(dmxoutArr, 1)->valueint, + aJson.getArrayItem(dmxoutArr, 0)->valueint); Serial.print(F("DMX out started. Channels: ")); - Serial.println(mc); + Serial.println(arrayItemValue); } #endif //DMX in is configured #ifdef _dmxin - dmxArr= aJson.getObjectItem(root, "dmxin"); - if (dmxArr && (incnt=aJson.getArraySize(dmxArr))) - { - DMXinSetup(incnt*4); + dmxArr = aJson.getObjectItem(aJsonObjectRoot, "dmxin"); + if (dmxArr && (itemsCount = aJson.getArraySize(dmxArr))) { + DMXinSetup(itemsCount * 4); Serial.print(F("DMX in started. Channels:")); - Serial.println(incnt*4); + Serial.println(itemsCount * 4); } #endif - items = aJson.getObjectItem(root,"items"); + items = aJson.getObjectItem(aJsonObjectRoot, "items"); modbusitem = items->child; - inputs = aJson.getObjectItem(root,"in"); + inputs = aJson.getObjectItem(aJsonObjectRoot, "in"); #ifdef _modbus - modbusArr= aJson.getObjectItem(root, "modbus"); + modbusArr = aJson.getObjectItem(aJsonObjectRoot, "modbus"); #endif - mqttArr= aJson.getObjectItem(root, "mqtt"); + mqttArr = aJson.getObjectItem(aJsonObjectRoot, "mqtt"); #ifdef _owire - owArr= aJson.getObjectItem(root, "ow"); + owArr = aJson.getObjectItem(aJsonObjectRoot, "ow"); #endif Serial.println(F("Configured:")); - Serial.print(F("items ")); printBool(items); - Serial.print(F("inputs ")); printBool(inputs); - Serial.print(F("modbus ")); printBool(modbusArr); - Serial.print(F("mqtt ")); printBool(mqttArr); - Serial.print(F("1-wire ")); printBool(owArr); + Serial.print(F("items ")); + printBool(items); + Serial.print(F("inputs ")); + printBool(inputs); + Serial.print(F("modbus ")); + printBool(modbusArr); + Serial.print(F("mqtt ")); + printBool(mqttArr); + Serial.print(F("1-wire ")); + printBool(owArr); #ifdef _owire - if (owArr && !owReady) - { - aJsonObject * item= owArr->child; - owReady=owSetup(&Changed); + if (owArr && !owReady) { + aJsonObject *item = owArr->child; + owReady = owSetup(&Changed); - while (item) - { - if ((item->type==aJson_Object) ) - { + while (item) { + if ((item->type == aJson_Object)) { DeviceAddress addr; //Serial.print(F("Add:")),Serial.println(item->name); - SetAddr(item->name,addr); + SetAddr(item->name, addr); owAdd(addr); } - item=item->next; + item = item->next; } } #endif } -void _loadConfig (int arg_cnt, char **args) {loadConfig(arg_cnt,args);restoreState();} -int loadConfig (int arg_cnt, char **args) +void _loadConfig(int arg_cnt, char **args) { + loadConfigFromEEPROM(arg_cnt, args); + restoreState(); +} + +int loadConfigFromEEPROM(int arg_cnt, char **args) //(char* tokens) -{ char ch; +{ + char ch; Serial.println(F("loading Config")); - ch=EEPROM.read(EEPROM_offset); - if (ch=='{') - { - aJsonEEPROMStream as=aJsonEEPROMStream(EEPROM_offset); - aJson.deleteItem(root); - root = aJson.parse(&as); + ch = EEPROM.read(EEPROM_offset); + if (ch == '{') { + aJsonEEPROMStream as = aJsonEEPROMStream(EEPROM_offset); + aJson.deleteItem(aJsonObjectRoot); + aJsonObjectRoot = aJson.parse(&as); Serial.println(); - if (!root) - { + if (!aJsonObjectRoot) { Serial.println(F("load failed")); return 0; } Serial.println(F("Loaded")); - parseConfig(); + parseConfigFromParsedJSON(); return 1; - } - else - { + } else { Serial.println(F("No stored config")); return 0; } } -void _mqttConfigReq (int arg_cnt, char **args) {mqttConfigReq(arg_cnt,args);restoreState();} +void _mqttConfigRequest(int arg_cnt, char **args) { + mqttConfigRequest(arg_cnt, args); + restoreState(); +} -int mqttConfigReq (int arg_cnt, char **args) +int mqttConfigRequest(int arg_cnt, char **args) //(char* tokens) { - char buf[25] ="/"; + char buf[25] = "/"; Serial.println(F("request MQTT Config")); - SetBytes((uint8_t*)mac,6,buf+1); - buf[13]=0; - strncat(buf,"/resp/#",25); + SetBytes((uint8_t *) mac, 6, buf + 1); + buf[13] = 0; + strncat(buf, "/resp/#", 25); Serial.println(buf); - client.subscribe(buf); - buf[13]=0; - strncat(buf,"/req/conf",25); + mqttClient.subscribe(buf); + buf[13] = 0; + strncat(buf, "/req/conf", 25); Serial.println(buf); - client.publish(buf,"1"); + mqttClient.publish(buf, "1"); } -int mqttConfigResp (char * as) -{ +int mqttConfigResp(char *as) { Serial.println(F("got MQTT Config")); //aJsonEEPROMStream as=aJsonEEPROMStream(EEPROM_offset); //aJson.deleteItem(root); - root = aJson.parse(as); + aJsonObjectRoot = aJson.parse(as); Serial.println(); - if (!root) - { + if (!aJsonObjectRoot) { Serial.println(F("load failed")); return 0; } Serial.println(F("Loaded")); - parseConfig(); + parseConfigFromParsedJSON(); return 1; } -void _saveConfig(int arg_cnt, char **args) +void _saveConfigToEEPROM(int arg_cnt, char **args) //(char* tokens) { - aJsonEEPROMStream es=aJsonEEPROMStream(EEPROM_offset); - Serial.println(F("Saving config..")); - aJson.print(root,&es); - es.putEOF(); - Serial.println(F("Saved")); - + aJsonEEPROMStream jsonEEPROMStream = aJsonEEPROMStream(EEPROM_offset); + Serial.println(F("Saving config to EEPROM..")); + aJson.print(aJsonObjectRoot, &jsonEEPROMStream); + jsonEEPROMStream.putEOF(); + Serial.println(F("Saved to EEPROM")); } -void _setConfig(int arg_cnt, char **args) -{ +void _setMacAddress(int arg_cnt, char **args) { //Serial.print("Got:"); //Serial.println(args[1]); @@ -730,158 +758,148 @@ void _setConfig(int arg_cnt, char **args) &mac[2], &mac[3], &mac[4], - &mac[5]) < 6) - { + &mac[5]) < 6) { Serial.print(F("could not parse: ")); Serial.println(args[1]); return; } printMACAddress(); - for (short i=0;i<6;i++) { EEPROM.write(i, mac[i]);} + for (short i = 0; i < 6; i++) { EEPROM.write(i, mac[i]); } Serial.println(F("Updated")); - } -void _getConfig(int arg_cnt, char **args) {getConfig(arg_cnt,args);restoreState();} +void _getConfig(int arg_cnt, char **args) { + getConfig(arg_cnt, args); + restoreState(); +} -void printBool (bool arg) -{if (arg) Serial.println(F("on")); else Serial.println(F("off"));} +void printBool(bool arg) { (arg) ? Serial.println(F("on")) : Serial.println(F("off")); } -void saveFlash(short n, char* str) -{} +void saveFlash(short n, char *str) {} -void loadFlash(short n, char* str) -{} +void loadFlash(short n, char *str) {} #ifndef MY_CONFIG_SERVER #define CONFIG_SERVER "lazyhome.ru" #else #define CONFIG_SERVER QUOTE(MY_CONFIG_SERVER) #endif -int getConfig (int arg_cnt, char **args) + +int getConfig(int arg_cnt, char **args) //(char *tokens) { - int returnCode =0; + int responseStatusCode = 0; char ch; - char URI [40]; - char server[32] = CONFIG_SERVER; - if (arg_cnt>0) { - strncpy(server,args[1],sizeof(server)-1); - saveFlash(0,server); - } - else loadFlash(0,server); + char URI[40]; + char configServer[32] = CONFIG_SERVER; + if (arg_cnt > 0) { + strncpy(configServer, args[1], sizeof(configServer) - 1); + saveFlash(0, configServer); + } else loadFlash(0, configServer); - snprintf(URI, sizeof(URI), "/%02x-%02x-%02x-%02x-%02x-%02x.config.json",mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - Serial.println(F("Config URI: "));Serial.print(F("http://"));Serial.print(server);Serial.println(URI); + snprintf(URI, sizeof(URI), "/%02x-%02x-%02x-%02x-%02x-%02x.config.json", mac[0], mac[1], mac[2], mac[3], mac[4], + mac[5]); + Serial.print(F("Config URI: http://")); + Serial.print(configServer); + Serial.println(URI); #if defined(__AVR__) - FILE* result; + FILE *result; //byte hserver[] = { 192,168,88,2 }; wdt_dis(); - HTTPClient hclient(server,80); + HTTPClient hclient(configServer, 80); // FILE is the return STREAM type of the HTTPClient - result = hclient.getURI( URI); - returnCode = hclient.getLastReturnCode(); + result = hclient.getURI(URI); + responseStatusCode = hclient.getLastReturnCode(); wdt_en(); - if (result!=NULL) { - if (returnCode==200) { + if (result != NULL) { + if (responseStatusCode == 200) { Serial.println(F("got Config")); - aJsonFileStream as=aJsonFileStream(result); - aJson.deleteItem(root); - root = aJson.parse(&as); + aJsonFileStream as = aJsonFileStream(result); + aJson.deleteItem(aJsonObjectRoot); + aJsonObjectRoot = aJson.parse(&as); hclient.closeStream(result); // this is very important -- be sure to close the STREAM - if (!root) - { + if (!aJsonObjectRoot) { Serial.println(F("Config parsing failed")); - lanCheck=millis()+15000; + lanCheck = millis() + 15000; return -11; - } - else - { - char * outstr=aJson.print(root); + } else { + char *outstr = aJson.print(aJsonObjectRoot); Serial.println(outstr); - free (outstr); + free(outstr); - parseConfig(); + parseConfigFromParsedJSON(); } - } - else { + } else { Serial.print(F("ERROR: Server returned ")); - Serial.println(returnCode); - lanCheck=millis()+5000; + Serial.println(responseStatusCode); + lanCheck = millis() + 5000; return -11; } - } - else { + } else { Serial.println(F("failed to connect")); Serial.println(F(" try again in 5 seconds")); - lanCheck=millis()+5000; + lanCheck = millis() + 5000; return -11; } #else //Non AVR code - String response; + String response; - HttpClient htclient = HttpClient(ethClient, server, 80); - htclient.setHttpResponseTimeout(4000); - wdt_res(); - //Serial.println("making GET request"); - htclient.beginRequest(); - htclient.get(URI); - htclient.endRequest(); + HttpClient htclient = HttpClient(ethClient, configServer, 80); + htclient.setHttpResponseTimeout(4000); + wdt_res(); + //Serial.println("making GET request"); + htclient.beginRequest(); + htclient.get(URI); + htclient.endRequest(); - // read the status code and body of the response - returnCode = htclient.responseStatusCode(); - response = htclient.responseBody(); - htclient.stop(); - wdt_res(); - Serial.print("HTTP Status code: "); - Serial.println(returnCode); - //Serial.print("GET Response: "); + // read the status code and body of the response + responseStatusCode = htclient.responseStatusCode(); + response = htclient.responseBody(); + htclient.stop(); + wdt_res(); + Serial.print("HTTP Status code: "); + Serial.println(responseStatusCode); + //Serial.print("GET Response: "); - if (returnCode==200) - { - aJson.deleteItem(root); - root = aJson.parse((char*) response.c_str()); + if (responseStatusCode == 200) { + aJson.deleteItem(aJsonObjectRoot); + aJsonObjectRoot = aJson.parse((char *) response.c_str()); - if (!root) - { + if (!aJsonObjectRoot) { Serial.println(F("Config parsing failed")); - // lanCheck=millis()+15000; - return -11; //Load from NVRAM - } - else - { + // lanCheck=millis()+15000; + return -11; //Load from NVRAM + } else { /* char * outstr=aJson.print(root); Serial.println(outstr); free (outstr); */ Serial.println(response); - parseConfig(); + parseConfigFromParsedJSON(); - } + } + } else { + Serial.println(F("Config retrieving failed")); + //lanCheck=millis()+15000; + return -11; //Load from NVRAM } - else - { - Serial.println(F("Config retrieving failed")); - //lanCheck=millis()+15000; - return -11; //Load from NVRAM - } #endif @@ -889,13 +907,12 @@ int getConfig (int arg_cnt, char **args) } #define TXEnablePin 13 -void preTransmission() -{ + +void preTransmission() { digitalWrite(TXEnablePin, 1); } -void postTransmission() -{ +void postTransmission() { //modbusSerial.flush(); digitalWrite(TXEnablePin, 0); } @@ -914,37 +931,35 @@ void setup_main() { #endif cmdAdd("help", _handleHelp); - cmdAdd("save", _saveConfig); + cmdAdd("save", _saveConfigToEEPROM); cmdAdd("load", _loadConfig); - cmdAdd("get", _getConfig); - cmdAdd("set", _setConfig); + cmdAdd("get", _getConfig); + cmdAdd("set", _setMacAddress); cmdAdd("kill", _kill); - cmdAdd("req", _mqttConfigReq); + cmdAdd("req", _mqttConfigRequest); #ifdef __ESP__ espSetup(); #endif - short macvalid=0; - byte defmac[6]={0xDE,0xAD,0xBE,0xEF,0xFE,0}; + short macvalid = 0; + byte defmac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0}; - for (short i=0;i<6;i++) - { - mac[i]=EEPROM.read(i); - if (mac[i]!=0 && mac[i]!=0xff) macvalid=1; + for (short i = 0; i < 6; i++) { + mac[i] = EEPROM.read(i); + if (mac[i] != 0 && mac[i] != 0xff) macvalid = 1; } - if (!macvalid) - { + if (!macvalid) { Serial.println(F("Invalid MAC: set default")); - memcpy(mac,defmac,6); + memcpy(mac, defmac, 6); } printMACAddress(); - loadConfig(0,NULL); + loadConfigFromEEPROM(0, NULL); #ifdef _modbus - pinMode(TXEnablePin,OUTPUT); + pinMode(TXEnablePin, OUTPUT); modbusSerial.begin(9600); node.idle(&modbusIdle); @@ -955,14 +970,14 @@ void setup_main() { delay(20); - owReady=0; + owReady = 0; #ifdef _owire if (net) net->idle(&owIdle); #endif //client.setServer(server, 1883); - client.setCallback(callback); + mqttClient.setCallback(callback); #ifdef _artnet @@ -977,21 +992,20 @@ void setup_main() { } -void loop_main(){ +void loop_main() { wdt_res(); //commandLine.update(); cmdPoll(); - if (lanLoop() >1) - { - client.loop(); + if (lanLoop() > 1) { + mqttClient.loop(); #ifdef _artnet if (artnet) artnet->read(); #endif } #ifdef _owire - if (owReady && owArr) owLoop(); + if (owReady && owArr) owLoop(); #endif #ifdef _dmxin @@ -1007,10 +1021,10 @@ void loop_main(){ #endif #ifdef _owire - if (items) thermoLoop(); + if (items) thermoLoop(); #endif - if (inputs) inputLoop(); + if (inputs) inputLoop(); #if defined (_espdmx) dmxout.update(); @@ -1019,8 +1033,7 @@ void loop_main(){ } // Idle handlers -void owIdle(void) -{ +void owIdle(void) { #ifdef _artnet if (artnet) artnet->read(); #endif @@ -1029,7 +1042,7 @@ void owIdle(void) return;/// Serial.print("o"); - if (lanLoop() == 1) client.loop(); + if (lanLoop() == 1) mqttClient.loop(); //if (owReady) owLoop(); #ifdef _dmxin @@ -1044,14 +1057,12 @@ void owIdle(void) } -void modbusIdle(void) -{ +void modbusIdle(void) { //Serial.print("m"); wdt_res(); - if (lanLoop() > 1) - { - client.loop(); + if (lanLoop() > 1) { + mqttClient.loop(); #ifdef _artnet if (artnet) artnet->read(); #endif @@ -1075,57 +1086,50 @@ void modbusIdle(void) -void inputLoop(void) -{ +void inputLoop(void) { - if (millis()>incheck) - { + if (millis() > incheck) { - aJsonObject * input= inputs->child; + aJsonObject *input = inputs->child; - while (input) - { - if ((input->type==aJson_Object) ) - { + while (input) { + if ((input->type == aJson_Object)) { Input in(input); in.Pool(); } - input=input->next; + input = input->next; } - incheck=millis()+50; + incheck = millis() + 50; } } -void modbusLoop(void) -{ - boolean done=false; - if (millis()>modbuscheck) - { - while (modbusitem && !done) - { - if (modbusitem->type==aJson_Array) - { - switch (aJson.getArrayItem(modbusitem, 0)->valueint) - { +void modbusLoop(void) { + boolean done = false; + if (millis() > modbuscheck) { + while (modbusitem && !done) { + if (modbusitem->type == aJson_Array) { + switch (aJson.getArrayItem(modbusitem, 0)->valueint) { case CH_MODBUS: //case CH_VCTEMP: - case CH_VC: - { + case CH_VC: { Item it(modbusitem); it.Pool(); - modbuscheck=millis()+2000; - done=true; + modbuscheck = millis() + 2000; + done = true; break; //case; } } //switch }//if - modbusitem=modbusitem->next; - if (!modbusitem) {modbusitem=items->child;return;} //start from 1-st element + modbusitem = modbusitem->next; + if (!modbusitem) { + modbusitem = items->child; + return; + } //start from 1-st element } //while }//if } @@ -1133,91 +1137,96 @@ void modbusLoop(void) // To be refactored -void thermoLoop(void) -{ +void thermoLoop(void) { #define T_ATTEMPTS 200 #define IET_TEMP 0 #define IET_ATTEMPTS 1 - if (millis()>thermocheck) - { + if (millis() > thermocheck) { - aJsonObject * item= items->child; + aJsonObject *item = items->child; - while (item) - { - if ((item->type==aJson_Array) && (aJson.getArrayItem(item, 0)->valueint==CH_THERMO) && (aJson.getArraySize(item)>4)) - { - int pin=aJson.getArrayItem(item, I_ARG)->valueint; - int temp=aJson.getArrayItem(item, I_VAL)->valueint; + while (item) { + if ((item->type == aJson_Array) && (aJson.getArrayItem(item, 0)->valueint == CH_THERMO) && + (aJson.getArraySize(item) > 4)) { + int pin = aJson.getArrayItem(item, I_ARG)->valueint; + int temp = aJson.getArrayItem(item, I_VAL)->valueint; - int cmd=aJson.getArrayItem(item, I_CMD)->valueint; + int cmd = aJson.getArrayItem(item, I_CMD)->valueint; - aJsonObject * extArr=aJson.getArrayItem(item, I_EXT); + aJsonObject *extArr = aJson.getArrayItem(item, I_EXT); - if (extArr && (aJson.getArraySize(extArr)>1) ) - { - int curtemp = aJson.getArrayItem(extArr, IET_TEMP)->valueint; - if (!aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint) - { - Serial.print(item->name);Serial.println(F(" Expired")); + if (extArr && (aJson.getArraySize(extArr) > 1)) { + int curtemp = aJson.getArrayItem(extArr, IET_TEMP)->valueint; + if (!aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint) { + Serial.print(item->name); + Serial.println(F(" Expired")); + + } else { + if (!(--aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint)) + mqttClient.publish("/alarm", item->name); } - else - { - if (! (--aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint)) client.publish("/alarm",item->name); + Serial.print(item->name); + Serial.print(F(" Set:")); + Serial.print(temp); + Serial.print(F(" Curtemp:")); + Serial.print(curtemp); + Serial.print(F(" cmd:")); + Serial.print(cmd), - } - Serial.print(item->name);Serial.print(F(" Set:"));Serial.print(temp); Serial.print(F(" Curtemp:"));Serial.print(curtemp); Serial.print(F( " cmd:")); Serial.print(cmd), - - pinMode(pin,OUTPUT); - if (cmd==CMD_OFF || cmd==CMD_HALT || aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint==0) {digitalWrite(pin,LOW);Serial.println(F(" OFF"));} - else - { - if (curtemp+GISTvalueint == 0) { + digitalWrite(pin, LOW); + Serial.println(F(" OFF")); + } else { + if (curtemp + GIST < temp) { + digitalWrite(pin, HIGH); + Serial.println(F(" ON")); + } //too cold + else if (temp <= curtemp) { + digitalWrite(pin, LOW); + Serial.println(F(" OFF")); + } //Reached settings else Serial.println(F(" --")); // Nothing to do } } } - item=item->next; + item = item->next; } - thermocheck=millis()+5000; - Serial.println(freeRam()); + thermocheck = millis() + 5000; + Serial.print(freeRam()); + Serial.print(" "); } } +short thermoSetCurTemp(char *name, short t) { + if (items) { + aJsonObject *item = aJson.getObjectItem(items, name); + if (item && (item->type == aJson_Array) && (aJson.getArrayItem(item, I_TYPE)->valueint == CH_THERMO) && + (aJson.getArraySize(item) >= 4)) { + aJsonObject *extArray = NULL; -short thermoSetCurTemp(char * name, short t) -{ - if (items) - { - aJsonObject *item= aJson.getObjectItem(items, name); - if (item && (item->type==aJson_Array) && (aJson.getArrayItem(item, I_TYPE)->valueint==CH_THERMO) && (aJson.getArraySize(item)>=4)) - { - aJsonObject * extArray =NULL; - - if (aJson.getArraySize(item)==4) //No thermo extension yet + if (aJson.getArraySize(item) == 4) //No thermo extension yet { extArray = aJson.createArray(); //Create Ext Array - aJsonObject * ocurt=aJson.createItem(t); //Create int - aJsonObject * oattempts=aJson.createItem(T_ATTEMPTS); //Create int - aJson.addItemToArray(extArray,ocurt); - aJson.addItemToArray(extArray,oattempts); - aJson.addItemToArray(item,extArray); //Adding to item + aJsonObject *ocurt = aJson.createItem(t); //Create int + aJsonObject *oattempts = aJson.createItem(T_ATTEMPTS); //Create int + aJson.addItemToArray(extArray, ocurt); + aJson.addItemToArray(extArray, oattempts); + aJson.addItemToArray(item, extArray); //Adding to item } //if - else if (extArray=aJson.getArrayItem(item,I_EXT)) - { - aJsonObject * att = aJson.getArrayItem(extArray, IET_ATTEMPTS); - aJson.getArrayItem(extArray, IET_TEMP)->valueint=t; - if (att->valueint == 0) client.publish("/alarmoff",item->name); - att->valueint =(int) T_ATTEMPTS; + else if (extArray = aJson.getArrayItem(item, I_EXT)) { + aJsonObject *att = aJson.getArrayItem(extArray, IET_ATTEMPTS); + aJson.getArrayItem(extArray, IET_TEMP)->valueint = t; + if (att->valueint == 0) mqttClient.publish("/alarmoff", item->name); + att->valueint = (int) T_ATTEMPTS; } //if diff --git a/lighthub/main.h b/lighthub/main.h index 2addc1c..3ddff81 100644 --- a/lighthub/main.h +++ b/lighthub/main.h @@ -25,14 +25,14 @@ void Changed (int i, DeviceAddress addr, int val); void modbusIdle(void); void _handleHelp(int arg_cnt, char **args); void _kill(int arg_cnt, char **args); -void parseConfig(); +void parseConfigFromParsedJSON(); void _loadConfig (int arg_cnt, char **args); -int loadConfig (int arg_cnt, char **args); -void _mqttConfigReq (int arg_cnt, char **args); -int mqttConfigReq (int arg_cnt, char **args); +int loadConfigFromEEPROM(int arg_cnt, char **args); +void _mqttConfigRequest(int arg_cnt, char **args); +int mqttConfigRequest(int arg_cnt, char **args); int mqttConfigResp (char * as); -void _saveConfig(int arg_cnt, char **args); -void _setConfig(int arg_cnt, char **args); +void _saveConfigToEEPROM(int arg_cnt, char **args); +void _setMacAddress(int arg_cnt, char **args); void _getConfig(int arg_cnt, char **args); void printBool (bool arg); void saveFlash(short n, char* str); diff --git a/lighthub/owTerm.cpp b/lighthub/owTerm.cpp index a435a4c..eec479b 100644 --- a/lighthub/owTerm.cpp +++ b/lighthub/owTerm.cpp @@ -22,67 +22,74 @@ e-mail anklimov@gmail.com #include "owTerm.h" #include #include "utils.h" +#include "options.h" + - OneWire *net = NULL; // Pass our oneWire reference to Dallas Temperature. //DallasTemperature sensors(&net); -DeviceAddress *term = NULL; +DeviceAddress *term = NULL; //int *regs = NULL; -uint16_t *wstat = NULL; +uint16_t *wstat = NULL; DallasTemperature *sensors = NULL; -short si=0; +short si = 0; int t_count = 0; -unsigned long owTimer=0; +unsigned long owTimer = 0; -owChangedType owChanged; +owChangedType owChanged; -int owUpdate() -{ - unsigned long finish = millis() + 5000; - short sr; - - //net.setStrongPullup(); - Serial.println(F("Searching")); -if (net) net->reset_search(); -for (short i=0;iwireSearch(term[t_count])>0 && (t_count millis ()) - { short ifind=-1; - if (net->crc8(term[t_count], 7) == term[t_count][7]) - { - for (short i=0;ireset_search(); + for (short i = 0; i < t_count; i++) wstat[i] &= ~SW_FIND; //absent + + while (net && net->wireSearch(term[t_count]) > 0 && (t_count < t_max) && finish > millis()) { + short ifind = -1; + if (net->crc8(term[t_count], 7) == term[t_count][7]) { + for (short i = 0; i < t_count; i++) + if (!memcmp(term[i], term[t_count], 8)) { + ifind = i; + wstat[i] |= SW_FIND; + Serial.print(F(" Node:")); + PrintBytes(term[t_count], 8); + Serial.println(F(" alive")); + break; + }; //alive + if (ifind < 0 && sensors) { + wstat[t_count] = SW_FIND; //Newly detected + Serial.print(F("dev#")); + Serial.print(t_count); + Serial.print(F(" Addr:")); + PrintBytes(term[t_count], 8); + Serial.println(); + if (term[t_count][0] == 0x28) { sensors->setResolution(term[t_count], TEMPERATURE_PRECISION); net->setStrongPullup(); - // sensors.requestTemperaturesByAddress(term[t_count]); - } - t_count++;} - }//if - } //while + // sensors.requestTemperaturesByAddress(term[t_count]); + } + t_count++; + } + }//if + } //while - Serial.print(F("1-wire count: ")); - Serial.println(t_count); + Serial.print(F("1-wire count: ")); + Serial.println(t_count); } - + int owSetup(owChangedType owCh) { - //// todo - move memory allocation to here + //// todo - move memory allocation to here #ifdef DS2482_100_I2C_TO_1W_BRIDGE Serial.println(F("DS2482_100_I2C_TO_1W_BRIDGE init")); -net = new OneWire; + net = new OneWire; #else Serial.print(F("One wire setup on PIN:")); Serial.println(QUOTE(USE_1W_PIN)); @@ -92,110 +99,104 @@ net = new OneWire (USE_1W_PIN); // Pass our oneWire reference to Dallas Temperature. -sensors = new DallasTemperature (net); + sensors = new DallasTemperature(net); -term = new DeviceAddress[t_max]; + term = new DeviceAddress[t_max]; //regs = new int [t_max]; -wstat = new uint16_t [t_max]; + wstat = new uint16_t[t_max]; - - #ifdef DS2482_100_I2C_TO_1W_BRIDGE - Wire.begin(); - if (net->checkPresence()) - { - Serial.println(F("DS2482-100 present")); - net->deviceReset(); - #ifdef APU_OFF - Serial.println(F("APU off")); - #else - net->setActivePullup(); - #endif - - Serial.println(F("\tChecking for 1-Wire devices...")); - if (net->wireReset()) - Serial.println(F("\tReset done")); - - sensors->begin(); - owChanged=owCh; - //owUpdate(); - //Serial.println(F("\t1-w Updated")); - sensors->setWaitForConversion(false); +#ifdef DS2482_100_I2C_TO_1W_BRIDGE + Wire.begin(); + if (net->checkPresence()) { + Serial.println(F("DS2482-100 present")); + net->deviceReset(); +#ifdef APU_OFF + Serial.println(F("APU off")); +#else + net->setActivePullup(); +#endif - - return true; - } - #endif - - return false; - // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement - - - delay(500); + Serial.println(F("\tChecking for 1-Wire devices...")); + if (net->wireReset()) + Serial.println(F("\tReset done")); + + sensors->begin(); + owChanged = owCh; + //owUpdate(); + //Serial.println(F("\t1-w Updated")); + sensors->setWaitForConversion(false); + + + return true; + } +#endif + + return false; + // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement + + + delay(500); } -int sensors_loop(void) - { - if (!sensors) return -1; - if (si>=t_count) - { - owUpdate(); //every check circle - scan for new devices - si=0; - return 8000; - } +int sensors_loop(void) { + if (!sensors) return -1; + if (si >= t_count) { + owUpdate(); //every check circle - scan for new devices + si = 0; + return 8000; + } + + int t; + switch (term[si][0]) { + + case 0x28: // Thermomerer + t = sensors->getTempC(term[si]);//*10.0; + //Serial.println("o"); + if (owChanged) owChanged(si, term[si], t); + sensors->requestTemperaturesByAddress(term[si]); + si++; + return 2500; + + // default + // return sensors_ext(); + } //switch + + + si++; + return check_circle; - int t; - switch (term[si][0]){ - - case 0x28: // Thermomerer - t=sensors->getTempC(term[si]);//*10.0; - //Serial.println("o"); - if (owChanged) owChanged(si,term[si],t); - sensors->requestTemperaturesByAddress(term[si]); - si++; - return 2500; - - // default - // return sensors_ext(); - } //switch - - - si++; - return check_circle; - } -void owLoop() - -{ - if (millis() >=owTimer) owTimer=millis()+sensors_loop(); +void owLoop() { + if (millis() >= owTimer) owTimer = millis() + sensors_loop(); } -int owFind(DeviceAddress addr) -{ - for (short i=0;isetResolution(term[t_count], TEMPERATURE_PRECISION); - net->setStrongPullup(); - // sensors.requestTemperaturesByAddress(term[t_count]); - } - t_count++; +void owAdd(DeviceAddress addr) { + wstat[t_count] = SW_FIND; //Newly detected + memcpy(term[t_count], addr, 8); + //term[t_count]=addr; + + Serial.print(F("dev#")); + Serial.print(t_count); + Serial.print(F(" Addr:")); + PrintBytes(term[t_count], 8); + Serial.println(); + if (term[t_count][0] == 0x28) { + sensors->setResolution(term[t_count], TEMPERATURE_PRECISION); + net->setStrongPullup(); + // sensors.requestTemperaturesByAddress(term[t_count]); + } + t_count++; } diff --git a/platformio.ini b/platformio.ini index 031343f..c5d2eee 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,8 +10,8 @@ [platformio] src_dir = lighthub env_default = -; megaatmega2560 - due + megaatmega2560 +; due [env:due] platform = atmelsam From bbf944c482999ef7c55e3eef61d045730cafd169 Mon Sep 17 00:00:00 2001 From: livello Date: Thu, 22 Mar 2018 22:31:35 +0300 Subject: [PATCH 2/7] root applyConfig And *Pool* to *Poll* of course --- lighthub/inputs.cpp | 2 +- lighthub/inputs.h | 2 +- lighthub/item.cpp | 10 ++++---- lighthub/item.h | 4 ++-- lighthub/main.cpp | 56 ++++++++++++++++++++++----------------------- lighthub/main.h | 2 +- platformio.ini | 4 ++-- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/lighthub/inputs.cpp b/lighthub/inputs.cpp index a6f9420..9aaec87 100644 --- a/lighthub/inputs.cpp +++ b/lighthub/inputs.cpp @@ -80,7 +80,7 @@ void Input::Parse() } } -int Input::Pool () +int Input::Poll() { boolean v; if (!isValid()) return -1; diff --git a/lighthub/inputs.h b/lighthub/inputs.h index faeeb94..0852ad9 100644 --- a/lighthub/inputs.h +++ b/lighthub/inputs.h @@ -87,7 +87,7 @@ class Input boolean isValid (); void Changed (int val); - int Pool (); + int Poll(); protected: void Parse(); }; diff --git a/lighthub/item.cpp b/lighthub/item.cpp index 5631a0e..326a121 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -647,7 +647,7 @@ OFF [22:25:34] => Poll: 0A 06 07 D0 00 00 88 3C -POOL 2101x10 +POLL 2101x10 [22:27:29] <= Response: 0A 03 14 00 23 00 00 27 10 13 88 0B 9C 00 32 00 F8 00 F2 06 FA 01 3F AD D0 [22:27:29] => Poll: 0A 03 08 34 00 0A 87 18 @@ -854,7 +854,7 @@ int Item::checkFM() { Serial.println(); } else { - Serial.print(F("Modbus pooling error=")); + Serial.print(F("Modbus polling error=")); Serial.println(result, HEX); } @@ -887,7 +887,7 @@ int Item::checkFM() { Serial.println(); } else { - Serial.print(F("Modbus pooling error=")); + Serial.print(F("Modbus polling error=")); Serial.println(result, HEX); } @@ -927,7 +927,7 @@ int Item::checkModbus() { Serial.println(data, HEX); checkModbus(data); } else { - Serial.print(F("Modbus pooling error=")); + Serial.print(F("Modbus polling error=")); Serial.println(result, HEX); } @@ -969,7 +969,7 @@ int Item::checkModbus(int data) { } //if data changed } -int Item::Pool() { +int Item::Poll() { switch (itemType) { case CH_MODBUS: checkModbus(); diff --git a/lighthub/item.h b/lighthub/item.h index ff35b4a..7999fd9 100644 --- a/lighthub/item.h +++ b/lighthub/item.h @@ -47,7 +47,7 @@ e-mail anklimov@gmail.com #include "aJSON.h" -extern aJsonObject *items; +extern aJsonObject *items; int txt2cmd (char * payload); @@ -85,7 +85,7 @@ class Item inline int On (){Ctrl(CMD_ON);}; inline int Off(){Ctrl(CMD_OFF);}; inline int Toggle(){Ctrl(CMD_TOGGLE);}; - int Pool (); + int Poll(); int SendCmd(short cmd,short n=0, int * Par=NULL); protected: diff --git a/lighthub/main.cpp b/lighthub/main.cpp index 7804433..0ae4104 100644 --- a/lighthub/main.cpp +++ b/lighthub/main.cpp @@ -180,7 +180,7 @@ extern Artnet *artnet; const char outprefix[] PROGMEM = "/myhome/s_out/"; #define subprefix "/myhome/in/#" -aJsonObject *aJsonObjectRoot = NULL; +aJsonObject *root = NULL; aJsonObject *items = NULL; aJsonObject *inputs = NULL; @@ -597,10 +597,10 @@ void _kill(int arg_cnt, char **args) { #define EEPROM_offset 32+6 -void parseConfigFromParsedJSON() { +void applyConfig() { int arrayItemValue, itemsCount; //DMX out is configured - aJsonObject *dmxoutArr = aJson.getObjectItem(aJsonObjectRoot, "dmx"); + aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx"); #ifdef _dmxout if (dmxoutArr && aJson.getArraySize(dmxoutArr) == 2) { DMXoutSetup(arrayItemValue = aJson.getArrayItem(dmxoutArr, 1)->valueint, @@ -611,7 +611,7 @@ void parseConfigFromParsedJSON() { #endif //DMX in is configured #ifdef _dmxin - dmxArr = aJson.getObjectItem(aJsonObjectRoot, "dmxin"); + dmxArr = aJson.getObjectItem(root, "dmxin"); if (dmxArr && (itemsCount = aJson.getArraySize(dmxArr))) { DMXinSetup(itemsCount * 4); Serial.print(F("DMX in started. Channels:")); @@ -619,18 +619,18 @@ void parseConfigFromParsedJSON() { } #endif - items = aJson.getObjectItem(aJsonObjectRoot, "items"); + items = aJson.getObjectItem(root, "items"); modbusitem = items->child; - inputs = aJson.getObjectItem(aJsonObjectRoot, "in"); + inputs = aJson.getObjectItem(root, "in"); #ifdef _modbus - modbusArr = aJson.getObjectItem(aJsonObjectRoot, "modbus"); + modbusArr = aJson.getObjectItem(root, "modbus"); #endif - mqttArr = aJson.getObjectItem(aJsonObjectRoot, "mqtt"); + mqttArr = aJson.getObjectItem(root, "mqtt"); #ifdef _owire - owArr = aJson.getObjectItem(aJsonObjectRoot, "ow"); + owArr = aJson.getObjectItem(root, "ow"); #endif Serial.println(F("Configured:")); @@ -679,15 +679,15 @@ int loadConfigFromEEPROM(int arg_cnt, char **args) ch = EEPROM.read(EEPROM_offset); if (ch == '{') { aJsonEEPROMStream as = aJsonEEPROMStream(EEPROM_offset); - aJson.deleteItem(aJsonObjectRoot); - aJsonObjectRoot = aJson.parse(&as); + aJson.deleteItem(root); + root = aJson.parse(&as); Serial.println(); - if (!aJsonObjectRoot) { + if (!root) { Serial.println(F("load failed")); return 0; } Serial.println(F("Loaded")); - parseConfigFromParsedJSON(); + applyConfig(); return 1; } else { Serial.println(F("No stored config")); @@ -726,14 +726,14 @@ int mqttConfigResp(char *as) { //aJsonEEPROMStream as=aJsonEEPROMStream(EEPROM_offset); //aJson.deleteItem(root); - aJsonObjectRoot = aJson.parse(as); + root = aJson.parse(as); Serial.println(); - if (!aJsonObjectRoot) { + if (!root) { Serial.println(F("load failed")); return 0; } Serial.println(F("Loaded")); - parseConfigFromParsedJSON(); + applyConfig(); return 1; } @@ -742,7 +742,7 @@ void _saveConfigToEEPROM(int arg_cnt, char **args) { aJsonEEPROMStream jsonEEPROMStream = aJsonEEPROMStream(EEPROM_offset); Serial.println(F("Saving config to EEPROM..")); - aJson.print(aJsonObjectRoot, &jsonEEPROMStream); + aJson.print(root, &jsonEEPROMStream); jsonEEPROMStream.putEOF(); Serial.println(F("Saved to EEPROM")); } @@ -822,20 +822,20 @@ int getConfig(int arg_cnt, char **args) Serial.println(F("got Config")); aJsonFileStream as = aJsonFileStream(result); - aJson.deleteItem(aJsonObjectRoot); - aJsonObjectRoot = aJson.parse(&as); + aJson.deleteItem(root); + root = aJson.parse(&as); hclient.closeStream(result); // this is very important -- be sure to close the STREAM - if (!aJsonObjectRoot) { + if (!root) { Serial.println(F("Config parsing failed")); lanCheck = millis() + 15000; return -11; } else { - char *outstr = aJson.print(aJsonObjectRoot); + char *outstr = aJson.print(root); Serial.println(outstr); free(outstr); - parseConfigFromParsedJSON(); + applyConfig(); } @@ -877,10 +877,10 @@ int getConfig(int arg_cnt, char **args) //Serial.print("GET Response: "); if (responseStatusCode == 200) { - aJson.deleteItem(aJsonObjectRoot); - aJsonObjectRoot = aJson.parse((char *) response.c_str()); + aJson.deleteItem(root); + root = aJson.parse((char *) response.c_str()); - if (!aJsonObjectRoot) { + if (!root) { Serial.println(F("Config parsing failed")); // lanCheck=millis()+15000; return -11; //Load from NVRAM @@ -891,7 +891,7 @@ int getConfig(int arg_cnt, char **args) free (outstr); */ Serial.println(response); - parseConfigFromParsedJSON(); + applyConfig(); } @@ -1095,7 +1095,7 @@ void inputLoop(void) { while (input) { if ((input->type == aJson_Object)) { Input in(input); - in.Pool(); + in.Poll(); } input = input->next; } @@ -1117,7 +1117,7 @@ void modbusLoop(void) { //case CH_VCTEMP: case CH_VC: { Item it(modbusitem); - it.Pool(); + it.Poll(); modbuscheck = millis() + 2000; done = true; break; //case; diff --git a/lighthub/main.h b/lighthub/main.h index 3ddff81..b892a43 100644 --- a/lighthub/main.h +++ b/lighthub/main.h @@ -25,7 +25,7 @@ void Changed (int i, DeviceAddress addr, int val); void modbusIdle(void); void _handleHelp(int arg_cnt, char **args); void _kill(int arg_cnt, char **args); -void parseConfigFromParsedJSON(); +void applyConfig(); void _loadConfig (int arg_cnt, char **args); int loadConfigFromEEPROM(int arg_cnt, char **args); void _mqttConfigRequest(int arg_cnt, char **args); diff --git a/platformio.ini b/platformio.ini index c5d2eee..031343f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,8 +10,8 @@ [platformio] src_dir = lighthub env_default = - megaatmega2560 -; due +; megaatmega2560 + due [env:due] platform = atmelsam From 70c31dd0eaea7aa108d4942a0763600f59b2e7cb Mon Sep 17 00:00:00 2001 From: livello Date: Fri, 23 Mar 2018 01:29:21 +0300 Subject: [PATCH 3/7] custom firmware mac address build_flags_template disabling freeram print removing CR if no previous thermostat printing --- README.md | 21 +++++++++++++++++---- build_flags_template.sh | 16 ++++++++++++++++ lighthub/main.cpp | 29 ++++++++++++++++++++--------- lighthub/main.h | 6 ++++++ lighthub/utils.cpp | 13 ++++++++++++- lighthub/utils.h | 1 + platformio.ini | 4 ++-- 7 files changed, 74 insertions(+), 16 deletions(-) create mode 100644 build_flags_template.sh diff --git a/README.md b/README.md index 0c17f19..77cc70c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # LightHub is Flexible, Arduino-Mega/Arduino DUE/ESP8266 based SmartHome controller -It allow to connect together: +It allows connecting together: * Contact sensors (switches, buttons etc) * 1-Wire temperature sensors (up to 20 on single bus) @@ -29,7 +29,7 @@ or to flash your DUE (need to correct path and port, of course) -# Dependences +# Dependencies (quite big number of libs required. Use git clone to have your local copy in your Arduino libs folder) Please check updates for all dependences. @@ -93,14 +93,27 @@ In linux you can open terminal, navigate to your programming directory, then * rm -Rf .piolibdeps // this will clean libraries folder. Try it if you have compilation problem * pio run -e megaatmega2560 //build for arduino mega * pio run -e due -t upload //build and upload firmware to arduino due +* platformio device monitor -b 115200 // open com port monitor with specified baud rate # Custom build flags * MY_CONFIG_SERVER=192.168.1.1 // address of external JSON-config http://192.168.1.1/de-ad-be-ef-fe-00.config.json * WATCH_DOG_TICKER_DISABLE=1 //disable wdt feature -* USE_1W_PIN=49 // use direct connection to 1W devices, no I2C bridge DS2482-100 +* USE_1W_PIN=49 // use direct connection to 1W devices on 49 pin, no I2C bridge DS2482-100 * SD_CARD_INSERTED=1 // enable sd-card support and fix lan starting * SERIAL_BAUD=115200 // set baud rate for console on Serial0 +* Wiz5500 //Use Wiznet 5500 library instead Wiznet 5100 +* DISABLE_FREERAM_PRINT // disable printing free Ram in bytes +* CUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:00 //set firmware macaddress -export PLATFORMIO_BUILD_FLAGS="-DMY_CONFIG_SERVER=192.168.1.1 -DWATCH_DOG_TICKER_DISABLE=1 -DUSE_1W_PIN=49 -DSERIAL_BAUD=115200 -DSD_CARD_INSERTED=1" +Look at build_flags_template.sh for customizing. +# Default compilation behavior: +* Config server: lazyhome.ru +* Watchdog enabled +* 1-Wire communication with DS2482-100 I2C driver +* No SD +* Serial speed 115200 +* Wiznet 5100 (for MEGA & DUE) +* Free Ram printing enabled +* de:ad:be:ef:fe:00 diff --git a/build_flags_template.sh b/build_flags_template.sh new file mode 100644 index 0000000..882b3d3 --- /dev/null +++ b/build_flags_template.sh @@ -0,0 +1,16 @@ +#! /bin/bash +# usage: +# first make your own copy of template +# cp build_flags_template.sh my_build_flags.sh +# then source it +# source my_build_flags.sh + export FLAGS="-DMY_CONFIG_SERVER=lazyhome.ru" + export FLAGS="$FLAGS -DWATCH_DOG_TICKER_DISABLE" + export FLAGS="$FLAGS -DUSE_1W_PIN=12" + export FLAGS="$FLAGS -DSD_CARD_INSERTED" + export FLAGS="$FLAGS -DSERIAL_BAUD=115200" + export FLAGS="$FLAGS -DWiz5500" + export FLAGS="$FLAGS -DDISABLE_FREERAM_PRINT" + export FLAGS="$FLAGS -DCUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:00" + export PLATFORMIO_BUILD_FLAGS="$FLAGS" + unset FLAGS \ No newline at end of file diff --git a/lighthub/main.cpp b/lighthub/main.cpp index 0ae4104..5741a06 100644 --- a/lighthub/main.cpp +++ b/lighthub/main.cpp @@ -906,8 +906,6 @@ int getConfig(int arg_cnt, char **args) return 2; } -#define TXEnablePin 13 - void preTransmission() { digitalWrite(TXEnablePin, 1); } @@ -926,6 +924,10 @@ void setup_main() { Serial.println(F("WATCHDOG TICKER DISABLED")); #endif +#ifdef DISABLE_FREERAM_PRINT + Serial.println(F("FreeRam printing DISABLED")); +#endif + #ifdef SD_CARD_INSERTED sd_card_w5100_setup(); #endif @@ -944,15 +946,22 @@ void setup_main() { #endif short macvalid = 0; - byte defmac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0}; + +#ifdef FIRMWARE_MAC + byte firmwareMacAddress[6] = FIRMWARE_MAC; +#else + byte firmwareMacAddress[6]; + const char* macStr = QUOTE(CUSTOM_FIRMWARE_MAC); + parseBytes(macStr, ':', firmwareMacAddress, 6, 16); +#endif for (short i = 0; i < 6; i++) { mac[i] = EEPROM.read(i); if (mac[i] != 0 && mac[i] != 0xff) macvalid = 1; } if (!macvalid) { - Serial.println(F("Invalid MAC: set default")); - memcpy(mac, defmac, 6); + Serial.println(F("Invalid MAC: set firmware's MAC")); + memcpy(mac, firmwareMacAddress, 6); } printMACAddress(); @@ -1143,7 +1152,7 @@ void thermoLoop(void) { #define IET_ATTEMPTS 1 if (millis() > thermocheck) { - + bool thermostatCheckPrinted = false; aJsonObject *item = items->child; while (item) { @@ -1167,6 +1176,7 @@ void thermoLoop(void) { mqttClient.publish("/alarm", item->name); } + thermostatCheckPrinted = true; Serial.print(item->name); Serial.print(F(" Set:")); Serial.print(temp); @@ -1190,18 +1200,19 @@ void thermoLoop(void) { } //Reached settings else Serial.println(F(" --")); // Nothing to do } - } } item = item->next; } - thermocheck = millis() + 5000; + +#ifndef DISABLE_FREERAM_PRINT + (thermostatCheckPrinted) ? Serial.print(F("\nfree:")) : Serial.print(F(" ")); Serial.print(freeRam()); Serial.print(" "); +#endif } - } diff --git a/lighthub/main.h b/lighthub/main.h index b892a43..e7dc8a2 100644 --- a/lighthub/main.h +++ b/lighthub/main.h @@ -5,11 +5,17 @@ #ifndef LIGHTHUB_MAIN_H #define LIGHTHUB_MAIN_H +#define TXEnablePin 13 #ifndef SERIAL_BAUD #define SERIAL_BAUD 115200 #endif +#define CUSTOM_FIRMWARE_MAC C4:3E:1f:03:1B:1E +#ifndef CUSTOM_FIRMWARE_MAC +#define FIRMWARE_MAC {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0} +#endif + #include "Arduino.h" #include "DallasTemperature.h" diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index 4459e31..b3178af 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -108,4 +108,15 @@ unsigned long freeRam() return stack_ptr - heapend + mi.fordblks; } - #endif + #endif + +void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base) { + for (int i = 0; i < maxBytes; i++) { + bytes[i] = strtoul(str, NULL, base); // Convert byte + str = strchr(str, separator); // Find next separator + if (str == NULL || *str == '\0') { + break; // No more separators, exit + } + str++; // Point to next character after separator + } +} \ No newline at end of file diff --git a/lighthub/utils.h b/lighthub/utils.h index 41eaa7e..79fe317 100644 --- a/lighthub/utils.h +++ b/lighthub/utils.h @@ -25,3 +25,4 @@ void SetAddr(char * out, uint8_t* addr); uint8_t HEX2DEC(char i); int getInt(char ** chan); unsigned long freeRam (); +void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base); \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 031343f..c5d2eee 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,8 +10,8 @@ [platformio] src_dir = lighthub env_default = -; megaatmega2560 - due + megaatmega2560 +; due [env:due] platform = atmelsam From 6497beaabb09605e4a7c5bf4d621a8db45c6b6f6 Mon Sep 17 00:00:00 2001 From: livello Date: Fri, 23 Mar 2018 01:33:52 +0300 Subject: [PATCH 4/7] CUSTOM_FIRMWARE_MAC --- lighthub/main.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lighthub/main.h b/lighthub/main.h index e7dc8a2..28bdb62 100644 --- a/lighthub/main.h +++ b/lighthub/main.h @@ -11,7 +11,6 @@ #define SERIAL_BAUD 115200 #endif -#define CUSTOM_FIRMWARE_MAC C4:3E:1f:03:1B:1E #ifndef CUSTOM_FIRMWARE_MAC #define FIRMWARE_MAC {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0} #endif From 829a7f40219fe8a8cd9fe81ebb824372b110d9f2 Mon Sep 17 00:00:00 2001 From: livello Date: Fri, 23 Mar 2018 10:52:15 +0300 Subject: [PATCH 5/7] readme.md reformat, build_flags_template comments --- README.md | 55 +++++++++++++++++++++++++++-------------- build_flags_template.sh | 4 ++- platformio.ini | 5 ++-- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 77cc70c..515953a 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,9 @@ Where is possible both, to configure local control/mapping between inputs and ou Scalability is virtually unlimited: Setup so many controllers you needed in most convenient places of your house - MQTT broker will allow controllers communicate each other and with Openhab and propagate commands across network -Prease refer our Wiki for insructions. +[Prease refer to our Wiki for insructions.](https://github.com/anklimov/lighthub/wiki/Configuring) -Finished portation of proejct to Arduino DUE and ESP8266 (ESP32 not tested) +Finished portation of project to Arduino DUE and ESP8266 (ESP32 not tested) Compiled image has been added to compiled/ folder use @@ -39,7 +39,7 @@ For patched libraries, appropriate GitHub repo URL provided: * DS2482_OneWire https://github.com/anklimov/DS2482_OneWire * FastLED * Wire (standard) -* Artnet https://github.com/anklimov/Artnet.git +* Artnet https://github.com/anklimov/Artnet.git * DmxSimple https://github.com/anklimov/DmxSimple (for AVR) or https://github.com/anklimov/ESP-Dmx (for ESP) or https://github.com/anklimov/DmxDue (for DUE) * HTTPClient (for AVR) https://github.com/anklimov/HTTPClient or https://github.com/arduino-libraries/ArduinoHttpClient for other platforms * aJson https://github.com/anklimov/aJson @@ -55,7 +55,7 @@ Portation from AVR Mega 2560 to SAM3X8E (Arduino DUE) done since v 0.96 # Platforms specific details: -AVR version is basic and have all functions +AVR version is basic and has all functions *DMX-out is software (DMXSimple) on pin3 SAM3X8E: @@ -80,27 +80,46 @@ Please, open /variants/arduino_due_x/variant.cpp file, then edit USART0_Handler void USART0_Handler(void) __attribute__((weak)); # Platformio command line build instructions -First of all install platformio framework. http://docs.platformio.org/en/latest/installation.html +[First of all install platformio framework.]( http://docs.platformio.org/en/latest/installation.html) [Good tutorial for fast start in RUSSIAN.](https://geektimes.ru/post/273852/) -https://geektimes.ru/post/273852/ // Good tutorial for fast start in RUSSIAN +In linux\macOS you can open terminal, navigate to your programming directory, then -In linux you can open terminal, navigate to your programming directory, then - -* git clone https://github.com/anklimov/lighthub.git -* cd lighthub -* pio init --ide clion // use your IDE, others here: http://docs.platformio.org/en/latest/ide.html -* pio run -e due // this will build firmware for arduino due board -* rm -Rf .piolibdeps // this will clean libraries folder. Try it if you have compilation problem -* pio run -e megaatmega2560 //build for arduino mega -* pio run -e due -t upload //build and upload firmware to arduino due -* platformio device monitor -b 115200 // open com port monitor with specified baud rate +```bash + git clone https://github.com/anklimov/lighthub.git + cd lighthub + ``` +now prepare project files for your IDE +```bash +pio init --ide [atom|clion|codeblocks|eclipse|emacs|netbeans|qtcreator|sublimetext|vim|visualstudio|vscode] +``` +Set custom build flags. first make your own copy of template +```bash +cp build_flags_template.sh my_build_flags.sh +``` +then edit, change or comment unnecessary sections and source it +```bash +nano my_build_flags.sh +source my_build_flags.sh +``` +build and upload firmware for due|megaatmega2560|esp8266 board +```bash +pio run -e due|megaatmega2560|esp8266 -t upload +``` +Clean pio libraries folder. Try it if you have compilation problem: +```bash +rm -Rf .piolibdeps +``` +open COM-port monitor with specified baud rate +```bash +platformio device monitor -b 115200 +``` # Custom build flags * MY_CONFIG_SERVER=192.168.1.1 // address of external JSON-config http://192.168.1.1/de-ad-be-ef-fe-00.config.json -* WATCH_DOG_TICKER_DISABLE=1 //disable wdt feature +* WATCH_DOG_TICKER_DISABLE //disable wdt feature * USE_1W_PIN=49 // use direct connection to 1W devices on 49 pin, no I2C bridge DS2482-100 -* SD_CARD_INSERTED=1 // enable sd-card support and fix lan starting +* SD_CARD_INSERTED // enable sd-card support and fix lan starting * SERIAL_BAUD=115200 // set baud rate for console on Serial0 * Wiz5500 //Use Wiznet 5500 library instead Wiznet 5100 * DISABLE_FREERAM_PRINT // disable printing free Ram in bytes diff --git a/build_flags_template.sh b/build_flags_template.sh index 882b3d3..c2a5a89 100644 --- a/build_flags_template.sh +++ b/build_flags_template.sh @@ -2,7 +2,9 @@ # usage: # first make your own copy of template # cp build_flags_template.sh my_build_flags.sh -# then source it +# then edit, change or comment something +# nano my_build_flags.sh +# and source it # source my_build_flags.sh export FLAGS="-DMY_CONFIG_SERVER=lazyhome.ru" export FLAGS="$FLAGS -DWATCH_DOG_TICKER_DISABLE" diff --git a/platformio.ini b/platformio.ini index c5d2eee..de602e4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,7 +11,8 @@ src_dir = lighthub env_default = megaatmega2560 -; due +; due +; esp8266 [env:due] platform = atmelsam @@ -101,7 +102,7 @@ lib_deps = https://github.com/anklimov/Artnet.git FastLED -[env:espressif8266] +[env:esp8266] platform = espressif8266 framework = arduino board = nodemcuv2 From ca44c6638730fa40a431304ee72c65eb7a9c25f6 Mon Sep 17 00:00:00 2001 From: livello Date: Fri, 23 Mar 2018 11:03:33 +0300 Subject: [PATCH 6/7] readme.md --- README.md | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 515953a..166bd74 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # LightHub -is Flexible, Arduino-Mega/Arduino DUE/ESP8266 based SmartHome controller +is Flexible, Arduino-Mega/Arduino DUE/ESP8266 based SmartHome controller. [RU](https://geektimes.ru/post/295109/) It allows connecting together: @@ -12,23 +12,24 @@ It allows connecting together: Where is possible both, to configure local control/mapping between inputs and outputs (light, floor heating thermostats) and remote control from Openhab or Openhab2 Smarthome software -Scalability is virtually unlimited: Setup so many controllers you needed in most convenient places of your house - MQTT broker will allow controllers communicate each other and with Openhab and propagate commands across network +Scalability is virtually unlimited: Setup so many controllers you needed in most convenient places of your house - MQTT broker will allow controllers communicate each other and with Openhab and propagate commands across network. [Prease refer to our Wiki for insructions.](https://github.com/anklimov/lighthub/wiki/Configuring) -Finished portation of project to Arduino DUE and ESP8266 (ESP32 not tested) +Finished portation of project to Arduino DUE and ESP8266 (ESP32 not tested). -Compiled image has been added to compiled/ folder -use +Compiled image has been added to [compiled/](https://github.com/anklimov/lighthub/tree/master/compiled) folder. Flash your Mega 2560 + +```bash avrdude -v -V -patmega2560 -cwiring -b115200 -D -Uflash:w:lighthub.ino.hex:i -to flash your Mega 2560 +``` -or +or flash your DUE (need to correct path and port, of course) +```bash +/Users//Library/Arduino15/packages/arduino/tools/bossac/1.6.1-arduino/bossac -i -d --port=cu.usbmodem1451 -U false -e -w -v -b lighthub.ino.bin -R +``` -/Users//Library/Arduino15/packages/arduino/tools/bossac/1.6.1-arduino/bossac -i -d --port=cu.usbmodem1451 -U false -e -w -v -b lighthub.ino.bin -R -to flash your DUE -(need to correct path and port, of course) # Dependencies (quite big number of libs required. Use git clone to have your local copy in your Arduino libs folder) Please check updates for all dependences. @@ -58,21 +59,21 @@ Portation from AVR Mega 2560 to SAM3X8E (Arduino DUE) done since v 0.96 AVR version is basic and has all functions *DMX-out is software (DMXSimple) on pin3 -SAM3X8E: -*default PWM frequency -*both, DMX-in and DMX-out are hardware USART based. Use USART1 (pins 18 and 19) for DMX-out and DMX-in +**SAM3X8E**: +* default PWM frequency +* both, DMX-in and DMX-out are hardware USART based. Use USART1 (pins 18 and 19) for DMX-out and DMX-in -ESP: -*DMX-OUT on USART1 TX -*DMX-IN - not possible to deploy in ESP8266 -*Modbus - disabled. Might be configured in future on USART0 instead CLI/DEBUG +**ESP8266**: +* DMX-OUT on USART1 TX +* DMX-IN - not possible to deploy in ESP8266 +* Modbus - disabled. Might be configured in future on USART0 instead CLI/DEBUG since v. 0.97: There is first attempt to use Wiznet 5500 (still not stable enough) Need to use compiler directive -D Wiz5500 and https://github.com/anklimov/Ethernet2 library -First attempt to use platformio toolchain for compiling (work not completed yet) +Prefered way to compile project is using platformio toolchain, suitable for Arduino Due, and Arduino Mega2560, but work is still in progress. # Due compilation issue "USART0_Handler redefinition" Please, open /variants/arduino_due_x/variant.cpp file, then edit USART0_Handler method definition like this From 642f20de8c85eb00185b5383acd8053422001a32 Mon Sep 17 00:00:00 2001 From: livello Date: Fri, 23 Mar 2018 13:35:52 +0300 Subject: [PATCH 7/7] DMX Modbus OneWire support now can be disabled --- README.md | 6 ++ build_flags_template.sh | 3 + lighthub/main.cpp | 18 ++---- lighthub/options.h | 11 +++- lighthub/utils.cpp | 118 ++++++++++++++++++++-------------------- platformio.ini | 4 +- 6 files changed, 86 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index 166bd74..f73de3c 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,9 @@ platformio device monitor -b 115200 * Wiz5500 //Use Wiznet 5500 library instead Wiznet 5100 * DISABLE_FREERAM_PRINT // disable printing free Ram in bytes * CUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:00 //set firmware macaddress +* DMX_DISABLE //disable DMX support +* MODBUS_DISABLE // disable Modbus support +* OWIRE_DISABLE // disable OneWire support Look at build_flags_template.sh for customizing. @@ -137,3 +140,6 @@ Look at build_flags_template.sh for customizing. * Wiznet 5100 (for MEGA & DUE) * Free Ram printing enabled * de:ad:be:ef:fe:00 +* DMX support enabled +* Modbus support enabled +* OneWire support enabled diff --git a/build_flags_template.sh b/build_flags_template.sh index c2a5a89..0e97a40 100644 --- a/build_flags_template.sh +++ b/build_flags_template.sh @@ -14,5 +14,8 @@ export FLAGS="$FLAGS -DWiz5500" export FLAGS="$FLAGS -DDISABLE_FREERAM_PRINT" export FLAGS="$FLAGS -DCUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:00" + export FLAGS="$FLAGS -DDMX_DISABLE" + export FLAGS="$FLAGS -DMODBUS_DISABLE" + export FLAGS="$FLAGS -DOWIRE_DISABLE" export PLATFORMIO_BUILD_FLAGS="$FLAGS" unset FLAGS \ No newline at end of file diff --git a/lighthub/main.cpp b/lighthub/main.cpp index 5741a06..395f994 100644 --- a/lighthub/main.cpp +++ b/lighthub/main.cpp @@ -122,9 +122,10 @@ DueFlashStorage EEPROM; #define wdt_en() #define wdt_dis() - #else +#include "Dhcp.h" + #ifdef Wiz5500 #include #else @@ -447,31 +448,24 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1; wdt_dis(); if (lanStatus > 0) switch (Ethernet.maintain()) { - case 1: + case DHCP_CHECK_RENEW_FAIL: //renewed fail Serial.println(F("Error: renewed fail")); lanStatus = -10; break; - case 2: - //renewed success + case DHCP_CHECK_RENEW_OK: Serial.println(F("Renewed success")); - - //print your local IP address: printIPAddress(); break; - case 3: - //rebind fail + case DHCP_CHECK_REBIND_FAIL: Serial.println(F("Error: rebind fail")); lanStatus = -10; break; - case 4: - //rebind success + case DHCP_CHECK_REBIND_OK: Serial.println(F("Rebind success")); - - //print your local IP address: printIPAddress(); break; diff --git a/lighthub/options.h b/lighthub/options.h index ce8d76e..92bbdd0 100644 --- a/lighthub/options.h +++ b/lighthub/options.h @@ -1,8 +1,17 @@ // Configuration of drivers enabled +#ifndef DMX_DISABLE #define _dmxin #define _dmxout +#endif + +#ifndef OWIRE_DISABLE #define _owire -#define _modbus +#endif + +#ifndef MODBUS_DISABLE +#define _modbus +#endif + #define _artnet #if defined(ESP8266) diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index b3178af..0509cf0 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -19,6 +19,7 @@ e-mail anklimov@gmail.com */ #include "utils.h" + #if defined(__SAM3X8E__) #include #endif @@ -29,63 +30,62 @@ extern "C" { } #endif -void PrintBytes(uint8_t* addr, uint8_t count, bool newline) { - for (uint8_t i = 0; i < count; i++) { - Serial.print(addr[i]>>4, HEX); - Serial.print(addr[i]&0x0f, HEX); - } - if (newline) - Serial.println(); +void PrintBytes(uint8_t *addr, uint8_t count, bool newline) { + for (uint8_t i = 0; i < count; i++) { + Serial.print(addr[i] >> 4, HEX); + Serial.print(addr[i] & 0x0f, HEX); + } + if (newline) + Serial.println(); } -const char HEXSTR[]="0123456789ABCDEF"; +const char HEXSTR[] = "0123456789ABCDEF"; + +void SetBytes(uint8_t *addr, uint8_t count, char *out) { + // Serial.println("SB:"); + for (uint8_t i = 0; i < count; i++) { + *(out++) = HEXSTR[(addr[i] >> 4)]; + *(out++) = HEXSTR[(addr[i] & 0x0f)]; + } + *out = 0; -void SetBytes(uint8_t* addr, uint8_t count, char * out) { - // Serial.println("SB:"); - for (uint8_t i = 0; i < count; i++) { - *(out++)=HEXSTR[(addr[i]>>4)]; - *(out++)=HEXSTR[(addr[i]&0x0f)]; - } - *out=0; - } -byte HEX2DEC(char i) -{ byte v; -if ('a' <= i && i <='f') { v=i-97+10; } - else if ('A' <= i && i <='F') { v=i-65+10; } - else if ('0' <= i && i <='9') { v=i-48; } - return v; - } +byte HEX2DEC(char i) { + byte v; + if ('a' <= i && i <= 'f') { v = i - 97 + 10; } + else if ('A' <= i && i <= 'F') { v = i - 65 + 10; } + else if ('0' <= i && i <= '9') { v = i - 48; } + return v; +} -void SetAddr(char * out, uint8_t* addr) { - - for (uint8_t i = 0; i < 8; i++) { - *addr=HEX2DEC(*out++)<<4; - *addr++|=HEX2DEC(*out++); - } +void SetAddr(char *out, uint8_t *addr) { + + for (uint8_t i = 0; i < 8; i++) { + *addr = HEX2DEC(*out++) << 4; + *addr++ |= HEX2DEC(*out++); + } } -int getInt(char ** chan) -{ - int ch = atoi(*chan); - *chan=strchr(*chan,','); - - if (*chan) *chan+=1; - //Serial.print(F("Par:")); Serial.println(ch); - return ch; - +int getInt(char **chan) { + int ch = atoi(*chan); + *chan = strchr(*chan, ','); + + if (*chan) *chan += 1; + //Serial.print(F("Par:")); Serial.println(ch); + return ch; + } #if defined(ESP8266) -unsigned long freeRam () +unsigned long freeRam () {return system_get_free_heap_size();} #endif -#if defined(__AVR__) +#if defined(__AVR__) unsigned long freeRam () { extern int __heap_start, *__brkval; @@ -98,25 +98,25 @@ unsigned long freeRam () extern char _end; extern "C" char *sbrk(int i); -unsigned long freeRam() -{ - char *ramstart = (char *) 0x20070000; - char *ramend = (char *) 0x20088000; - char *heapend = sbrk(0); - register char * stack_ptr asm( "sp" ); - struct mallinfo mi = mallinfo(); - - return stack_ptr - heapend + mi.fordblks; -} - #endif +unsigned long freeRam() { + char *ramstart = (char *) 0x20070000; + char *ramend = (char *) 0x20088000; + char *heapend = sbrk(0); + register char *stack_ptr asm( "sp" ); + struct mallinfo mi = mallinfo(); -void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base) { - for (int i = 0; i < maxBytes; i++) { - bytes[i] = strtoul(str, NULL, base); // Convert byte - str = strchr(str, separator); // Find next separator - if (str == NULL || *str == '\0') { - break; // No more separators, exit + return stack_ptr - heapend + mi.fordblks; +} + +#endif + +void parseBytes(const char *str, char separator, byte *bytes, int maxBytes, int base) { + for (int i = 0; i < maxBytes; i++) { + bytes[i] = strtoul(str, NULL, base); // Convert byte + str = strchr(str, separator); // Find next separator + if (str == NULL || *str == '\0') { + break; // No more separators, exit + } + str++; // Point to next character after separator } - str++; // Point to next character after separator - } } \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index de602e4..5e4e1d5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,8 +10,8 @@ [platformio] src_dir = lighthub env_default = - megaatmega2560 -; due +; megaatmega2560 + due ; esp8266 [env:due]