14 Commits

Author SHA1 Message Date
09831781aa bins 2024-01-28 16:27:01 +03:00
340d54be09 sync 2024-01-28 16:20:45 +03:00
bcae3c9d50 artnet hung, sensors loop, inputs, multivent 2024-01-28 16:19:45 +03:00
1654f05bbe lh21 bins 2024-01-28 15:12:35 +03:00
99466f6e9f bins & cross-compilation 2024-01-28 15:10:56 +03:00
05ea031977 PID out, less logs, GET cfg fix, mbus concurr wrte 2024-01-28 12:05:10 +03:00
5ec57f0414 GET cmd refactored to operate in safe time 2024-01-27 15:03:11 +03:00
7ab78ab2ae binaries 2023-11-23 17:05:50 +03:00
4d909dd449 DMX IN integration with items 2023-11-20 20:55:37 +03:00
Климов Андрей Николаевич
b3db766b1a post-refactoring fix (Mercury) 2023-11-20 14:58:56 +03:00
080cdd4e22 LOG cleaning 2023-11-20 13:50:14 +03:00
91d5acf619 pre-release bins 2023-11-20 01:23:58 +03:00
454b88fbbf DMX IN fix (rollback to 2021) 2023-11-20 01:13:25 +03:00
6e283e32db decrease Timer0 int priority 2023-11-19 13:47:48 +03:00
39 changed files with 55141 additions and 54538 deletions

View File

@@ -44,3 +44,6 @@
-D BEARSSL_SSL_BASIC
-D SPILED_DISABLE
-D PWM_DISABLE
# WAK for HDC1080 (pin D3 on wemos is IO0)
-D WAK_PIN=D3

View File

@@ -40,3 +40,4 @@
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
-D MERCURY_ENABLE
#-D IPMODBUS
-D CONFIG_CLEAN_PIN=2

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +1,3 @@
export PORT=cu.usbmodem141101
export PORT=cu.usbmodem142101
echo . | stty -f /dev/$PORT speed 1200
../tools/mac/tool-bossac/bossac -U false -p $PORT -i -w -v -b firmware.bin -R

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
#define CST_UNKNOWN 0
#define CST_FAILED 1
#define CST_INITIALIZED 2
#define CST_USER 3
class abstractCh {
public:

View File

@@ -47,6 +47,7 @@ volatile uint32_t checkTimestamp=0L;
#if defined(_dmxin)
volatile uint32_t D_State=0;
volatile unsigned long D_checkT=0;
uint8_t DMXINChannels=0;
#endif
#ifdef _artnet
@@ -61,6 +62,61 @@ extern aJsonObject *items;
extern aJsonObject *dmxArr;
itemCmd rgb2hsv(itemCmd in)
{
itemCmd out;
out.setArgType(ST_HSV255);
double min, max, delta;
double inr=in.param.r/255;
double ing=in.param.g/255;
double inb=in.param.b/255;
double inw=in.param.w/255;
min = inr < ing ? inr : ing;
min = min < inb ? min : inb;
max = inr > ing ? inr : ing;
max = max > inb ? max : inb;
max = max > inw ? max : inw;
out.param.v = max*255; // v
delta = max - min;
if (delta < 0.00001)
{
out.param.s = 0;
out.param.h = 0; // undefined, maybe nan?
return out;
}
if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash
out.param.s = (delta / max)*100; // s
} else {
// if max is 0, then r = g = b = 0
// s = 0, h is undefined
out.param.s = 0;
out.param.h = 0; // its now undefined
return out;
}
double outh;
if( inr >= max ) // > is bogus, just keeps compilor happy
outh = ( ing - inb ) / delta; // between yellow & magenta
else
if( ing >= max )
outh = 2.0 + ( inb - inr ) / delta; // between cyan & yellow
else
outh = 4.0 + ( inr - ing ) / delta; // between magenta & cyan
outh *= 60.0; // degrees
if( outh < 0.0 )
outh += 360.0;
out.param.h=outh;
return out;
}
int itemCtrl2(char* name,int r,int g, int b, int w)
{
if (!items) return 0;
@@ -68,7 +124,6 @@ int itemCtrl2(char* name,int r,int g, int b, int w)
if (itemArr && (itemArr->type==aJson_Array))
{
short itemtype = aJson.getArrayItem(itemArr,0)->valueint;
short itemaddr = aJson.getArrayItem(itemArr,1)->valueint;
switch (itemtype){
@@ -84,7 +139,6 @@ int itemCtrl2(char* name,int r,int g, int b, int w)
case CH_RGB: // RGB
{
DmxWrite(itemaddr, r);
DmxWrite(itemaddr+1, g);
DmxWrite(itemaddr+2, b);
@@ -96,7 +150,7 @@ int itemCtrl2(char* name,int r,int g, int b, int w)
if (groupArr && (groupArr->type==aJson_Array))
{ aJsonObject *i =groupArr->child;
while (i)
{ //Serial.println(i->valuestring);
{
if (i->type == aJson_String) itemCtrl2(i->valuestring,r,g,b,w);
i=i->next;}
}
@@ -119,9 +173,34 @@ void DMXImmediateUpdate(short tch,short r, short g, short b, short w) {
}
}
void DMXSemiImmediateUpdate(short tch,short trh, int val)
void DMXSemiImmediateUpdate(short tch,short r, short g, short b, short w)
{
//Here any code for passthrow between DMX IN and DMX OUT in idle state
if (dmxArr && (dmxArr->type==aJson_Array))
{
aJsonObject *DMXch = aJson.getArrayItem(dmxArr,tch);
char* itemname = NULL;
if (DMXch->type == aJson_String) itemname=DMXch->valuestring;
if (itemname)
{
Item it(itemname);
if (!r && !g && !b && !w) it.Ctrl(itemCmd().Cmd(CMD_OFF).setSuffix(S_CMD));
else
{
/*
CRGB rgb;
rgb.r = r;
rgb.g = g;
rgb.b = b;
CHSV hsv = rgb2hsv_approximate(rgb);
it.Ctrl(itemCmd().HSV255(hsv.h,hsv.s,hsv.v).setSuffix(S_SET)); */
it.Ctrl(itemCmd().RGBW(r,g,b,w).setSuffix(S_SET));
//it.Ctrl(rgb2hsv(itemCmd().RGBW(r,g,b,w)).setSuffix(S_SET));
it.Ctrl(itemCmd().Cmd(CMD_ON).setSuffix(S_CMD));
}
}
}
}
void DMXput(void)
@@ -132,6 +211,7 @@ for (short tch=0; tch<=3 ; tch++)
short base = tch*4;
DMXImmediateUpdate(tch,DMXin[base],DMXin[base+1],DMXin[base+2],DMXin[base+3]);
}
};
extern volatile uint8_t timerHandlerBusy;
@@ -140,81 +220,62 @@ extern volatile uint8_t timerHandlerBusy;
volatile int DMXinDoublecheck=0;
#endif
// INVOKED BY INTERRUPTS - MUST BE SAFE CODE
void DMXUpdate(void)
{
#if defined(_dmxin)
int t;
if(!DMXin) return;
#if defined(__SAM3X8E__)
if (dmxin.getRxLength()<16) return;
if (dmxin.getRxLength()<DMXINChannels) return;
#endif
for (short tch=0; tch<=3 ; tch++)
uint8_t RGBWChannels=DMXINChannels >> 2;
for (short tch=0; tch<RGBWChannels ; tch++)
{
short base = tch*4;
bool updated = 0;
bool confirmed = 0;
bool updated = false;
int t;
for (short trh=0; trh<4 ; trh++)
if (((t=dmxin.read(base+trh+1)) != DMXin[base+trh]))
if ((t=dmxin.read(base+trh+1)) != DMXin[base+trh])
{
D_State |= (1<<tch);
updated=1;
if (DMXinDoublecheck>2)
{
D_State |= (1<<tch);
DMXin[base+trh]=t;
confirmed = 1;
}
DMXin[base+trh]=t;
}
if (updated) DMXinDoublecheck++; else DMXinDoublecheck=0;
if (confirmed)
if (updated)
{
DMXImmediateUpdate(tch,DMXin[base],DMXin[base+1],DMXin[base+2],DMXin[base+3]);
//for (int i=1; i<17; i++) {debugSerial.print(dmxin.read(i));debugSerial.print("-");};debugSerial.print("|");
D_checkT=millisNZ();
}
}
//Serial.print(D_State,BIN);Serial.println();
#endif
}
void DMXCheck(void)
// INVOKED in safe loop
void DMXCheck(void)
{
// CHSV hsv;
// CRGB rgb;
DMXOUT_propagate();
#if defined(_dmxin)
short t,tch;
//Here code for semi-immediate update
for (t=1,tch=0; t<=8 ; t<<=1,tch++)
if (D_State & t)
{
// Serial.print(D_State,BIN);Serial.print(":");
D_State &= ~t;
for (short trh=0; trh<4 ; trh++)
DMXSemiImmediateUpdate(tch,trh,DMXin[tch*4+trh]);
}
//if ((millis()<D_checkT) || (D_checkT==0)) return;
if ( (!D_checkT) || (!isTimeOver(D_checkT,millis(),D_CHECKT))) return;
if ( (!D_checkT) || (!isTimeOver(D_checkT,millis(),D_CHECKT))) return;
D_checkT=0;
uint8_t RGBWChannels=DMXINChannels >> 2;
for (short rgbwChan=0; rgbwChan < RGBWChannels; rgbwChan++)
{
short base = rgbwChan*4;
short bitMask = 1 << rgbwChan;
if (D_State & bitMask)
{
D_State &= ~bitMask;
DMXSemiImmediateUpdate(rgbwChan,DMXin[base],DMXin[base+1],DMXin[base+2],DMXin[base+3]);
break;
}
}
// Here code for network update
//int ch = 0;
DMXput();
#ifdef _dmxout
for (int i=1; i<17; i++) {debugSerial.print(dmxin.read(i));debugSerial.print(";");}
debugSerial.println();
#endif
//#ifdef _dmxout
//for (int i=1; i<17; i++) {debugSerial.print(dmxin.read(i));debugSerial.print(";");}
//debugSerial.println();
//#endif
#endif
}
@@ -238,7 +299,9 @@ void DMXinSetup(int channels)
//DmxSimple.maxChannel(channels);
#if defined(_dmxin)
if (channels>(32*4)) channels = 32*4;
DMXin = new uint8_t [channels];
DMXINChannels=channels;
#if defined(ARDUINO_ARCH_AVR)
DMXSerial.init(DMXReceiver,0,channels);
if (DMXSerial.getBuffer()) {debugSerial.print(F("Init in ch:"));debugSerial.println(channels);} else debugSerial.println(F("DMXin Buffer alloc err"));

View File

@@ -146,7 +146,8 @@ if (input->type == aJson_Object) {
else
{
Input in(input);
in.Poll(CHECK_INPUT);
in.store->aslong = 0;
//in.Poll(CHECK_INPUT);
}
}
}
@@ -524,7 +525,7 @@ bool Input::changeState(uint8_t newState, short cause)
if (!inputObj || !store) return false;
if (newState == IS_REQSTATE)
if (store->delayedState && cause != CHECK_INTERRUPT)
if (store->delayedState && (cause != CHECK_INTERRUPT))
{
// Requested delayed change State and safe moment
newState=store->reqState; //Retrieve requested state

View File

@@ -105,7 +105,7 @@ extern aJsonObject *inputs;
typedef union {
long int aslong;
uint32_t aslong;
uint32_t timestamp;
// Analog input structure
struct {

View File

@@ -327,7 +327,7 @@ void Item::setCmd(uint8_t cmdValue) {
{
itemCmd->type = aJson_Int;
itemCmd->valueint = cmdValue & CMD_MASK | itemCmd->valueint & (FLAG_MASK); // Preserve special bits
debugSerial<<F("SetCmd:")<<cmdValue<<endl;
//debugSerial<<F("SetCmd:")<<cmdValue<<endl;
}
}

View File

@@ -1171,8 +1171,8 @@ bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
item->setVal(param.asInt32);
item->setSubtype(cmd.itemArgType);
}
debugSerial<<F("Saved:");
debugOut();
//debugSerial<<F("Saved:");
//debugOut();
return true;
}
return false;

View File

@@ -170,6 +170,13 @@ bool cleanConf(bool wait)
{
if (!root) return true;
bool clean = true;
if (configLocked)
{
errorSerial<<F("Can not clean - locked")<<endl;
return false;
}
/*
No more unsafe operations
if (wait)
{
debugSerial<<F("Unlocking config ...")<<endl;
@@ -196,6 +203,7 @@ if (configLocked)
clean = false;
}
} //wait
*/
debugSerial<<F("Stopping channels ...")<<endl;
timerHandlerBusy++;
@@ -400,7 +408,7 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
int fr = freeRam();
debugSerial<<F("\n")<<fr<<F(":[")<<topic<<F("] ");
debugSerial<<fr<<F(":[")<<topic<<F("] ");
if (fr < 250+MQTT_TOPIC_LENGTH) {
errorSerial<<F("OutOfMemory!")<<endl;
@@ -619,12 +627,14 @@ lan_status lanLoop() {
if (!initializedListeners)
{
setupSyslog();
debugSerial<<F("Setup OTA")<<endl;
setupOTA();
#ifdef _artnet
if (artnet) artnet->begin();
#endif
#ifdef IPMODBUS
debugSerial<<F("Setup IPModbus")<<endl;
setupIpmodbus();
#endif
initializedListeners = true;
@@ -753,7 +763,7 @@ lan_status lanLoop() {
lanStatus=READ_RE_CONFIG;
break;
case READ_RE_CONFIG: // Restore config from FLASH, re-init LAN
case READ_RE_CONFIG: // Restore config from FLASH, re-init LAN
if (loadConfigFromEEPROM()) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
else
if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_RELOAD))
@@ -763,8 +773,32 @@ lan_status lanLoop() {
}
break;
case DO_GET:
if (mqttClient.connected()) mqttClient.disconnect();
timerLanCheckTime = millis();// + 5000;
lanStatus = GET;
break;
case GET:
statusLED.set(ledRED|ledGREEN|((configLoaded)?ledBLINK:0));
if (configLocked) return GET;
lanStatus = GET_IN_PROGRESS;
if (loadConfigFromHttp()==200) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
else if (configLoaded) {
infoSerial<<F("Continue with previously loaded config")<<endl;
lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
}
else if (Ethernet.localIP()) lanStatus = DO_READ_RE_CONFIG;
else lanStatus = DO_REINIT; //Load from NVRAM
break;
case DO_NOTHING:
case OPERATION_NO_MQTT:
case GET_IN_PROGRESS:
;
}
@@ -1680,7 +1714,10 @@ if (arg_cnt>1)
if (lanStatus>=HAVE_IP_ADDRESS)
{
lanStatus = DO_GET;
return 200;
/*
let Re-Get will be only in safe time
int retCode=loadConfigFromHttp();
if (retCode==200)
{
@@ -1699,6 +1736,7 @@ int retCode=loadConfigFromHttp();
if (configLoaded) lanStatus =IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
else lanStatus = DO_READ_RE_CONFIG;
return retCode;
*/
}
errorSerial<<F("No IP adress")<<endl;
return 500;
@@ -1772,7 +1810,12 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
infoSerial<<F("got Config\n"); delay(500);
aJsonFileStream as = aJsonFileStream(configStream);
noInterrupts();
cleanConf(true);
if (!cleanConf(true))
{
errorSerial<<F("Get aborted")<<endl;
hclient.closeStream(configStream);
return 500;
}
root = aJson.parse(&as);
interrupts();
hclient.closeStream(configStream); // this is very important -- be sure to close the STREAM
@@ -1844,7 +1887,13 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
if (responseStatusCode == 200) {
aJsonStream socketStream = aJsonStream(&htclient);
debugSerial<<F("Free:")<<freeRam()<<endl;
cleanConf(true);
if (!cleanConf(true))
{
errorSerial<<F("Get aborted")<<endl;
htclient.stop();
return 500;
}
debugSerial<<F("Configuration cleaned")<<endl;
debugSerial<<F("Free:")<<freeRam()<<endl;
//root = aJson.parse((char *) response.c_str());
@@ -1917,7 +1966,12 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
sysConf.setETAG(httpClient.header("ETag"));
//String response = httpClient.getString();
//debugSerial<<response;
cleanConf(true);
if (!cleanConf(true))
{
errorSerial<<F("Get aborted")<<endl;
httpClient.end();
return 500;
}
//root = aJson.parse((char *) response.c_str());
root = aJson.parse(&socketStream);
@@ -2003,6 +2057,10 @@ int16_t attachTimer(double microseconds, timerCallback callback, const char* Tim
dueTimerInterrupt.attachInterruptInterval(microseconds, callback);
timerNumber = dueTimerInterrupt.getTimerNumber();
debugSerial<<TimerName<<F(" attached to Timer(")<<timerNumber<<F(")")<<endl;
//DueTimer.Timers[timerNumber].irq
NVIC_SetPriority(TC0_IRQn,2);
debugSerial << "USART0 prio:" << NVIC_GetPriority (USART0_IRQn)<< " TC0 prio:" << NVIC_GetPriority (TC0_IRQn)<<endl;
return timerNumber;
}
#endif
@@ -2493,6 +2551,11 @@ infoSerial<<F("\nNOSERIAL");
infoSerial<<F("\n(+)ELEVATOR");
#endif
#ifdef MERCURY_ENABLE
infoSerial<<F("\n(+)MERCURY");
#else
infoSerial<<F("\n(-)MERCURY");
#endif
//#ifdef IPMODBUS
//infoSerial<<F("\n(+)IPMODBUS");
//#endif
@@ -2625,12 +2688,12 @@ void loop_main() {
#if defined(OTA)
yield();
ArduinoOTA.poll();
if (initializedListeners) ArduinoOTA.poll();
#endif
#ifdef _artnet
yield();
if (artnet) artnet->read(); ///hung if network not initialized
if (artnet && initializedListeners) artnet->read(); ///hung if network not initialized
#endif
#ifdef MDNS_ENABLE
#ifndef WIFI_ENABLE
@@ -2679,7 +2742,7 @@ if (initializedListeners) ipmodbusLoop();
void owIdle(void) {
// timerCtr++;
#ifdef _artnet
if (artnet && (lanStatus>=HAVE_IP_ADDRESS)) artnet->read();
if (artnet && initializedListeners && (lanStatus>=HAVE_IP_ADDRESS)) artnet->read();
#endif
wdt_res();
@@ -2738,7 +2801,7 @@ void modbusIdle(void) {
yield();
mqttClient.loop();
#ifdef _artnet
if (artnet) artnet->read();
if (artnet && initializedListeners) artnet->read();
#endif
#if defined(OTA)
yield();
@@ -2810,9 +2873,10 @@ inputLoopBusy--;
void inputSensorsLoop() {
if (!inputs || inputLoopBusy) return;
//inputLoopBusy++;
configLocked++;
//configLocked++;
if (isTimeOver(timerSensorCheck,millis(),INTERVAL_CHECK_SENSOR))
{
configLocked++;
aJsonObject *input = inputs->child;
while (input) {
if ((input->type == aJson_Object)) {
@@ -2824,14 +2888,16 @@ configLocked++;
input = input->next;
}
timerSensorCheck = millis();
configLocked--;
}
configLocked--;
//configLocked--;
//inputLoopBusy--;
}
void inputSetup(void) {
infoSerial<<F("Initializing Inputs")<<endl;
if (!inputs) return;
configLocked++;
aJsonObject *input = inputs->child;

View File

@@ -218,7 +218,10 @@ enum lan_status {
RECONNECT = 13,
READ_RE_CONFIG = 14,
DO_READ_RE_CONFIG = 15,
DO_NOTHING = -15
DO_NOTHING = -15,
DO_GET = -16,
GET = -17,
GET_IN_PROGRESS = 18
};
extern lan_status lanStatus;

View File

@@ -22,14 +22,14 @@ static bool CCS811ready = false;
int in_ccs811::Setup()
{
if (CCS811ready) {errorSerial<<F("ccs811 is already initialized")<<endl; return 0;}
if (CCS811ready) {errorSerial<<F("CCS811: Already initialized")<<endl; return 0;}
#ifdef WAK_PIN
pinMode(WAK_PIN,OUTPUT);
digitalWrite(WAK_PIN,LOW);
#endif
infoSerial.println("CCS811 Init");
infoSerial.println(F("CCS811: Init"));
#if defined (TWI_SCL) && defined (TWI_SDA)
Wire.begin(TWI_SDA,TWI_SCL); //Inialize I2C Harware
@@ -37,7 +37,9 @@ Wire.begin(TWI_SDA,TWI_SCL); //Inialize I2C Harware
Wire.begin(); //Inialize I2C Harware
#endif
Wire.setClock(4000);
#ifdef I2C_CLOCK
Wire.setClock(I2C_CLOCK);
#endif
//It is recommended to check return status on .begin(), but it is not
//required.
@@ -46,8 +48,7 @@ Wire.setClock(4000);
if (returnCode != CCS811Core::SENSOR_SUCCESS)
//if (returnCode != CCS811Core::CCS811_Stat_SUCCESS)
{
errorSerial.print("CCS811 Init error ");
//debugSerial.println(ccs811.statusString(returnCode));
errorSerial.print(F("CCS811: Init error "));
printDriverError(returnCode);
return 0;
}
@@ -68,16 +69,16 @@ return 1;
int in_hdc1080::Setup()
{
//i2cReset();
if (HDC1080ready) {debugSerial<<F("hdc1080 is already initialized")<<endl; return 0;}
debugSerial.println("HDC1080 Init ");
if (HDC1080ready) {debugSerial<<F("HDC1080: Already initialized")<<endl; return 0;}
debugSerial.print(F("HDC1080: Init. "));
Wire.begin(); //Inialize I2C Harware
// Default settings:
// - Heater off
// - 14 bit Temperature and Humidity Measurement Resolutions
hdc1080.begin(0x40);
debugSerial.print("Manufacturer ID=0x");
debugSerial.println(hdc1080.readManufacturerId(), HEX); // 0x5449 ID of Texas Instruments
debugSerial.print("Device ID=0x");
debugSerial.print(F("Manufacturer ID=0x"));
debugSerial.print(hdc1080.readManufacturerId(), HEX); // 0x5449 ID of Texas Instruments
debugSerial.print(F(" Device ID=0x"));
debugSerial.println(hdc1080.readDeviceId(), HEX); // 0x1050 ID of the device
printSerialNumber();
HDC1080ready = true;
@@ -91,14 +92,14 @@ int in_hdc1080::Poll(short cause)
float h,t;
int reg;
if (cause!=POLLING_SLOW) return 0;
if (!HDC1080ready) {debugSerial<<F("HDC1080 not initialized")<<endl; return 0;}
debugSerial.print("HDC Status=");
debugSerial.println(reg=hdc1080.readRegister().rawData,HEX);
if (!HDC1080ready) {errorSerial<<F("HDC1080: Not initialized")<<endl; return 0;}
debugSerial.print(F("HDC1080: Status="));
debugSerial.print(reg=hdc1080.readRegister().rawData,HEX);
if (reg!=0xff)
{
debugSerial.print(" T=");
debugSerial.print(t=hdc1080.readTemperature());
debugSerial.print("C, RH=");
debugSerial.print(F("C, RH="));
debugSerial.print(h=hdc1080.readHumidity());
debugSerial.println("%");
@@ -126,6 +127,7 @@ if (reg!=0xff)
}
else //ESP I2C glitch
{
debugSerial.println();
i2cReset();
}
return INTERVAL_SLOW_POLLING;
@@ -147,14 +149,14 @@ int in_ccs811::Poll(short cause)
CCS811Core::status returnCode = ccs811.readAlgorithmResults();
printDriverError(returnCode);
float co2,tvoc;
debugSerial.print(" CO2[");
debugSerial.print(F(" CO2["));
//Returns calculated CO2 reading
debugSerial.print(co2 = ccs811.getCO2());
debugSerial.print("] tVOC[");
debugSerial.print(F("] tVOC["));
//Returns calculated TVOC reading
debugSerial.print(tvoc = ccs811.getTVOC());
debugSerial.print("] baseline[");
debugSerial.print(F("] baseline["));
debugSerial.print(ccs811Baseline = ccs811.getBaseline());
#ifdef M5STACK
@@ -192,11 +194,11 @@ int in_ccs811::Poll(short cause)
}
void in_hdc1080::printSerialNumber() {
debugSerial.print("Device Serial Number=");
infoSerial.print(F("Device Serial Number="));
HDC1080_SerialNumber sernum = hdc1080.readSerialNumber();
char format[16];
sprintf(format, "%02X-%04X-%04X", sernum.serialFirst, sernum.serialMid, sernum.serialLast);
debugSerial.println(format);
infoSerial.println(format);
}
//printDriverError decodes the CCS811Core::status type and prints the
@@ -206,25 +208,26 @@ debugSerial.println(format);
//to this function to see what the output was.
void in_ccs811::printDriverError( CCS811Core::status errorCode )
{
debugSerial.print(F("CCS811: "));
switch ( errorCode )
{
case CCS811Core::SENSOR_SUCCESS:
debugSerial.print("SUCCESS");
debugSerial.print(F("SUCCESS"));
break;
case CCS811Core::SENSOR_ID_ERROR:
debugSerial.print("ID_ERROR");
debugSerial.print(F("ID_ERROR"));
break;
case CCS811Core::SENSOR_I2C_ERROR:
debugSerial.print("I2C_ERROR");
debugSerial.print(F("I2C_ERROR"));
break;
case CCS811Core::SENSOR_INTERNAL_ERROR:
debugSerial.print("INTERNAL_ERROR");
debugSerial.print(F("INTERNAL_ERROR"));
break;
case CCS811Core::SENSOR_GENERIC_ERROR:
debugSerial.print("GENERIC_ERROR");
debugSerial.print(F("GENERIC_ERROR"));
break;
default:
debugSerial.print("Unspecified error.");
debugSerial.print(F("Unspecified error."));
}
}
@@ -236,18 +239,18 @@ void in_ccs811::printSensorError()
if ( error == 0xFF ) //comm error
{
debugSerial.println("Failed to get ERROR_ID register.");
errorSerial.println(F("CCS811: Failed to get ERROR_ID register."));
}
else
{
//debugSerial.print("");
if (error & 1 << 5) debugSerial.print("Error: HeaterSupply");
if (error & 1 << 4) debugSerial.print("Error: HeaterFault");
if (error & 1 << 3) debugSerial.print("Error: MaxResistance");
if (error & 1 << 2) debugSerial.print("Error: MeasModeInvalid");
if (error & 1 << 1) debugSerial.print("Error: ReadRegInvalid");
if (error & 1 << 0) debugSerial.print("Error: MsgInvalid");
debugSerial.println();
if (error) errorSerial.print(F("CCS811: Error "));
if (error & 1 << 5) errorSerial.print(F("HeaterSupply"));
if (error & 1 << 4) errorSerial.print(F("HeaterFault"));
if (error & 1 << 3) errorSerial.print(F("MaxResistance"));
if (error & 1 << 2) errorSerial.print(F("MeasModeInvalid"));
if (error & 1 << 1) errorSerial.print(F("ReadRegInvalid"));
if (error & 1 << 0) errorSerial.print(F("MsgInvalid"));
if (error) errorSerial.println();
}
}
#endif

View File

@@ -7,18 +7,22 @@
#include "ClosedCube_HDC1080.h"
#include "SparkFunCCS811.h" //Click here to get the library: http://librarymanager/All#SparkFun_CCS811
//#ifndef I2C_CLOCK
//#define I2C_CLOCK 4000
//#endif
//#define CCS811_ADDR 0x5B //Default I2C Address
#define CCS811_ADDR 0x5A //Alternate I2C Address
#if defined (ARDUINO_ARCH_ESP8266)
#if not defined (TWI_SCL) && defined (D1)
#define TWI_SCL D1
#endif
// #if not defined (TWI_SCL) && defined (D1)
// #define TWI_SCL D1
// #endif
#if not defined (WAK_PIN) && defined (D3)
#define WAK_PIN D3
#endif
// #if not defined (WAK_PIN) && defined (D3)
// #define WAK_PIN D3
// #endif
#if defined (TWI_SCL)
#define SCL_LOW() (GPES = (1 << TWI_SCL))
@@ -28,16 +32,10 @@
#endif
/*
#if defined (__SAM3X8E__)
#define SCL_LOW() digitalWrite(21,LOW)
#define SCL_HIGH() digitalWrite(21,HIGH)
#define SCL_RESET
#endif
*/
#if defined (ARDUINO_ARCH_ESP32)
#undef WAK_PIN
//#undef WAK_PIN
#undef SCL_RESET
//#ifndef WAK_PIN
//#define WAK_PIN 17
@@ -45,9 +43,9 @@
#endif
#if defined(ARDUINO_ARCH_AVR)
#ifndef WAK_PIN
#define WAK_PIN 3 // for LightHub UEXT SCS Pin
#endif
//#ifndef WAK_PIN
//#define WAK_PIN 3 // for LightHub UEXT SCS Pin
//#endif
#endif

View File

@@ -21,8 +21,8 @@ extern bool disableCMD;
#define AC_FAILED CST_FAILED
#define AC_UNKNOWN CST_UNKNOWN
#define AC_IDLE CST_INITIALIZED
#define AC_SENDING 3
#define AC_IDLE CST_INITIALIZED
#define AC_SENDING CST_USER
//byte inCheck = 0;
byte qstn[] = {255,255,10,0,0,0,0,0,1,1,77,1,90}; // Команда опроса
@@ -468,6 +468,7 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute, bool authorized)
case S_CMD:
// s_mode[0]='\0';
store->inCheck=0;
switch (cmd.getCmd())
{
case CMD_ON:
@@ -549,9 +550,42 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute, bool authorized)
store->data[B_FAN_SPD] = 2;
strcpy_P(s_speed,LOW_P);
break;
case CMD_OFF:
store->inCheck=0;
store->data[B_POWER] = store->power;
store->data[B_POWER] &= ~1;
SendData(off, sizeof(off)/sizeof(byte));
return 1;
default:
//if (n) data[B_FAN_SPD] = Parameters[0];
store->data[B_FAN_SPD] = cmd.getInt();
{
uint8_t speed = 0;
if (cmd.getInt()) speed = map(cmd.getInt(),1,255,1,3);
store->inCheck=0;
switch (speed) {
case 0:
store->data[B_POWER] = store->power;
store->data[B_POWER] &= ~1;
SendData(off, sizeof(off)/sizeof(byte));
return 1;
case 1:
store->data[B_FAN_SPD] = 2;
strcpy_P(s_speed,LOW_P);
store->data[B_POWER] = store->power;
store->data[B_POWER] |= 1;
break;
case 2:
store->data[B_FAN_SPD] = 1;
strcpy_P(s_speed,MED_P);
store->data[B_POWER] = store->power;
store->data[B_POWER] |= 1;
break;
case 3:
store->data[B_FAN_SPD] = 0;
strcpy_P(s_speed,HIGH_P);
store->data[B_POWER] = store->power;
store->data[B_POWER] |= 1;
}
}
//TODO - mapping digits to speed
}
publishTopic(item->itemArr->name,s_speed,"/fan");

View File

@@ -97,6 +97,7 @@ debugSerial.println("Mercury: De-Init");
disconnectMercury();
delete store;
item->setPersistent(NULL);
setStatus(CST_UNKNOWN);
store = NULL;
return 1;
}

View File

@@ -20,16 +20,16 @@ public:
#define MB_SEND_ERROR 4
#define MB_SEND_ATTEMPTS 3
#define M_CONNECTING 10
#define M_CONNECTED 11
#define M_POLLING1 12
#define M_POLLING2 13
#define M_POLLING3 14
#define M_POLLING4 15
#define M_POLLING5 16
#define M_POLLING6 17
#define M_POLLING7 18
#define M_POLLING8 19
#define M_CONNECTING CST_USER+0
#define M_CONNECTED CST_USER+1
#define M_POLLING1 CST_USER+2
#define M_POLLING2 CST_USER+3
#define M_POLLING3 CST_USER+4
#define M_POLLING4 CST_USER+5
#define M_POLLING5 CST_USER+6
#define M_POLLING6 CST_USER+7
#define M_POLLING7 CST_USER+8
#define M_POLLING8 CST_USER+9
#define RET_SUCCESS 0
#define RET_INVALID_PARAM 1

View File

@@ -341,7 +341,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
switch (defMappingObj->type)
{
case aJson_Int: //register/coil/.. number
debugSerial<<F("Searching reg#")<<defMappingObj->valueint<<endl;
traceSerial<<F("Searching reg#")<<defMappingObj->valueint<<endl;
if ((defMappingObj->valueint>= registerFrom) && (defMappingObj->valueint<=registerTo))
{
mappedParam = findRegister(defMappingObj->valueint,defMappingObj->valueint-registerFrom,regType,registerFrom,registerTo,false,&submitRecurrentOut);
@@ -351,7 +351,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
break;
case aJson_String: // parameter name
debugSerial<<F("Searching reg: ")<<defMappingObj->valuestring<<endl;
traceSerial<<F("Searching reg: ")<<defMappingObj->valuestring<<endl;
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
{
//Searching item param for nested mapping
@@ -364,7 +364,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
aJsonObject *lastMeasured = aJson.getObjectItem(itemParObj,"@S");
if (lastMeasured && lastMeasured->type ==aJson_Int)
{
debugSerial<<F("LastKnown value: ")<<lastMeasured->valueint<<endl;
traceSerial<<F("LastKnown value: ")<<lastMeasured->valueint<<endl;
//Searching template param for nested mapping
aJsonObject * templateParObj = aJson.getObjectItem(store->parameters,defMappingObj->valuestring);
if (templateParObj)
@@ -550,7 +550,7 @@ return itemCmd();
int registerTo=aJson.getArrayItem(reg, 1)->valueint;
if (readModbus(registerFrom,regType,registerTo-registerFrom+1))
{ debugSerial<<endl;
{ traceSerial<<endl;
for(int i=registerFrom;i<=registerTo;i++)
{
findRegister(i,i-registerFrom,regType,registerFrom,registerTo);
@@ -633,7 +633,7 @@ int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
break;
}
mbusSlenceTimer = millisNZ();
debugSerial<<F("Res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
debugSerial<<F("MBUS res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
return ( res == 0);
}
@@ -667,8 +667,18 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
lineInitialized=true;
initLine();
}
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<" ";
switch (sendModbus(execObj->name,outValue->valueint,outValue->subtype))
int sendRes;
int savedValue;
do
{
savedValue = outValue->valueint;
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<" ";
sendRes = sendModbus(execObj->name,outValue->valueint,outValue->subtype);
}
while (savedValue != outValue->valueint); //repeat sending if target value changed while we're waited for mbus responce
switch (sendRes)
{
case 1: //success
execObj->subtype&=~ MB_NEED_SEND;

View File

@@ -44,19 +44,19 @@ if (gatesObj /*&& aJson.getArraySize(item->itemArg)>=2*/)
}
i=i->next;
}
debugSerial << F ("MultiVent init")<< endl;
debugSerial << F ("VENT: init")<< endl;
setStatus(CST_INITIALIZED);
return 1;
}
debugSerial << F ("MultiVent config failed")<< endl;
debugSerial << F ("VENT: config failed")<< endl;
return 0;
}
int out_Multivent::Stop()
{
debugSerial << F ("Multivent De-Init") << endl;
debugSerial << F ("VENT: De-Init") << endl;
setStatus(CST_UNKNOWN);
return 1;
}
@@ -151,7 +151,7 @@ while (i)
if (cmdObj->valueint == CMD_OFF || cmdObj->valueint == -1)
{
debugSerial<<"Turning ON"<<endl;
debugSerial<<"VENT: Turning ON"<<endl;
cmdObj->valueint = CMD_ON;
cmd.Cmd(CMD_ON);
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_ON),FLAG_COMMAND,i->name);
@@ -162,7 +162,7 @@ while (i)
else
{
if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != -1)
{ debugSerial<<"Turning OFF"<<endl;
{ debugSerial<<"VENT: Turning OFF"<<endl;
cmdObj->valueint = CMD_OFF;
cmd.Cmd(CMD_OFF);
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF),FLAG_COMMAND,i->name);
@@ -204,10 +204,13 @@ while (i)
if (!totalV) return 0;
int fanV=activeV/totalV;
debugSerial << F("Total V:")<<totalV<<F(" active V:")<<activeV/255<< F(" fan%:")<<fanV<< F(" Max request:")<<maxRequestedV/255 <<F(" from ")<<maxV<<F(" m3")<< endl;
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd((fanV)?CMD_ON:CMD_OFF));
debugSerial << F("VENT: Total V:")<<totalV<<F(" active V:")<<activeV/255<< F(" fan%:")<<fanV<< F(" Max req:")<<maxRequestedV/255 <<F(" from ")<<maxV<<F(" m3")<< endl;
//executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd((fanV)?CMD_ON:CMD_OFF));
if (fanV)
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd(CMD_ON));
else
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV));
//Move gates only if fan is actually on
if (!fanV) return 1;
@@ -229,7 +232,7 @@ while (i)
{
int requestedV=V*setObj->valueint;
out = (( long)requestedV*255L)/(( long)V)*( long)maxV/( long)maxRequestedV;
debugSerial<<i->name<<(" Req:")<<requestedV/255<<F(" Out:")<<out<<endl;
debugSerial<<F("VENT: ")<<i->name<<F(" Req:")<<requestedV/255<<F(" Out:")<<out<<endl;
}

View File

@@ -334,32 +334,38 @@ case S_CTRL:
switch (command)
{
case CMD_OFF:
//value.Percents255(0);
if (isNotRetainingStatus()) executeCommand(oCmd,-1,itemCmd().Cmd(CMD_DISABLE)); // Not actually disable, just inform depended systems, that no autoreg now (for pannels indication)
executeCommand(oCmd,-1,value);
item->SendStatus(FLAG_FLAGS);
return 1;
case CMD_ON:
case CMD_HEAT:
case CMD_COOL:
case CMD_AUTO:
case CMD_FAN:
case CMD_DRY:
executeCommand(oCmd,-1,value);
executeCommand(oCmd,-1,itemCmd().Cmd((item->getFlag(FLAG_DISABLED))?CMD_DISABLE:CMD_ENABLE));
executeCommand(oCmd,-1,value);
item->SendStatus(FLAG_FLAGS);
return 1;
case CMD_ENABLE:
//item->setCmd(CMD_ENABLE);
//item->SendStatus(FLAG_COMMAND);
if (isNotRetainingStatus())
{
item->setCmd(CMD_ON);
item->SendStatus(FLAG_COMMAND);
}
item->setFlag(FLAG_ACTION_NEEDED);
executeCommand(oCmd,-1,value);
if (isActive()) executeCommand(oCmd,-1,itemCmd().Cmd((CMD_ON)));
store->prevOut=-2.0;
return 1;
case CMD_DISABLE:
//item->setCmd(CMD_DISABLE);
//item->SendStatus(FLAG_COMMAND);
executeCommand(oCmd,-1,value);
if (!isActive()) executeCommand(oCmd,-1,itemCmd().Cmd((CMD_OFF)));
return 1;
/*
case CMD_OFF:

View File

@@ -26,10 +26,9 @@ e-mail anklimov@gmail.com
#include "options.h"
#include "main.h"
#include "aJSON.h"
//#include "twi.h"
extern aJsonObject *owArr;
extern uint32_t timerCtr;
//extern uint32_t timerCtr;
aJsonObject *dev2Check = NULL;
OneWire *oneWire = NULL;
@@ -62,7 +61,7 @@ char * getReadableNote(aJsonObject * owObj)
void processTemp(aJsonObject * owObj, float currentTemp) {
if (!owObj || !owArr) return;
char* note = getReadableNote(owObj);
debugSerial<<endl<<F("1WT:")<<currentTemp<<F(" <")<<owObj->name<<F("> ");
debugSerial <<F("1WT:")<<currentTemp<<F(" <")<<owObj->name<<F("> ");
if ((currentTemp != -127.0) && (currentTemp != 85.0) && (currentTemp != 0.0))
{
if (note) debugSerial<<note;

View File

@@ -5,7 +5,7 @@
#define MAXFLASHSTR 32
#define PWDFLASHSTR 16
#define EEPROM_SIGNATURE "LHC1"
#define EEPROM_SIGNATURE "LHC2"
#define EEPROM_SIGNATURE_LENGTH 4
//#define EEPROM_offsetJSON IFLASH_PAGE_SIZE
@@ -23,12 +23,12 @@ const char EEPROM_signature[] = EEPROM_SIGNATURE;
uint32_t configFlags32bit;
struct
{
uint8_t serialDebugLevel:3;
uint8_t serialDebugLevel:4;
uint8_t notGetConfigFromHTTP:1;
uint8_t udpDebugLevel:3;
uint8_t notSaveSuccedConfig:1;
uint8_t dhcpFallback:1;
uint8_t spare2:7;
uint8_t spare2:6;
uint16_t sysConfigHash;
};
} systemConfigFlags;

View File

@@ -193,7 +193,7 @@ monitor_speed = 115200
platform = espressif32
framework = arduino
monitor_filters = esp32_exception_decoder
build_type = debug
;build_type = debug
board = esp32-evb
extra_scripts = extra_script.py
monitor_speed = 115200
@@ -521,10 +521,24 @@ lib_deps =
platform = espressif8266
framework = arduino
;board = nodemcuv2
board = esp01_1m
;esp12e ESP8266 80MHz 4MB 80KB Espressif ESP8266 ESP-12E
;esp01_1m ESP8266 80MHz 1MB 80KB Espressif Generic ESP8266 ESP-01 1M
extra_scripts = extra_script.py
board_build.ldscript = eagle.flash.1m64.ld
;upload_protocol = esptool
;;;; 1M plug ;;;
;board = esp01_1m
;board_build.ldscript = eagle.flash.1m64.ld
;;;;;;;;;;;;;;;;;;;
;;;; WEMOS D1 ;;;;;
board = d1_mini
; change microcontroller
board_build.mcu = esp8266
; change MCU frequency
board_build.f_cpu = 80000000L
upload_protocol = esptool
;;;;;;;;;;;;;;;;;;;
;build_type = debug
;monitor_filters = esp8266_exception_decoder