Ultrasonic sensor added

CAN driver logic/relability  improved
string -> itemCmd functionality added,
cold boot w/o config procedure improved
This commit is contained in:
2024-04-12 11:00:42 +03:00
parent 4fff338482
commit 5b5e6e3d6a
16 changed files with 275 additions and 87 deletions

View File

@@ -15,6 +15,7 @@
-D CANDRV
-D THERMOSTAT_CHECK_PERIOD=5000
-D ULTRASONIC
-DENABLE_HWSERIAL1

Binary file not shown.

View File

@@ -52,7 +52,7 @@ bool canDriver::upTime(uint32_t ut)
packet.metric1=ut;
debugSerial<<("UpTime")<<endl;
debugSerial<<("CAN: UpTime")<<endl;
return write (id.id, &packet, 4);
}
@@ -69,7 +69,7 @@ bool canDriver::salt(uint32_t salt)
packet.metric1=salt;
debugSerial<<("Salt")<<endl;
debugSerial<<("CAN: Salt")<<endl;
return write (id.id, &packet, 4);
}
@@ -88,7 +88,7 @@ bool canDriver::lookupMAC()
memcpy(packet.mac,sysConf.mac,6);
debugSerial<<("Lookup MAC")<<endl;
debugSerial<<("CAN: Lookup MAC")<<endl;
res=write (id.id, &packet, 6);
if (res) state=canState::MACLookup;
else state=canState::Error;
@@ -96,7 +96,7 @@ bool canDriver::lookupMAC()
return res;
}
bool canDriver::requestFrame(uint8_t devId, payloadType _payloadType )
bool canDriver::requestFrame(uint8_t devId, payloadType _payloadType, uint16_t seqNo )
{
canid_t id;
datagram_t packet;
@@ -107,11 +107,11 @@ bool canDriver::requestFrame(uint8_t devId, payloadType _payloadType )
id.status=0;
id.payloadType=_payloadType;
id.deviceId=devId;
id.itemId=0; //CRC?
id.itemId=seqNo;
packet.metric1 =0;
//memcpy(packet.mac,sysConf.mac,6);
debugSerial<<("Request frame ")<<_payloadType<<F(" for id ")<<devId<<endl;
//delay (100);
debugSerial<<("CAN: Request frame ")<<_payloadType<<F(" for id ")<<devId<<F(" seq:")<<seqNo<<endl;
res=write (id.id,&packet,1);
if (res) state=canState::FrameRequested;
else state=canState::Error;
@@ -134,7 +134,7 @@ bool canDriver::sendRemoteID(macAddress mac)
id.itemId=200; //CRC16 of remote config
//packet.data[0]=1;
debugSerial<<("Send remote ID")<<endl;
debugSerial<<("CAN: Send remote ID")<<endl;
res = write (id.id);//,&packet,8);
if (res) state=canState::Idle;
else state=canState::Error;
@@ -173,7 +173,7 @@ bool canDriver::begin()
}
#endif
debugSerial<<"CAN initialized"<<endl;
debugSerial<<"CAN: initialized"<<endl;
controllerId = getMyId();
ready=true;
return true;
@@ -200,7 +200,7 @@ int canDriver::readFrame()
if (packetSize ){//|| CAN.packetId() != -1) {
// received a packet
debugSerialPort.print("Received ");
debugSerialPort.print("CAN: Received ");
if (CAN.packetExtended()) {
debugSerialPort.print("extended ");
@@ -271,7 +271,7 @@ switch (state)
{
responseTimer=millisNZ();
state=canState::Error;
errorSerial<<"CAN Timeout"<<endl;
errorSerial<<"CAN: lookup Timeout"<<endl;
}
break;
@@ -288,25 +288,25 @@ switch (state)
if (configLocked) return; // only in safe moments
configLocked++;
infoSerial<<F("Requesting Config from CAN")<<endl;
infoSerial<<F("CAN: Requesting Config")<<endl;
CANConfStream.open(controllerId,payloadType::configFrame,'r');
if (CANConfStream.peek() == '{') {
debugSerial<<F("JSON detected")<<endl;
debugSerial<<F("CAN: JSON detected")<<endl;
aJsonStream as = aJsonStream(&CANConfStream);
cleanConf(false);
root = aJson.parse(&as);
CANConfStream.close();
if (!root) {
errorSerial<<F("load failed")<<endl;
errorSerial<<F("CAN: config load failed")<<endl;
sysConf.setETAG("");
// sysConfStream.close();
configLocked--;
state = canState::Error;
return;
}
infoSerial<<F("Loaded from CAN")<<endl;
infoSerial<<F("CAN: config Loaded")<<endl;
configLocked--;
applyConfig();
sysConf.loadETAG();
@@ -314,7 +314,7 @@ switch (state)
return ;
}
CANConfStream.close();
infoSerial<<F("Config not loaded")<<endl;
infoSerial<<F("CAN: Config not loaded")<<endl;
state = canState::Error;
configLocked--;
}
@@ -328,7 +328,7 @@ switch (state)
bool canDriver::processPacket(canid_t id, datagram_t *packet, uint8_t len, bool rtr)
{
debugSerial.print("CAN Received ");
debugSerial.print("CAN: Received ");
debugSerial.print(len);
debugSerial.print(" bytes id 0x");
debugSerial.print(id.id,HEX);
@@ -379,7 +379,7 @@ if (id.status){
case canState::MACLookup:
if ((id.payloadType == payloadType::lookupMAC))
{
debugSerial<<"Got Controller CAN addr: "<<id.deviceId<<endl;
debugSerial<<"\nCAN: Got Controller addr: "<<id.deviceId<<endl;
controllerId=id.deviceId;
state = canState::ReadConfig;
}
@@ -388,7 +388,7 @@ if (id.status){
case canState::FrameRequested:
if ((id.payloadType == payloadType::configFrame) && (id.deviceId == controllerId))
{
errorSerial<<F("Config received when not expected")<<endl;
errorSerial<<F("CAN: Config received when not expected")<<endl;
}
break;
@@ -432,13 +432,13 @@ else //Requests
return sendRemoteID(packet->mac);
//debugSerial<<"ID requested"<<endl;
}
else if (id.payloadType == payloadType::configFrame)
else if ((id.payloadType == payloadType::configFrame) && (id.itemId == 0xFFFF))
{
debugSerial<<F("Requested conf for dev#")<<id.deviceId<<endl;
debugSerial<<F("CAN: Requested conf for dev#")<<id.deviceId<<endl;
aJsonObject * remoteConfObj = findConfbyID(id.deviceId);
if (remoteConfObj)
{
infoSerial<<F("Sending conf for dev#")<<id.deviceId<<endl;
infoSerial<<F("CAN: Sending conf for dev#")<<id.deviceId<<endl;
CANConfStream.open(id.deviceId,payloadType::configFrame,'w');
aJsonStream outStream = aJsonStream(&CANConfStream);
aJson.print(remoteConfObj, &outStream);
@@ -510,7 +510,7 @@ uint8_t canDriver::getIdByMac(macAddress mac)
if (i < 5) macStr[strptr++]=':';
}
debugSerial<<F("Searching devId for ")<<macStr<<endl;
debugSerial<<F("CAN: Searching devId for ")<<macStr<<endl;
aJsonObject * remoteConfObj = aJson.getObjectItem(confObj, macStr);
if (!remoteConfObj) return 0;
@@ -522,7 +522,7 @@ aJsonObject * addrObj = aJson.getObjectItem(remoteCanObj, "addr");
if (!addrObj) return 0;
if (addrObj && (addrObj->type == aJson_Int))
{
debugSerial<<F("find dev#")<< addrObj->valueint << endl;
debugSerial<<F("CAN: find dev#")<< addrObj->valueint << endl;
return addrObj->valueint;
}
@@ -531,7 +531,7 @@ return 0;
bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
{ //return 0;
if (!ready) errorSerial<<"CAN not initialized"<<endl;
if (!ready) errorSerial<<"CAN: not initialized"<<endl;
bool res;
if (size>8) size = 8;
@@ -542,8 +542,8 @@ bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
CAN_TX_msg.id = msg_id;
CAN_TX_msg.flags.extended = 1; // To enable extended ID
CAN_TX_msg.len=size;
if (res=STMCan.write(CAN_TX_msg)) debugSerial<<("CAN Wrote ")<<size<<" bytes, id "<<_HEX(msg_id)<<endl;
else debugSerial.println("CAN Write error");
if (res=STMCan.write(CAN_TX_msg)) debugSerial<<("CAN: Wrote ")<<size<<" bytes, id "<<_HEX(msg_id)<<endl;
else debugSerial.println("CAN: Write error");
return res;
#endif
@@ -552,8 +552,8 @@ bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
CAN.beginExtendedPacket(msg_id,size);
CAN.write(buf->data,size);
//for(uint8_t i=0;i<size; i++) CAN.write(buf[i]);
if (res=CAN.endPacket()) debugSerial<< ("CAN Wrote ")<<size << " bytes, id "<<_HEX(msg_id)<<endl;
else debugSerial.println("CAN Write error");
if (res=CAN.endPacket()) debugSerial<< ("CAN: Wrote ")<<size << " bytes, id "<<_HEX(msg_id)<<endl;
else debugSerial.println("CAN: Write error");
return res;
#endif
@@ -565,8 +565,8 @@ bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
//outgoing.priority = 4; //0-15 lower is higher priority
if (buf) for(uint8_t i=0;i<size; i++) CAN_TX_msg.data.bytes[i]=buf->data[i];
res=Can0.sendFrame(CAN_TX_msg);
if (res) debugSerial<<("CAN Wrote ")<<size<<" bytes, id "<<_HEX(msg_id)<<endl;
else debugSerial.println("CAN Write error");
if (res) debugSerial<<("CAN: Wrote ")<<size<<" bytes, id "<<_HEX(msg_id)<<endl;
else debugSerial.println("CAN: Write error");
return res;
#endif
}
@@ -592,6 +592,16 @@ bool canDriver::sendCommand(aJsonObject * can,itemCmd cmd, bool status)
{
aJsonObject * dev = aJson.getArrayItem(can,0);
aJsonObject * it = aJson.getArrayItem(can,1);
aJsonObject * sfx = aJson.getArrayItem(can,2);
if (sfx)
switch (sfx->type)
{
case aJson_Int: cmd.setSuffix(sfx->valueint);
break;
case aJson_String:
int suffix=txt2subItem(sfx->valuestring);
if (suffix) cmd.setSuffix(suffix);
}
debugSerial<<dev->valueint << ":" << it->valueint<<endl;
if (dev && it && dev->type == aJson_Int && it->type == aJson_Int)
return sendCommand(dev->valueint, it->valueint, cmd, status);
@@ -621,8 +631,8 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
res=write (id.id,&packet,8);
if (res) debugSerial<<F(" ok")<<endl;
else debugSerial<<F(" fail")<<endl;
if (res) debugSerial<<F("CAN: sent ok")<<endl;
else debugSerial<<F("CAN: fail")<<endl;
return res;
}
@@ -632,7 +642,7 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
////////////////////////////// Steream //////////////////////////
int canStream::send(uint8_t len)
int canStream::send(uint8_t len, uint16_t _seqNo)
{
canid_t id;
datagram_t packet;
@@ -642,7 +652,7 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
id.status=1;
id.payloadType=pType;
id.deviceId=devId;
id.itemId=0; // chunk?
id.itemId=_seqNo;
res=driver->write (id.id, &writeBuffer, len);
writePos=0;
@@ -662,7 +672,7 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
{
case canState::StreamOpenedRead:
readPos = 0;
res= driver->requestFrame(devId,pType); //Requesting frame;
res= driver->requestFrame(devId,pType,seqNo); //Requesting frame;
if (res)
state = canState::FrameRequested;
else
@@ -670,29 +680,40 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
state = canState::Error;
return -1;
}
if (seqNo ==0xFFFF) seqNo =0;
//continue
case canState::FrameRequested:
{
uint32_t timer = millis();
int c;
uint32_t timer = millis();
do {
debugSerial.print(".");
//debugSerial.print(".");
yield();
if (c=driver->readFrame()>0 && (driver->RXid.deviceId == devId) && (driver ->RXid.payloadType == pType))
if ((c=driver->readFrame()>0) && (driver->RXid.deviceId == devId) && (driver ->RXid.payloadType == pType) && driver->RXid.status)
{
state = canState::FrameReceived;
debugSerial<<F("Payload received ")<< c << "|" <<driver->RXlen<< " "<<driver->RXpacket.payload<<endl;;
debugSerial<<F("CAN: Payload received ")<< c << "|" <<driver->RXlen<< " "<<driver->RXpacket.payload<<"#"<<driver->RXid.itemId<<endl;
seqNo=driver->RXid.itemId;
failedCount=0;
return driver->RXlen;
}
} while((!isTimeOver(timer,millis(),1000UL)) );
debugSerial<<F("RX data awaiting timeout")<<endl;
debugSerial<<F("CAN: RX data awaiting timeout #")<<failedCount<<endl;
if (failedCount>=3)
{
state = canState::Error;
return -1;
}
failedCount++;
state = canState::StreamOpenedRead;
}
return -1;
break;
case canState::FrameReceived:
@@ -707,7 +728,22 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
(driver->RXid.payloadType == pType) &&
(driver->RXid.status == 0)
)
{
debugSerial<<F("CAN: frame confirmed #")<<driver->RXid.itemId<<endl;
if (seqNo == driver->RXid.itemId)
{
state = canState::StreamOpenedWrite;
seqNo++;
}
else
{
state = canState::Error;
errorSerial<<F("CAN: wrong seqNum")<<endl;
return -1;
}
}
return 0;
}
return driver->RXlen;
@@ -772,7 +808,7 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
if (isTimeOver(timer,millis(),1000UL))
{
state = canState::Error;
errorSerial<<F("CAN write timeout")<<endl;
errorSerial<<F("CAN: write timeout")<<endl;
return -1;
}
@@ -782,7 +818,7 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
writeBuffer.data[writePos++]=c;
if (writePos>=8)
{
bool res = send(8);
bool res = send(8,seqNo);
if (res) state = canState::waitingConfirm;
else state = canState::Error;
return res;
@@ -791,7 +827,7 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
void canStream::flush()
{
send(writePos);
send(writePos,seqNo);
};

View File

@@ -118,7 +118,7 @@ bool sendCommand(aJsonObject * can,itemCmd cmd, bool status = false);
bool upTime(uint32_t ut);
bool salt(uint32_t salt);
bool lookupMAC();
bool requestFrame(uint8_t devId, payloadType _payloadType );
bool requestFrame(uint8_t devId, payloadType _payloadType, uint16_t seqNo );
int readFrame();
bool sendRemoteID(macAddress mac);
bool begin();
@@ -161,13 +161,15 @@ extern aJsonObject * topics;
class canStream : public Stream
{
public:
canStream(canDriver * _driver) : readPos(0),writePos(0),devId(0), pType(payloadType::unknown),state(canState::stateUnknown){driver=_driver; }
canStream(canDriver * _driver) : readPos(0),writePos(0),devId(0), pType(payloadType::unknown),state(canState::stateUnknown),seqNo(0),failedCount(0){driver=_driver; }
int open(uint8_t controllerID, payloadType _pType, char _mode)
{
if (mode) close();
devId=controllerID;
pType = _pType;
mode = _mode;
seqNo=0xFFFF;
failedCount=0;
if (mode == 'w') state=canState::StreamOpenedWrite;
else state=canState::StreamOpenedRead;
return 1;
@@ -194,7 +196,7 @@ public:
private:
int send(uint8_t len);
int send(uint8_t len, uint16_t _seqNo);
int checkState();
canDriver * driver;
unsigned int readPos;
@@ -203,6 +205,8 @@ private:
datagram_t writeBuffer;
uint8_t devId;
uint16_t seqNo;
int8_t failedCount;
char mode;
payloadType pType;
canState state;

View File

@@ -44,6 +44,14 @@ extern canDriver LHCAN;
#include "Adafruit_MCP23X17.h"
Adafruit_MCP23X17 mcp;
#endif
#ifdef ULTRASONIC
#define US_TRIG PA_14 //pin49
#define US_ECHO PA_15 //pin50
#include "Ultrasonic.h"
Ultrasonic ultrasonic(US_TRIG, US_ECHO);
#endif
#if not defined (NOIP)
extern PubSubClient mqttClient;
#endif
@@ -107,6 +115,7 @@ void Input::Parse(aJsonObject * configObj)
store = NULL;
inType = 0;
pin = 0;
pin2 =0;
if (!inputObj || !root) return;
if (!configObj) configObj = inputObj;
@@ -118,10 +127,25 @@ void Input::Parse(aJsonObject * configObj)
if (itemBuffer) inType = static_cast<uint8_t>(itemBuffer->valueint);
itemBuffer = aJson.getObjectItem(configObj, "#");
if (itemBuffer) pin = static_cast<uint8_t>(itemBuffer->valueint);
else pin = static_cast<uint8_t>(atoi(configObj->name));
if (itemBuffer)
switch (itemBuffer->type)
{
case aJson_Int:
pin = static_cast<uint8_t>(itemBuffer->valueint);
break;
case aJson_Array:
if ((itemBuffer->child) && (itemBuffer->child->type == aJson_Int))
{
pin = static_cast<uint8_t>(itemBuffer->child->valueint);
if ((itemBuffer->child->child) && (itemBuffer->child->child->type == aJson_Int))
pin = static_cast<uint8_t>(itemBuffer->child->child->valueint);
}
} //switch
else pin = static_cast<uint8_t>(atoi(configObj->name));
}
// Persistant storage
itemBuffer = aJson.getObjectItem(inputObj, "@S");
if (!itemBuffer) {
@@ -135,8 +159,10 @@ void Input::Parse(aJsonObject * configObj)
void cleanStore(aJsonObject * input)
{
if (input->type == aJson_Object) {
if (input && (input->type == aJson_Object)) {
// Check for nested inputs
Input in(input);
in.store->aslong = 0;
aJsonObject * inputArray = aJson.getObjectItem(input, "act");
if (inputArray && (inputArray->type == aJson_Array))
{
@@ -153,9 +179,8 @@ if (input->type == aJson_Object) {
}
else
{
Input in(input);
in.store->aslong = 0;
//in.Poll(CHECK_INPUT);
// Input in(input);
// in.store->aslong = 0;
}
}
}
@@ -267,6 +292,14 @@ switch (cause) {
break;
}
break;
case CHECK_ULTRASONIC:
switch (inType)
{
case IN_ULTRASONIC:
analogPoll(cause);
contactPoll(cause);
}
break;
case CHECK_SENSOR: //Slow polling
switch (inType)
{
@@ -528,7 +561,8 @@ debugSerial << F("IN:") << pin << F(" DHT22 type. T=") << temp << F("°C H=") <<
#endif
// TODO Polling via timed interrupt with CHECK_INTERRUPT cause
bool Input::changeState(uint8_t newState, short cause)
bool Input::
changeState(uint8_t newState, short cause)
{
if (!inputObj || !store) return false;
@@ -666,8 +700,11 @@ if (newState!=store->state && cause!=CHECK_INTERRUPT) debugSerial<<F("#")<<pin<<
static volatile uint8_t contactPollBusy = 0;
void Input::contactPoll(short cause) {
boolean currentInputState;
bool currentInputState;
if (!store /*|| contactPollBusy*/) return;
if ((inType == IN_ULTRASONIC) && (cause!=CHECK_ULTRASONIC)) return;
contactPollBusy++;
changeState(IS_REQSTATE,cause); //Check for postponed states transitions
@@ -684,9 +721,9 @@ if (inType & IN_I2C)
currentInputState = (inCache.I2CReadBit(IN_I2C,0,pin) == inputOnLevel);
else
#endif
if (isAnalogPin(pin) && (mapObj=aJson.getObjectItem(inputObj, "map")) && mapObj->type == aJson_Array)
if ((isAnalogPin(pin) || (inType == IN_ULTRASONIC)) && (mapObj=aJson.getObjectItem(inputObj, "map")) && mapObj->type == aJson_Array)
{
int value = inCache.analogReadCached(pin);
int value = inCache.analogReadCached(pin,pin2,inType);
if (value >= aJson.getArrayItem(mapObj, 0)->valueint && value <= aJson.getArrayItem(mapObj, 1)->valueint)
currentInputState = true;
else currentInputState = false;
@@ -896,7 +933,7 @@ void Input::analogPoll(short cause) {
pinMode(pin, inputPinMode);
*/
inputVal = inCache.analogReadCached(pin);
inputVal = inCache.analogReadCached(pin,pin2,inType);
// Mapping
if (inputMap && inputMap->type == aJson_Array)
{
@@ -1110,8 +1147,18 @@ readCache::readCache()
cached_data = 0;
}
uint16_t readCache::analogReadCached (uint8_t _pin)
uint16_t readCache::analogReadCached (uint8_t _pin, uint8_t trigPin, uint8_t _type )
{
#ifdef ULTRASONIC
if (_type == IN_ULTRASONIC)
{
if ((_pin==addr) && (IN_ULTRASONIC == type)) return cached_data;
type = IN_ULTRASONIC;
cached_data=ultrasonic.read();
//debugSerial<<F("LEN: ")<<cached_data<<endl;
return cached_data;
}
#endif
if ((_pin==addr) && (IN_ANALOG==type)) return cached_data;
addr = _pin;
type = IN_ANALOG;

View File

@@ -33,6 +33,7 @@ e-mail anklimov@gmail.com
#define IN_DHT22 4
#define IN_CCS811 5
#define IN_HDC1080 6
#define IN_ULTRASONIC 7
#define IN_COUNTER 8
#define IN_UPTIME 16
@@ -62,6 +63,7 @@ e-mail anklimov@gmail.com
#define CHECK_SENSOR 1
#define CHECK_INPUT 2
#define CHECK_INTERRUPT 3
#define CHECK_ULTRASONIC 4
#define T_LONG 1000
@@ -134,6 +136,7 @@ public:
aJsonObject *inputObj;
uint8_t inType;
uint8_t pin;
uint8_t pin2;
inStore *store;
Input(aJsonObject *obj, aJsonObject * configObj = NULL);
@@ -188,11 +191,12 @@ protected:
class readCache {
public:
readCache();
uint16_t analogReadCached (uint8_t pin);
uint16_t analogReadCached (uint8_t pin, uint8_t trigPin=0, uint8_t _type = IN_ANALOG);
uint8_t digitalReadCached(uint8_t pin);
#ifdef MCP23017
uint8_t I2CReadBit(uint8_t type, uint8_t addr, uint8_t pin);
#endif
void invalidateInputCache();
protected:
uint8_t addr;

View File

@@ -703,7 +703,7 @@ st.setSuffix(suffixCode);
int Par[3];
while (payload && k < 3)
Par[k++] = getInt((char **) &payload);
Par[k++] = getIntFromStr((char **) &payload);
i=i+k; //i=total # of parameters
switch(suffixCode)
{case S_HUE:
@@ -748,7 +748,7 @@ st.setSuffix(suffixCode);
short i = 0;
int Par[4];
while (payload && i < 4)
Par[i++] = getInt((char **) &payload);
Par[i++] = getIntFromStr((char **) &payload);
switch (i) //Number of params
{
@@ -770,7 +770,7 @@ st.setSuffix(suffixCode);
}
default: //some known command
{
int32_t intParam = getInt((char **) &payload);
int32_t intParam = getIntFromStr((char **) &payload);
if (intParam) st.Int(intParam);
return Ctrl(st,NULL, true, authorized);
}

View File

@@ -98,6 +98,7 @@ extern aJsonObject *items;
extern short thermoSetCurTemp(char *name, float t);
int txt2cmd (char * payload);
int txt2subItem(char *payload);
class Item
{

View File

@@ -101,15 +101,78 @@ todo - extend to values
*/
itemCmd::itemCmd(char * _cmd)
{
//debugSerial<<"ITEMCMD:" <<_cmd<<endl;
cmd.aslong=0;
param.aslong=0;
cmd.itemArgType=ST_VOID;
int i=0;
short i=0;
int Par[4];
while (_cmd[i]) {_cmd[i]=toupper(_cmd[i]);i++;};
int cmdN = txt2cmd(_cmd);
if (cmdN == CMD_UNKNOWN) return;
cmd.cmdCode=cmdN;
if (cmdN>=0) cmd.cmdCode = cmdN;
bool hsvflag=false;
switch (cmd.cmdCode) {
case CMD_HSV:
hsvflag=true;
case CMD_RGB:
cmd.cmdCode=CMD_VOID;
//Parsing integers from payload
i = 0;
while (_cmd && i < 4)
Par[i++] = getIntFromStr((char **) &_cmd);
if (hsvflag)
{
setSuffix(S_HSV);
cmd.itemArgType=ST_HSV255;
switch (i) //Number of params
{
case 4:
setColorTemp(Par[3]);
case 3:
param.v=Par[2];
case 2:
setH(Par[0]);
setS(Par[1]);
}
}
else
{
setSuffix(S_RGB);
switch (i) //Number of params
{
case 3: RGB(Par[0],Par[1],Par[2]);
break;
case 4: RGBW(Par[0],Par[1],Par[2],Par[3]);
default:;
}
}
break;
// case CMD_UNKNOWN: //Not known command
// case CMD_JSON: //JSON input (not implemented yet
// cmd.cmdCode=CMD_VOID;
// break;
default: //some known command
//case CMD_VOID:
//case CMD_UP:
//case CMD_DN:
{
itemCmd num =getNumber((char **) &_cmd);
cmd.itemArgType=num.getArgType();
param.aslong=num.param.aslong;
if (cmd.cmdCode) setSuffix(S_CMD);
}
} //switch
//debugOut();
}
itemCmd itemCmd::setChanType(short chanType)

View File

@@ -148,6 +148,7 @@ volatile unsigned long timerCount=0;
volatile int16_t timerNumber=-1;
volatile int8_t timerHandlerBusy=0;
volatile uint32_t cryptoSalt=0;
volatile uint32_t ultrasonicInputCheck=0;
//uint32_t timerCtr=0;
aJsonObject *pollingItem = NULL;
@@ -778,15 +779,31 @@ lan_status lanLoop() {
lanStatus=READ_RE_CONFIG;
break;
case AWAITING_CONFIG:
if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_REINIT_NOT_CONFIGURED))
lanStatus=DO_REINIT;
break;
case READ_RE_CONFIG: // Restore config from FLASH, re-init LAN
if (loadConfigFromEEPROM()) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
else
switch (loadConfigFromEEPROM())
{
case 1: lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
break;
case -1: //Temporary busy
if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_RELOAD))
{
errorSerial<<F("30s EEPROM is not reloaded. Reboot");
softRebootFunc();
}
break;
case 0:
lanStatus = AWAITING_CONFIG;
timerLanCheckTime = millis();
break;
}
break;
case DO_GET:
if (mqttClient.connected()) mqttClient.disconnect();
@@ -1558,7 +1575,7 @@ lanStatus=DO_READ_RE_CONFIG;
int loadConfigFromEEPROM()
{
if (configLocked) return 0;
if (configLocked) return -1;
configLocked++;
infoSerial<<F("Loading Config from EEPROM")<<endl;
@@ -2957,13 +2974,21 @@ void inputLoop(short cause) {
inputLoopBusy++;
configLocked++;
bool needCheckUltrasonic = false;
//if (millis() > timerInputCheck)
if (isTimeOver(timerInputCheck,millis(),INTERVAL_CHECK_INPUT))
{
if ((cause != CHECK_INTERRUPT) && isTimeOver(ultrasonicInputCheck,millis(),INTERVAL_CHECK_ULTRASONIC)) needCheckUltrasonic=true;
aJsonObject *input = inputs->child;
while (input) {
if (input->type == aJson_Object) {
Input in(input);
in.Poll(cause);
if (needCheckUltrasonic) in.Poll(CHECK_ULTRASONIC);
// Check for nested inputs
aJsonObject * inputArray = aJson.getObjectItem(input, "act");
if (inputArray && (inputArray->type == aJson_Array))
@@ -2974,6 +2999,7 @@ configLocked++;
{
Input in(inputObj,input);
in.Poll(cause);
if (needCheckUltrasonic) in.Poll(CHECK_ULTRASONIC);
//yield();
inputObj = inputObj->next;
@@ -2982,14 +3008,16 @@ configLocked++;
}
else
{
Input in(input);
in.Poll(cause);
//Input in(input);
//in.Poll(cause);
//if (needCheckUltrasonic) in.Poll(CHECK_ULTRASONIC);
}
}
//yield();
input = input->next;
}
if (cause != CHECK_INTERRUPT) timerInputCheck = millis();// + INTERVAL_CHECK_INPUT;
if (cause != CHECK_INTERRUPT) timerInputCheck = millis();
if (needCheckUltrasonic) {ultrasonicInputCheck = millis(); needCheckUltrasonic=false;}
inCache.invalidateInputCache();
}
configLocked--;

View File

@@ -232,7 +232,8 @@ enum lan_status {
DO_NOTHING = -15,
DO_GET = -16,
GET = -17,
GET_IN_PROGRESS = 18
GET_IN_PROGRESS = 18,
AWAITING_CONFIG = 19
};
extern lan_status lanStatus;

View File

@@ -77,6 +77,7 @@
#define TIMEOUT_REINIT 5000UL
#define TIMEOUT_RELOAD 30000UL
#define TIMEOUT_RETAIN 8000UL
#define TIMEOUT_REINIT_NOT_CONFIGURED 120000UL
#define INTERVAL_1W 5000UL
#define PERIOD_THERMOSTAT_FAILED (600 * 1000UL)
@@ -120,6 +121,8 @@
#define INTERVAL_CHECK_INPUT 11
#endif
#define INTERVAL_CHECK_ULTRASONIC 100
#ifndef TIMER_CHECK_INPUT
#define TIMER_CHECK_INPUT 15
#endif

View File

@@ -22,7 +22,7 @@ virtual unsigned int seek(unsigned int _pos = 0) = 0;
virtual int open(String _filename, char mode) = 0;
virtual void close() = 0;
virtual uint16_t getContentType() {return contentType;};
virtual void putEOF() {if (textMode) write (EOFchar);};
virtual void putEOF() {if (textMode) {write (EOFchar);textMode=false;}};
};
#endif

View File

@@ -110,7 +110,7 @@ return !err;
// chan is pointer to pointer to string
// Function return first retrived integer and move pointer to position next after ','
long getInt(char **chan) {
long getIntFromStr(char **chan) {
if (chan && *chan && **chan)
{
//Skip non-numeric values

View File

@@ -53,7 +53,7 @@ void PrintBytes(uint8_t* addr, uint8_t count, bool newline);
void SetBytes(uint8_t* addr, uint8_t count, char * out);
bool SetAddr(char * in, uint8_t* addr);
uint8_t HEX2DEC(char i, bool* err);
long getInt(char ** chan);
long getIntFromStr(char **chan);
itemCmd getNumber(char ** chan);
unsigned long freeRam ();
void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base);