mass refactoring

sd_card_code not affects ram and firmware if not enabled
This commit is contained in:
livello
2018-03-30 02:30:10 +03:00
parent ec840f784a
commit a10c948f5a
9 changed files with 398 additions and 602 deletions

View File

@@ -83,7 +83,7 @@ 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) [Good tutorial for fast start in RUSSIAN.](https://geektimes.ru/post/273852/)
In linux\macOS you can open terminal, navigate to your programming directory, then
In linux\OSX you can open terminal, navigate to your programming directory, then
```bash
git clone https://github.com/anklimov/lighthub.git
@@ -129,11 +129,6 @@ platformio device monitor -b 115200
* MODBUS_DISABLE // disable Modbus support
* OWIRE_DISABLE // disable OneWire support
Look at build_flags_template.sh for customizing.
=======
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"
# Default compilation behavior:
* Config server: lazyhome.ru
@@ -147,5 +142,4 @@ export PLATFORMIO_BUILD_FLAGS="-DMY_CONFIG_SERVER=192.168.1.1 -DWATCH_DOG_TICKER
* DMX support enabled
* Modbus support enabled
* OneWire support enabled
=======

View File

@@ -35,7 +35,7 @@ e-mail anklimov@gmail.com
#define fmPar SERIAL_8N1
short modbusBusy = 0;
extern aJsonObject *modbusitem;
extern aJsonObject *modbusItem;
int modbusSet(int addr, uint16_t _reg, int _mask, uint16_t value);
@@ -934,12 +934,12 @@ int Item::checkModbus() {
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 &&
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;
modbusItem = modbusItem->next;
if (!modbusItem) modbusItem = items->child;
}
}

View File

@@ -57,119 +57,20 @@ DMX-OUT deploy on USART1
Config webserver
*/
#if defined(__ESP__)
#include <FS.h> //this needs to be first, or it all crashes and burns...
#endif
#include "main.h"
// Configuration of drivers enabled
#include "options.h"
#include <PubSubClient.h>
#include <SPI.h>
#include "utils.h"
#include <string.h>
#include <ModbusMaster.h>
#include "aJSON.h"
#include <Cmd.h>
#include "stdarg.h"
#if defined(__AVR__)
#include "HTTPClient.h"
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#define wdt_en() wdt_enable(WDTO_8S)
#define wdt_dis() wdt_disable()
#define wdt_res() wdt_reset()
#else
#include <ArduinoHttpClient.h>
#endif
#if defined(WATCH_DOG_TICKER_DISABLE)
#define wdt_en() wdt_disable()
#define wdt_dis() wdt_disable()
#define wdt_res() wdt_disable()
#endif
#if defined(__SAM3X8E__)
#include <DueFlashStorage.h>
DueFlashStorage EEPROM;
#include <watchdog.h>
#define wdt_res() watchdogReset()
#define wdt_en()
#define wdt_dis()
#else
#include <EEPROM.h>
#endif
#if defined(__ESP__)
#include "esp.h"
#define wdt_res()
#define wdt_en()
#define wdt_dis()
#else
#include "Dhcp.h"
#ifdef Wiz5500
#include <Ethernet2.h>
#else
#include <Ethernet.h>
#endif
EthernetClient ethClient;
#endif
#ifdef _owire
#include "owTerm.h"
#if defined(__AVR__)
EthernetClient ethClient;
#endif
#if defined(_dmxin) || defined(_dmxout) || defined (_artnet)
#include "dmx.h"
#endif
#include "item.h"
#include "inputs.h"
#ifdef _artnet
#include <Artnet.h>
extern Artnet *artnet;
#endif
#ifdef SD_CARD_INSERTED
#include "sd_card_w5100.h"
#endif
// Hardcoded definitions
//Thermostate histeresys
#define GIST 2
//#define serverip "192.168.88.2"
//IPAddress server(192, 168, 88, 2); //TODO - configure it
//const char inprefix[] PROGMEM = "/myhome/in/"
const char outprefix[] PROGMEM = OUTTOPIC;
const char inprefix[] PROGMEM = INTOPIC;
@@ -182,12 +83,12 @@ aJsonObject *modbusArr = NULL;
aJsonObject *owArr = NULL;
aJsonObject *dmxArr = NULL;
unsigned long modbuscheck = 0;
unsigned long incheck = 0;
unsigned long nextModbusCheck = 0;
unsigned long nextInputCheck = 0;
unsigned long lanCheck = 0;
unsigned long thermocheck = 0;
unsigned long nextThermostatCheck = 0;
aJsonObject *modbusitem = NULL;
aJsonObject *modbusItem = NULL;
bool owReady = false;
int lanStatus = 0;
@@ -205,9 +106,10 @@ PubSubClient mqttClient(ethClient);
void watchdogSetup(void) {} //Do not remove - strong re-definition WDT Init for DUE
// MQTT Callback routine
#define sublen 20
#define topiclen 20
void callback(char *topic, byte *payload, unsigned int length) {
#define MQTT_SUBJECT_LENGTH 20
#define MQTT_TOPIC_LENGTH 20
void mqttCallback(char *topic, byte *payload, unsigned int length) {
payload[length] = 0;
Serial.print(F("\n["));
Serial.print(topic);
@@ -218,7 +120,7 @@ void callback(char *topic, byte *payload, unsigned int length) {
Serial.println(F("OOM!"));
return;
}
for (int i = 0; i < length; i++) {
Serial.print((char) payload[i]);
}
@@ -226,25 +128,26 @@ void callback(char *topic, byte *payload, unsigned int length) {
boolean retaining = (lanStatus == 4); //Todo - named constant
//Check if topic = Command topic
short intopic=0;
short intopic = 0;
{
char buf[topiclen+1];
strncpy_P(buf,inprefix,sizeof(buf));
intopic = strncmp(topic,buf,strlen(inprefix));
char buf[MQTT_TOPIC_LENGTH + 1];
strncpy_P(buf, inprefix, sizeof(buf));
intopic = strncmp(topic, buf, strlen(inprefix));
}
// in Retaining status - trying to restore previous state from retained output topic. Retained input topics are not relevant.
if (retaining && !intopic) {
Serial.println(F("Skipping.."));
return;
Serial.println(F("Skipping.."));
return;
}
char subtopic[sublen] = "";
char subtopic[MQTT_SUBJECT_LENGTH] = "";
int cmd = 0;
cmd = txt2cmd((char *) payload);
char *t;
if (t = strrchr(topic, '/')) strncpy(subtopic, t + 1, sublen - 1);
if (t = strrchr(topic, '/'))
strncpy(subtopic, t + 1, MQTT_SUBJECT_LENGTH - 1);
@@ -286,8 +189,9 @@ void callback(char *topic, byte *payload, unsigned int length) {
case CMD_ON:
if (item.getEnableCMD(500) || lanStatus == 4)
item.Ctrl(cmd, 0, NULL, !retaining); //Accept ON command not earlier then 500 ms after set settings (Homekit hack)
else Serial.println("on Skipped");
item.Ctrl(cmd, 0, NULL,
!retaining); //Accept ON command not earlier then 500 ms after set settings (Homekit hack)
else Serial.println(F("on Skipped"));
break;
default: //some known command
@@ -303,7 +207,6 @@ void callback(char *topic, byte *payload, unsigned int length) {
void printIPAddress() {
Serial.print(F("My IP address: "));
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(F("."));
}
@@ -313,13 +216,11 @@ void printIPAddress() {
#endif
void printMACAddress() {
Serial.print(F("My mac address: "));
Serial.print(F("Configured MAC:"));
for (byte thisByte = 0; thisByte < 6; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(mac[thisByte], HEX);
Serial.print(F(":"));
}
Serial.println();
}
@@ -328,9 +229,6 @@ void restoreState() {
//mqttClient.publish("/myhome/out/RestoreState", "ON");
};
int getConfig(int arg_cnt, char **args);
int lanLoop() {
#ifdef NOETHER
@@ -403,17 +301,17 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
// ... Temporary subscribe to status topic
char buf[topiclen];
strncpy_P(buf,outprefix,sizeof(buf));
strncat(buf,"#",sizeof(buf));
char buf[MQTT_TOPIC_LENGTH];
strncpy_P(buf, outprefix, sizeof(buf));
strncat(buf, "#", sizeof(buf));
mqttClient.subscribe(buf);
//Subscribing for command topics
strncpy_P(buf,inprefix,sizeof(buf));
strncat(buf,"#",sizeof(buf));
mqttClient.subscribe(buf);
strncpy_P(buf, inprefix, sizeof(buf));
strncat(buf, "#", sizeof(buf));
mqttClient.subscribe(buf);
//restoreState();
// if (_once) {DMXput(); _once=0;}
lanStatus = 4;
@@ -431,19 +329,19 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
}
case 4: //retaining ... Collecting
if (millis() > lanCheck) {
char buf[topiclen];
//Unsubscribe from status topics..
strncpy_P(buf,outprefix,sizeof(buf));
strncat(buf,"#",sizeof(buf));
mqttClient.unsubscribe(buf);
lanStatus = 3;
Serial.println(F("Accepting commands..."));
break;
}
if (millis() > lanCheck) {
char buf[MQTT_TOPIC_LENGTH];
//Unsubscribe from status topics..
strncpy_P(buf, outprefix, sizeof(buf));
strncat(buf, "#", sizeof(buf));
mqttClient.unsubscribe(buf);
lanStatus = 3;
Serial.println(F("Accepting commands..."));
break;
}
case 3: //operation
if (!mqttClient.connected()) lanStatus = 2;
break;
@@ -597,11 +495,10 @@ void Changed(int i, DeviceAddress addr, int val) {
}
}
#endif
#endif //_owire
void modbusIdle(void);
void _handleHelp(int arg_cnt, char **args)
void cmdFunctionHelp(int arg_cnt, char **args)
//(char* tokens)
{
Serial.println(F("Use the commands: 'help' - this text\n"
@@ -612,29 +509,27 @@ void _handleHelp(int arg_cnt, char **args)
"'kill' - test watchdog"));
}
void _kill(int arg_cnt, char **args) {
void cmdFunctionKill(int arg_cnt, char **args) {
for (short i = 17; i > 0; i--) {
delay(1000);
Serial.println(i);
};
}
#define EEPROM_offset 32+6
void applyConfig() {
int arrayItemValue, itemsCount;
//DMX out is configured
aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx");
#ifdef _dmxout
int maxChannels;
aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx");
if (dmxoutArr && aJson.getArraySize(dmxoutArr) == 2) {
DMXoutSetup(arrayItemValue = aJson.getArrayItem(dmxoutArr, 1)->valueint,
DMXoutSetup(maxChannels = aJson.getArrayItem(dmxoutArr, 1)->valueint,
aJson.getArrayItem(dmxoutArr, 0)->valueint);
Serial.print(F("DMX out started. Channels: "));
Serial.println(arrayItemValue);
Serial.println(maxChannels);
}
#endif
//DMX in is configured
#ifdef _dmxin
int itemsCount;
dmxArr = aJson.getObjectItem(root, "dmxin");
if (dmxArr && (itemsCount = aJson.getArraySize(dmxArr))) {
DMXinSetup(itemsCount * 4);
@@ -643,22 +538,38 @@ void applyConfig() {
}
#endif
items = aJson.getObjectItem(root, "items");
modbusitem = items->child;
inputs = aJson.getObjectItem(root, "in");
#ifdef _modbus
modbusArr = aJson.getObjectItem(root, "modbus");
#endif
mqttArr = aJson.getObjectItem(root, "mqtt");
#ifdef _owire
owArr = aJson.getObjectItem(root, "ow");
#endif
Serial.println(F("Configured:"));
#ifdef _owire
if (owArr && !owReady) {
aJsonObject *item = owArr->child;
owReady = owSetup(&Changed);
while (item) {
if ((item->type == aJson_Object)) {
DeviceAddress addr;
//Serial.print(F("Add:")),Serial.println(item->name);
SetAddr(item->name, addr);
owAdd(addr);
}
item = item->next;
}
}
#endif
items = aJson.getObjectItem(root, "items");
modbusItem = items->child;
inputs = aJson.getObjectItem(root, "in");
mqttArr = aJson.getObjectItem(root, "mqtt");
printConfigSummary();
}
void printConfigSummary() {
Serial.println(F("Configured:"));
Serial.print(F("items "));
printBool(items);
Serial.print(F("inputs "));
@@ -669,27 +580,9 @@ void applyConfig() {
printBool(mqttArr);
Serial.print(F("1-wire "));
printBool(owArr);
#ifdef _owire
if (owArr && !owReady) {
aJsonObject *item = owArr->child;
owReady = owSetup(&Changed);
while (item) {
if ((item->type == aJson_Object)) {
DeviceAddress addr;
//Serial.print(F("Add:")),Serial.println(item->name);
SetAddr(item->name, addr);
owAdd(addr);
}
item = item->next;
}
}
#endif
}
void _loadConfig(int arg_cnt, char **args) {
void cmdFunctionLoad(int arg_cnt, char **args) {
loadConfigFromEEPROM(arg_cnt, args);
restoreState();
}
@@ -720,7 +613,7 @@ int loadConfigFromEEPROM(int arg_cnt, char **args)
}
}
void _mqttConfigRequest(int arg_cnt, char **args) {
void cmdFunctionReq(int arg_cnt, char **args) {
mqttConfigRequest(arg_cnt, args);
restoreState();
}
@@ -761,7 +654,7 @@ int mqttConfigResp(char *as) {
return 1;
}
void _saveConfigToEEPROM(int arg_cnt, char **args)
void cmdFunctionSave(int arg_cnt, char **args)
//(char* tokens)
{
aJsonEEPROMStream jsonEEPROMStream = aJsonEEPROMStream(EEPROM_offset);
@@ -772,7 +665,7 @@ void _saveConfigToEEPROM(int arg_cnt, char **args)
}
void _setMacAddress(int arg_cnt, char **args) {
void cmdFunctionSetMac(int arg_cnt, char **args) {
//Serial.print("Got:");
//Serial.println(args[1]);
@@ -792,7 +685,7 @@ void _setMacAddress(int arg_cnt, char **args) {
Serial.println(F("Updated"));
}
void _getConfig(int arg_cnt, char **args) {
void cmdFunctionGet(int arg_cnt, char **args) {
getConfig(arg_cnt, args);
restoreState();
}
@@ -938,63 +831,27 @@ void postTransmission() {
//modbusSerial.flush();
digitalWrite(TXEnablePin, 0);
}
//#define PIO_SRC_REV commit 8034a6b765229d94a94d90fd08dd9588acf5f3da Author: livello <livello@bk.ru> Date: Wed Mar 28 02:35:50 2018 +0300 refactoring
void setup_main() {
cmdInit(uint32_t(SERIAL_BAUD));
Serial.print(F("\nLazyhome.ru LightHub controller "));
Serial.println(F(QUOTE(PIO_SRC_REV)));
#ifdef WATCH_DOG_TICKER_DISABLE
Serial.println(F("WATCHDOG TICKER DISABLED"));
#endif
#ifdef DISABLE_FREERAM_PRINT
Serial.println(F("FreeRam printing DISABLED"));
#endif
setupCmdArduino();
printFirmwareVersionAndBuildOptions();
#ifdef SD_CARD_INSERTED
sd_card_w5100_setup();
#endif
cmdAdd("help", _handleHelp);
cmdAdd("save", _saveConfigToEEPROM);
cmdAdd("load", _loadConfig);
cmdAdd("get", _getConfig);
cmdAdd("set", _setMacAddress);
cmdAdd("kill", _kill);
cmdAdd("req", _mqttConfigRequest);
#ifdef __ESP__
espSetup();
#endif
short macvalid = 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 firmware's MAC"));
memcpy(mac, firmwareMacAddress, 6);
}
printMACAddress();
setupMacAddress();
loadConfigFromEEPROM(0, NULL);
#ifdef _modbus
pinMode(TXEnablePin, OUTPUT);
modbusSerial.begin(9600);
modbusSerial.begin(MODBUS_SERIAL_BAUD);
node.idle(&modbusIdle);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
@@ -1002,33 +859,83 @@ void setup_main() {
#endif
delay(20);
owReady = 0;
#ifdef _owire
if (net) net->idle(&owIdle);
#endif
//client.setServer(server, 1883);
mqttClient.setCallback(callback);
mqttClient.setCallback(mqttCallback);
#ifdef _artnet
ArtnetSetup();
#endif
#if defined(__SAM3X8E__)
// checkForRemoteSketchUpdate();
//TODO: checkForRemoteSketchUpdate();
}
void printFirmwareVersionAndBuildOptions() {
Serial.print(F("\nLazyhome.ru LightHub controller "));
Serial.println(F(QUOTE(PIO_SRC_REV)));
#ifdef WATCH_DOG_TICKER_DISABLE
Serial.println(F("(-)WATCHDOG"));
#else
Serial.println(F("(+)WATCHDOG"));
#endif
Serial.print(F("Config server:"));
Serial.println(F(CONFIG_SERVER));
Serial.print(F("Firmware MAC Address "));
#ifdef DEFAULT_FIRMWARE_MAC
Serial.println(F(Q(DEFAULT_FIRMWARE_MAC)));
#endif
#ifdef CUSTOM_FIRMWARE_MAC
Serial.println(F(QUOTE(CUSTOM_FIRMWARE_MAC)));
#endif
printMACAddress();
#ifdef DISABLE_FREERAM_PRINT
Serial.println(F("(-)FreeRam printing"));
#else
Serial.println(F("(+)FreeRam printing"));
#endif
}
void setupMacAddress() {
#ifdef DEFAULT_FIRMWARE_MAC
byte firmwareMacAddress[6] = DEFAULT_FIRMWARE_MAC;
#else
byte firmwareMacAddress[6];
const char *macStr = QUOTE(CUSTOM_FIRMWARE_MAC);
parseBytes(macStr, ':', firmwareMacAddress, 6, 16);
#endif
bool isMacValid = false;
for (short i = 0; i < 6; i++) {
mac[i] = EEPROM.read(i);
if (mac[i] != 0 && mac[i] != 0xff) isMacValid = true;
}
if (!isMacValid) {
Serial.println(F("Invalid MAC: set firmware's MAC"));
memcpy(mac, firmwareMacAddress, 6);
}
printMACAddress();
}
void setupCmdArduino() {
cmdInit(uint32_t(SERIAL_BAUD));
cmdAdd("help", cmdFunctionHelp);
cmdAdd("save", cmdFunctionSave);
cmdAdd("load", cmdFunctionLoad);
cmdAdd("get", cmdFunctionGet);
cmdAdd("set", cmdFunctionSetMac);
cmdAdd("kill", cmdFunctionKill);
cmdAdd("req", cmdFunctionReq);
}
void loop_main() {
wdt_res();
//commandLine.update();
cmdPoll();
if (lanLoop() > 1) {
mqttClient.loop();
@@ -1047,8 +954,6 @@ void loop_main() {
#endif
// if (lastpacket && (lastpacket%10==0)) Serial.println(lastpacket);
#ifdef _modbus
if (modbusArr && items) modbusLoop();
#endif
@@ -1062,19 +967,16 @@ void loop_main() {
#if defined (_espdmx)
dmxout.update();
#endif
}
// Idle handlers
void owIdle(void) {
#ifdef _artnet
if (artnet) artnet->read();
#endif
wdt_res();
return;///
return; //TODO: unreached code
Serial.print(F("o"));
if (lanLoop() == 1) mqttClient.loop();
//if (owReady) owLoop();
@@ -1085,14 +987,9 @@ void owIdle(void) {
#if defined (_espdmx)
dmxout.update();
#endif
//modbusLoop();
}
void modbusIdle(void) {
//Serial.print("m");
wdt_res();
if (lanLoop() > 1) {
mqttClient.loop();
@@ -1101,7 +998,6 @@ void modbusIdle(void) {
#endif
}
//if (owReady) owLoop();
#ifdef _dmxin
DMXCheck();
#endif
@@ -1109,22 +1005,11 @@ void modbusIdle(void) {
#if defined (_espdmx)
dmxout.update();
#endif
//modbusloop();
}
// Loops
void inputLoop(void) {
if (millis() > incheck) {
if (millis() > nextInputCheck) {
aJsonObject *input = inputs->child;
while (input) {
if ((input->type == aJson_Object)) {
Input in(input);
@@ -1132,35 +1017,31 @@ void inputLoop(void) {
}
input = input->next;
}
incheck = millis() + 50;
nextInputCheck = millis() + INTERVAL_CHECK_INPUT;
}
}
void modbusLoop(void) {
boolean done = false;
if (millis() > modbuscheck) {
while (modbusitem && !done) {
if (modbusitem->type == aJson_Array) {
switch (aJson.getArrayItem(modbusitem, 0)->valueint) {
if (millis() > nextModbusCheck) {
while (modbusItem && !done) {
if (modbusItem->type == aJson_Array) {
switch (aJson.getArrayItem(modbusItem, 0)->valueint) {
case CH_MODBUS:
//case CH_VCTEMP:
case CH_VC: {
Item it(modbusitem);
Item it(modbusItem);
it.Poll();
modbuscheck = millis() + 2000;
nextModbusCheck = millis() + INTERVAL_CHECK_MODBUS;
done = true;
break; //case;
}
} //switch
}//if
modbusitem = modbusitem->next;
if (!modbusitem) {
modbusitem = items->child;
modbusItem = modbusItem->next;
if (!modbusItem) {
modbusItem = items->child;
return;
} //start from 1-st element
} //while
@@ -1168,75 +1049,71 @@ void modbusLoop(void) {
}
// To be refactored
//TODO: refactoring
void thermoLoop(void) {
#define T_ATTEMPTS 200
#define IET_TEMP 0
#define IET_ATTEMPTS 1
if (millis() < nextThermostatCheck)
return;
if (millis() > thermocheck) {
bool thermostatCheckPrinted = false;
aJsonObject *item = items->child;
bool thermostatCheckPrinted = false;
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 itemPin = aJson.getArrayItem(item, I_ARG)->valueint;
int itemTempSetting = aJson.getArrayItem(item, I_VAL)->valueint;
int itemCommand = aJson.getArrayItem(item, I_CMD)->valueint;
aJsonObject *itemExtensionArray = aJson.getArrayItem(item, I_EXT);
int cmd = aJson.getArrayItem(item, I_CMD)->valueint;
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"));
} else {
if (!(--aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint))
mqttClient.publish("/alarm", item->name);
}
thermostatCheckPrinted = true;
if (itemExtensionArray && (aJson.getArraySize(itemExtensionArray) > 1)) {
int curtemp = aJson.getArrayItem(itemExtensionArray, IET_TEMP)->valueint;
if (!aJson.getArrayItem(itemExtensionArray, IET_ATTEMPTS)->valueint) {
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.println(F(" Expired"));
pinMode(pin, OUTPUT);
if (cmd == CMD_OFF || cmd == CMD_HALT || aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint == 0) {
digitalWrite(pin, LOW);
} else {
if (!(--aJson.getArrayItem(itemExtensionArray, IET_ATTEMPTS)->valueint))
mqttClient.publish("/alarm", item->name);
}
thermostatCheckPrinted = true;
Serial.print(item->name);
Serial.print(F(" Set:"));
Serial.print(itemTempSetting);
Serial.print(F(" Curtemp:"));
Serial.print(curtemp);
Serial.print(F(" cmd:"));
Serial.print(itemCommand),
pinMode(itemPin, OUTPUT);
if (itemCommand == CMD_OFF || itemCommand == CMD_HALT ||
aJson.getArrayItem(itemExtensionArray, IET_ATTEMPTS)->valueint == 0) {
digitalWrite(itemPin, LOW);
Serial.println(F(" OFF"));
} else {
if (curtemp + THERMO_GIST_CELSIUS < itemTempSetting) {
digitalWrite(itemPin, HIGH);
Serial.println(F(" ON"));
} //too cold
else if (itemTempSetting <= curtemp) {
digitalWrite(itemPin, 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
}
} //Reached settings
else Serial.println(F(" --")); // Nothing to do
}
}
item = item->next;
}
item = item->next;
}
thermocheck = millis() + 5000;
nextThermostatCheck = millis() + THERMOSTAT_CHECK_PERIOD;
#ifndef DISABLE_FREERAM_PRINT
(thermostatCheckPrinted) ? Serial.print(F("\nfree:")) : Serial.print(F(" "));
Serial.print(freeRam());
Serial.print(" ");
(thermostatCheckPrinted) ? Serial.print(F("\nfree:")) : Serial.print(F(" "));
Serial.print(freeRam());
Serial.print(" ");
#endif
}
}

View File

@@ -1,56 +1,181 @@
//
// Created by livello on 13.03.18.
//
#include "options.h"
#ifndef LIGHTHUB_MAIN_H
#define LIGHTHUB_MAIN_H
#define TXEnablePin 13
#ifndef SERIAL_BAUD
#define SERIAL_BAUD 115200
#if defined(__SAM3X8E__)
#define wdt_res() watchdogReset()
#define wdt_en()
#define wdt_dis()
#endif
#ifndef CUSTOM_FIRMWARE_MAC
#define FIRMWARE_MAC {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0}
#if defined(__AVR__)
#define wdt_en() wdt_enable(WDTO_8S)
#define wdt_dis() wdt_disable()
#define wdt_res() wdt_reset()
#endif
#if defined(__ESP__)
#define wdt_res()
#define wdt_en()
#define wdt_dis()
#endif
#if defined(WATCH_DOG_TICKER_DISABLE) && defined(__AVR__)
#define wdt_en() wdt_disable()
#define wdt_dis() wdt_disable()
#define wdt_res() wdt_disable()
#endif
#include "Arduino.h"
#include "DallasTemperature.h"
#include <PubSubClient.h>
#include <SPI.h>
#include "utils.h"
#include <string.h>
#include <ModbusMaster.h>
#include "aJSON.h"
#include <Cmd.h>
#include "stdarg.h"
#include "item.h"
#include "inputs.h"
#include "Dhcp.h"
#if defined(__SAM3X8E__)
#include <DueFlashStorage.h>
#include <watchdog.h>
#include <ArduinoHttpClient.h>
#endif
#if defined(__AVR__)
#include "HTTPClient.h"
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <EEPROM.h>
#endif
#if defined(__ESP__)
#include <FS.h> //this needs to be first, or it all crashes and burns...
#include "esp.h"
#include <EEPROM.h>
#include <ArduinoHttpClient.h>
#endif
#ifdef _owire
#include "owTerm.h"
#endif
#if defined(_dmxin) || defined(_dmxout) || defined (_artnet)
#include "dmx.h"
#endif
#ifdef Wiz5500
#include <Ethernet2.h>
#else
#include <Ethernet.h>
#endif
#ifdef _artnet
#include <Artnet.h>
#endif
#ifdef SD_CARD_INSERTED
#include "sd_card_w5100.h"
#endif
#ifdef _artnet
extern Artnet *artnet;
#endif
void watchdogSetup(void);
void callback(char* topic, byte* payload, unsigned int length);
void mqttCallback(char *topic, byte *payload, unsigned int length);
#ifndef __ESP__
void printIPAddress();
#endif
void printMACAddress();
void restoreState();
int lanLoop();
void Changed (int i, DeviceAddress addr, int val);
int lanLoop();
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 cmdFunctionHelp(int arg_cnt, char **args);
void cmdFunctionKill(int arg_cnt, char **args);
void applyConfig();
void _loadConfig (int arg_cnt, char **args);
void cmdFunctionLoad(int arg_cnt, char **args);
int loadConfigFromEEPROM(int arg_cnt, char **args);
void _mqttConfigRequest(int arg_cnt, char **args);
void cmdFunctionReq(int arg_cnt, char **args);
int mqttConfigRequest(int arg_cnt, char **args);
int mqttConfigResp (char * as);
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);
void loadFlash(short n, char* str);
int getConfig (int arg_cnt, char **args);
int mqttConfigResp(char *as);
void cmdFunctionSave(int arg_cnt, char **args);
void cmdFunctionSetMac(int arg_cnt, char **args);
void cmdFunctionGet(int arg_cnt, char **args);
void printBool(bool arg);
void saveFlash(short n, char *str);
void loadFlash(short n, char *str);
int getConfig(int arg_cnt, char **args);
void preTransmission();
void postTransmission();
void setup_main();
void loop_main();
void owIdle(void);
void modbusIdle(void);
void inputLoop(void);
void modbusLoop(void);
void thermoLoop(void);
short thermoSetCurTemp(char * name, short t);
short thermoSetCurTemp(char *name, short t);
void modbusIdle(void);
void printConfigSummary();
void setupCmdArduino();
void setupMacAddress();
int getConfig(int arg_cnt, char **args);
void printFirmwareVersionAndBuildOptions();
#endif //LIGHTHUB_MAIN_H

View File

@@ -3,6 +3,33 @@
#define PIO_SRC_REV v0.99
#endif
#define TXEnablePin 13
#define T_ATTEMPTS 200
#define IET_TEMP 0
#define IET_ATTEMPTS 1
#define THERMO_GIST_CELSIUS 2
#define EEPROM_offset 32+6
#define INTERVAL_CHECK_INPUT 50
#define INTERVAL_CHECK_MODBUS 2000
#define THERMOSTAT_CHECK_PERIOD 5000
#ifndef MODBUS_SERIAL_BAUD
#define MODBUS_SERIAL_BAUD 9600
#endif
#ifndef SERIAL_BAUD
#define SERIAL_BAUD 115200
#endif
#ifndef CUSTOM_FIRMWARE_MAC
#define DEFAULT_FIRMWARE_MAC {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0}
#endif
#ifndef OUTTOPIC
#define OUTTOPIC "/myhome/s_out/"
#endif
@@ -55,6 +82,3 @@
#ifndef _dmxout
#undef _artnet
#endif
#define Q(x) #x
#define QUOTE(x) Q(x)

View File

@@ -17,8 +17,11 @@ GIT: https://github.com/anklimov/lighthub
e-mail anklimov@gmail.com
*/
#define Q(x) #x
#define QUOTE(x) Q(x)
#include <Arduino.h>
void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0);
void SetBytes(uint8_t* addr, uint8_t count, char * out);
void SetAddr(char * out, uint8_t* addr);

View File

@@ -10,8 +10,8 @@
[platformio]
src_dir = lighthub
env_default =
megaatmega2560
; due
; megaatmega2560
due
; esp8266
[env:due]

View File

@@ -1,212 +0,0 @@
//
// Created by livello on 14.10.17.
//
/*
SD card test
This example shows how use the utility libraries on which the'
SD library is based in order to get info about your SD card.
Very useful for testing a card when you're not sure whether its working or not.
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
** CS - depends on your SD card shield or module.
Pin 4 used here for consistency with other Arduino examples
created 28 Mar 2011
by Limor Fried
modified 9 Apr 2012
by Tom Igoe
*/
//template<class T> inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
#include "sd_card_w5100.h"
#include <SD.h>
#include <SPI.h>
//#include <iostream>
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile sdFile;
File myFile;
char *entireFileContents;
// Arduino Ethernet shield: pin 4
const int chipSelect = 4;
void bench() {
/* uint8_t buf[BUF_SIZE];
long maxLatency,minLatency,totalLatency,temp_DHT22;
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
} else {
// if the file didn'temp_DHT22 open, print an error:
Serial.println("error opening test.txt");
}
for (uint16_t i = 0; i < (BUF_SIZE - 2); i++) {
buf[i] = 'A' + (i % 26);
}
buf[BUF_SIZE - 2] = '\r';
buf[BUF_SIZE - 1] = '\n';
Serial.println("File size MB: ");
Serial.print(FILE_SIZE_MB);
Serial.println("Buffer size ");
Serial.print(BUF_SIZE);
Serial.println("Starting write test, please wait.");
// do write test
uint32_t n = FILE_SIZE / sizeof(buf);
Serial.println("write speed and latency");
Serial.print(" speed,max,min,avg");
Serial.print(" KB/Sec,usec,usec,usec");
for (uint8_t nTest = 0; nTest < WRITE_PASS_COUNT; nTest++) {
// myFile.truncate(0);
maxLatency = 0;
minLatency = 9999999;
totalLatency = 0;
temp_DHT22 = millis();
for (uint32_t i = 0; i < n; i++) {
uint32_t m = micros();
if (myFile.write(buf, sizeof(buf)) != sizeof(buf)) {
Serial.println("write failed");
}
m = micros() - m;
if (maxLatency < m) {
maxLatency = m;
}
if (minLatency > m) {
minLatency = m;
}
totalLatency += m;
}
myFile.flush();
temp_DHT22 = millis() - temp_DHT22;
int s = myFile.size();
Serial.println(s / temp_DHT22);
Serial.print(',');
Serial.print(maxLatency);
Serial.print(',');
Serial.print(minLatency);
Serial.print(',');
Serial.print(totalLatency / n);
}*/
myFile.close();
Serial.println("done.");
}
char* sdW5100_readEntireFile(const char *filename) {
SdFile requestedFile;
if(requestedFile.open(sdFile,filename)) {
Serial.println("Success open INDEX.HTM:");
long time_started = millis();
entireFileContents = new char[requestedFile.fileSize()];
requestedFile.read(entireFileContents,requestedFile.fileSize());
Serial.print(millis()-time_started);
Serial.println(" milliseconds takes to read.");
return entireFileContents;
}
else {
Serial.print("Failed sdFile.open ");
Serial.println(filename);
}
return NULL;
}
uint32_t sdW5100_getFileSize(const char *filename){
SdFile requestedFile;
if(requestedFile.open(sdFile,filename))
return requestedFile.fileSize();
else
return 0;
}
void sd_card_w5100_setup() {
Serial.print("\nInitializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.
pinMode(chipSelect, OUTPUT);
if (!card.init(SPI_FULL_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card is inserted?");
Serial.println("* Is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
return;
} else {
Serial.println("Wiring is correct and a card is present.");
}
// print the type of card
Serial.print("\nCard type: ");
switch (card.type()) {
case SD_CARD_TYPE_SD1:
Serial.println("SD1");
break;
case SD_CARD_TYPE_SD2:
Serial.println("SD2");
break;
case SD_CARD_TYPE_SDHC:
Serial.println("SDHC");
break;
default:
Serial.println("Unknown");
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
return;
}
// print the type and size of the first FAT-type volume
uint32_t volumesize;
Serial.print("\nVolume type is FAT");
Serial.println(volume.fatType(), DEC);
Serial.println();
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
volumesize *= 512; // SD card blocks are always 512 bytes
Serial.print("Volume size (bytes): ");
Serial.println(volumesize);
Serial.print("Volume size (Kbytes): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.print("Volume size (Mbytes): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
sdFile.openRoot(volume);
// list all files in the card with date and size
sdFile.ls(LS_R | LS_DATE | LS_SIZE);
Serial.println(sdW5100_readEntireFile("INDEX.HTM"));
}

View File

@@ -1,15 +0,0 @@
//
// Created by livello on 14.10.17.
//
#include <stdint.h>
#ifndef NODEMCU_STOPWATCH_SD_CARD_W5100_H
#define NODEMCU_STOPWATCH_SD_CARD_W5100_H
#endif //NODEMCU_STOPWATCH_SD_CARD_W5100_H
void sd_card_w5100_setup();
void cidDmp();
void bench();
char* sdW5100_readEntireFile(const char *filename);
uint32_t sdW5100_getFileSize(const char *filename);