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 # 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/) [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 ```bash
git clone https://github.com/anklimov/lighthub.git git clone https://github.com/anklimov/lighthub.git
@@ -129,11 +129,6 @@ platformio device monitor -b 115200
* MODBUS_DISABLE // disable Modbus support * MODBUS_DISABLE // disable Modbus support
* OWIRE_DISABLE // disable OneWire 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: # Default compilation behavior:
* Config server: lazyhome.ru * 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 * DMX support enabled
* Modbus support enabled * Modbus support enabled
* OneWire support enabled * OneWire support enabled
=======

View File

@@ -35,7 +35,7 @@ e-mail anklimov@gmail.com
#define fmPar SERIAL_8N1 #define fmPar SERIAL_8N1
short modbusBusy = 0; short modbusBusy = 0;
extern aJsonObject *modbusitem; extern aJsonObject *modbusItem;
int modbusSet(int addr, uint16_t _reg, int _mask, uint16_t value); int modbusSet(int addr, uint16_t _reg, int _mask, uint16_t value);
@@ -934,12 +934,12 @@ int Item::checkModbus() {
modbusBusy = 0; modbusBusy = 0;
// Looking 1 step ahead for modbus item, which uses same register // Looking 1 step ahead for modbus item, which uses same register
Item nextItem(modbusitem->next); Item nextItem(modbusItem->next);
if (modbusitem && nextItem.isValid() && nextItem.itemType == CH_MODBUS && nextItem.getArg(0) == addr && if (modbusItem && nextItem.isValid() && nextItem.itemType == CH_MODBUS && nextItem.getArg(0) == addr &&
nextItem.getArg(1) == reg) { nextItem.getArg(1) == reg) {
nextItem.checkModbus(data); nextItem.checkModbus(data);
modbusitem = modbusitem->next; modbusItem = modbusItem->next;
if (!modbusitem) modbusitem = items->child; if (!modbusItem) modbusItem = items->child;
} }
} }

View File

@@ -57,119 +57,20 @@ DMX-OUT deploy on USART1
Config webserver Config webserver
*/ */
#if defined(__ESP__)
#include <FS.h> //this needs to be first, or it all crashes and burns...
#endif
#include "main.h" #include "main.h"
// Configuration of drivers enabled
#include "options.h" #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__) #if defined(__SAM3X8E__)
#include <DueFlashStorage.h>
DueFlashStorage EEPROM; 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; EthernetClient ethClient;
#endif #endif
#ifdef _owire #if defined(__AVR__)
EthernetClient ethClient;
#include "owTerm.h"
#endif #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 outprefix[] PROGMEM = OUTTOPIC;
const char inprefix[] PROGMEM = INTOPIC; const char inprefix[] PROGMEM = INTOPIC;
@@ -182,12 +83,12 @@ aJsonObject *modbusArr = NULL;
aJsonObject *owArr = NULL; aJsonObject *owArr = NULL;
aJsonObject *dmxArr = NULL; aJsonObject *dmxArr = NULL;
unsigned long modbuscheck = 0; unsigned long nextModbusCheck = 0;
unsigned long incheck = 0; unsigned long nextInputCheck = 0;
unsigned long lanCheck = 0; unsigned long lanCheck = 0;
unsigned long thermocheck = 0; unsigned long nextThermostatCheck = 0;
aJsonObject *modbusitem = NULL; aJsonObject *modbusItem = NULL;
bool owReady = false; bool owReady = false;
int lanStatus = 0; int lanStatus = 0;
@@ -205,9 +106,10 @@ 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 // MQTT Callback routine
#define sublen 20 #define MQTT_SUBJECT_LENGTH 20
#define topiclen 20 #define MQTT_TOPIC_LENGTH 20
void callback(char *topic, byte *payload, unsigned int length) {
void mqttCallback(char *topic, byte *payload, unsigned int length) {
payload[length] = 0; payload[length] = 0;
Serial.print(F("\n[")); Serial.print(F("\n["));
Serial.print(topic); Serial.print(topic);
@@ -226,25 +128,26 @@ void callback(char *topic, byte *payload, unsigned int length) {
boolean retaining = (lanStatus == 4); //Todo - named constant boolean retaining = (lanStatus == 4); //Todo - named constant
//Check if topic = Command topic //Check if topic = Command topic
short intopic=0; short intopic = 0;
{ {
char buf[topiclen+1]; char buf[MQTT_TOPIC_LENGTH + 1];
strncpy_P(buf,inprefix,sizeof(buf)); strncpy_P(buf, inprefix, sizeof(buf));
intopic = strncmp(topic,buf,strlen(inprefix)); intopic = strncmp(topic, buf, strlen(inprefix));
} }
// in Retaining status - trying to restore previous state from retained output topic. Retained input topics are not relevant. // in Retaining status - trying to restore previous state from retained output topic. Retained input topics are not relevant.
if (retaining && !intopic) { if (retaining && !intopic) {
Serial.println(F("Skipping..")); Serial.println(F("Skipping.."));
return; return;
} }
char subtopic[sublen] = ""; char subtopic[MQTT_SUBJECT_LENGTH] = "";
int cmd = 0; int cmd = 0;
cmd = txt2cmd((char *) payload); cmd = txt2cmd((char *) payload);
char *t; 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: case CMD_ON:
if (item.getEnableCMD(500) || lanStatus == 4) 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) item.Ctrl(cmd, 0, NULL,
else Serial.println("on Skipped"); !retaining); //Accept ON command not earlier then 500 ms after set settings (Homekit hack)
else Serial.println(F("on Skipped"));
break; break;
default: //some known command default: //some known command
@@ -303,7 +207,6 @@ void callback(char *topic, byte *payload, unsigned int length) {
void printIPAddress() { void printIPAddress() {
Serial.print(F("My IP address: ")); Serial.print(F("My IP address: "));
for (byte thisByte = 0; thisByte < 4; thisByte++) { 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(Ethernet.localIP()[thisByte], DEC);
Serial.print(F(".")); Serial.print(F("."));
} }
@@ -313,13 +216,11 @@ void printIPAddress() {
#endif #endif
void printMACAddress() { void printMACAddress() {
Serial.print(F("My mac address: ")); Serial.print(F("Configured MAC:"));
for (byte thisByte = 0; thisByte < 6; thisByte++) { for (byte thisByte = 0; thisByte < 6; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(mac[thisByte], HEX); Serial.print(mac[thisByte], HEX);
Serial.print(F(":")); Serial.print(F(":"));
} }
Serial.println(); Serial.println();
} }
@@ -328,9 +229,6 @@ void restoreState() {
//mqttClient.publish("/myhome/out/RestoreState", "ON"); //mqttClient.publish("/myhome/out/RestoreState", "ON");
}; };
int getConfig(int arg_cnt, char **args);
int lanLoop() { int lanLoop() {
#ifdef NOETHER #ifdef NOETHER
@@ -403,15 +301,15 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
// ... Temporary subscribe to status topic // ... Temporary subscribe to status topic
char buf[topiclen]; char buf[MQTT_TOPIC_LENGTH];
strncpy_P(buf,outprefix,sizeof(buf)); strncpy_P(buf, outprefix, sizeof(buf));
strncat(buf,"#",sizeof(buf)); strncat(buf, "#", sizeof(buf));
mqttClient.subscribe(buf); mqttClient.subscribe(buf);
//Subscribing for command topics //Subscribing for command topics
strncpy_P(buf,inprefix,sizeof(buf)); strncpy_P(buf, inprefix, sizeof(buf));
strncat(buf,"#",sizeof(buf)); strncat(buf, "#", sizeof(buf));
mqttClient.subscribe(buf); mqttClient.subscribe(buf);
//restoreState(); //restoreState();
@@ -431,18 +329,18 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
} }
case 4: //retaining ... Collecting case 4: //retaining ... Collecting
if (millis() > lanCheck) { if (millis() > lanCheck) {
char buf[topiclen]; char buf[MQTT_TOPIC_LENGTH];
//Unsubscribe from status topics.. //Unsubscribe from status topics..
strncpy_P(buf,outprefix,sizeof(buf)); strncpy_P(buf, outprefix, sizeof(buf));
strncat(buf,"#",sizeof(buf)); strncat(buf, "#", sizeof(buf));
mqttClient.unsubscribe(buf); mqttClient.unsubscribe(buf);
lanStatus = 3; lanStatus = 3;
Serial.println(F("Accepting commands...")); Serial.println(F("Accepting commands..."));
break; break;
} }
case 3: //operation case 3: //operation
if (!mqttClient.connected()) lanStatus = 2; if (!mqttClient.connected()) lanStatus = 2;
@@ -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) //(char* tokens)
{ {
Serial.println(F("Use the commands: 'help' - this text\n" Serial.println(F("Use the commands: 'help' - this text\n"
@@ -612,29 +509,27 @@ void _handleHelp(int arg_cnt, char **args)
"'kill' - test watchdog")); "'kill' - test watchdog"));
} }
void _kill(int arg_cnt, char **args) { void cmdFunctionKill(int arg_cnt, char **args) {
for (short i = 17; i > 0; i--) { for (short i = 17; i > 0; i--) {
delay(1000); delay(1000);
Serial.println(i); Serial.println(i);
}; };
} }
#define EEPROM_offset 32+6
void applyConfig() { void applyConfig() {
int arrayItemValue, itemsCount;
//DMX out is configured
aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx");
#ifdef _dmxout #ifdef _dmxout
int maxChannels;
aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx");
if (dmxoutArr && aJson.getArraySize(dmxoutArr) == 2) { 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); aJson.getArrayItem(dmxoutArr, 0)->valueint);
Serial.print(F("DMX out started. Channels: ")); Serial.print(F("DMX out started. Channels: "));
Serial.println(arrayItemValue); Serial.println(maxChannels);
} }
#endif #endif
//DMX in is configured
#ifdef _dmxin #ifdef _dmxin
int itemsCount;
dmxArr = aJson.getObjectItem(root, "dmxin"); dmxArr = aJson.getObjectItem(root, "dmxin");
if (dmxArr && (itemsCount = aJson.getArraySize(dmxArr))) { if (dmxArr && (itemsCount = aJson.getArraySize(dmxArr))) {
DMXinSetup(itemsCount * 4); DMXinSetup(itemsCount * 4);
@@ -643,22 +538,38 @@ void applyConfig() {
} }
#endif #endif
items = aJson.getObjectItem(root, "items");
modbusitem = items->child;
inputs = aJson.getObjectItem(root, "in");
#ifdef _modbus #ifdef _modbus
modbusArr = aJson.getObjectItem(root, "modbus"); modbusArr = aJson.getObjectItem(root, "modbus");
#endif #endif
mqttArr = aJson.getObjectItem(root, "mqtt");
#ifdef _owire #ifdef _owire
owArr = aJson.getObjectItem(root, "ow"); owArr = aJson.getObjectItem(root, "ow");
#endif #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 ")); Serial.print(F("items "));
printBool(items); printBool(items);
Serial.print(F("inputs ")); Serial.print(F("inputs "));
@@ -669,27 +580,9 @@ void applyConfig() {
printBool(mqttArr); printBool(mqttArr);
Serial.print(F("1-wire ")); Serial.print(F("1-wire "));
printBool(owArr); 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); loadConfigFromEEPROM(arg_cnt, args);
restoreState(); 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); mqttConfigRequest(arg_cnt, args);
restoreState(); restoreState();
} }
@@ -761,7 +654,7 @@ int mqttConfigResp(char *as) {
return 1; return 1;
} }
void _saveConfigToEEPROM(int arg_cnt, char **args) void cmdFunctionSave(int arg_cnt, char **args)
//(char* tokens) //(char* tokens)
{ {
aJsonEEPROMStream jsonEEPROMStream = aJsonEEPROMStream(EEPROM_offset); 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.print("Got:");
//Serial.println(args[1]); //Serial.println(args[1]);
@@ -792,7 +685,7 @@ void _setMacAddress(int arg_cnt, char **args) {
Serial.println(F("Updated")); Serial.println(F("Updated"));
} }
void _getConfig(int arg_cnt, char **args) { void cmdFunctionGet(int arg_cnt, char **args) {
getConfig(arg_cnt, args); getConfig(arg_cnt, args);
restoreState(); restoreState();
} }
@@ -938,63 +831,27 @@ void postTransmission() {
//modbusSerial.flush(); //modbusSerial.flush();
digitalWrite(TXEnablePin, 0); 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() { void setup_main() {
cmdInit(uint32_t(SERIAL_BAUD)); setupCmdArduino();
printFirmwareVersionAndBuildOptions();
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
#ifdef SD_CARD_INSERTED #ifdef SD_CARD_INSERTED
sd_card_w5100_setup(); sd_card_w5100_setup();
#endif #endif
cmdAdd("help", _handleHelp);
cmdAdd("save", _saveConfigToEEPROM);
cmdAdd("load", _loadConfig);
cmdAdd("get", _getConfig);
cmdAdd("set", _setMacAddress);
cmdAdd("kill", _kill);
cmdAdd("req", _mqttConfigRequest);
#ifdef __ESP__ #ifdef __ESP__
espSetup(); espSetup();
#endif #endif
short macvalid = 0; setupMacAddress();
#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();
loadConfigFromEEPROM(0, NULL); loadConfigFromEEPROM(0, NULL);
#ifdef _modbus #ifdef _modbus
pinMode(TXEnablePin, OUTPUT); pinMode(TXEnablePin, OUTPUT);
modbusSerial.begin(9600); modbusSerial.begin(MODBUS_SERIAL_BAUD);
node.idle(&modbusIdle); node.idle(&modbusIdle);
// Callbacks allow us to configure the RS485 transceiver correctly // Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission); node.preTransmission(preTransmission);
@@ -1002,33 +859,83 @@ void setup_main() {
#endif #endif
delay(20); delay(20);
owReady = 0; owReady = 0;
#ifdef _owire #ifdef _owire
if (net) net->idle(&owIdle); if (net) net->idle(&owIdle);
#endif #endif
//client.setServer(server, 1883); mqttClient.setCallback(mqttCallback);
mqttClient.setCallback(callback);
#ifdef _artnet #ifdef _artnet
ArtnetSetup(); ArtnetSetup();
#endif #endif
#if defined(__SAM3X8E__) //TODO: checkForRemoteSketchUpdate();
// 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 #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() { void loop_main() {
wdt_res(); wdt_res();
//commandLine.update();
cmdPoll(); cmdPoll();
if (lanLoop() > 1) { if (lanLoop() > 1) {
mqttClient.loop(); mqttClient.loop();
@@ -1047,8 +954,6 @@ void loop_main() {
#endif #endif
// if (lastpacket && (lastpacket%10==0)) Serial.println(lastpacket); // if (lastpacket && (lastpacket%10==0)) Serial.println(lastpacket);
#ifdef _modbus #ifdef _modbus
if (modbusArr && items) modbusLoop(); if (modbusArr && items) modbusLoop();
#endif #endif
@@ -1062,19 +967,16 @@ void loop_main() {
#if defined (_espdmx) #if defined (_espdmx)
dmxout.update(); dmxout.update();
#endif #endif
} }
// Idle handlers
void owIdle(void) { void owIdle(void) {
#ifdef _artnet #ifdef _artnet
if (artnet) artnet->read(); if (artnet) artnet->read();
#endif #endif
wdt_res(); wdt_res();
return;/// return; //TODO: unreached code
Serial.print(F("o")); Serial.print(F("o"));
if (lanLoop() == 1) mqttClient.loop(); if (lanLoop() == 1) mqttClient.loop();
//if (owReady) owLoop(); //if (owReady) owLoop();
@@ -1085,14 +987,9 @@ void owIdle(void) {
#if defined (_espdmx) #if defined (_espdmx)
dmxout.update(); dmxout.update();
#endif #endif
//modbusLoop();
} }
void modbusIdle(void) { void modbusIdle(void) {
//Serial.print("m");
wdt_res(); wdt_res();
if (lanLoop() > 1) { if (lanLoop() > 1) {
mqttClient.loop(); mqttClient.loop();
@@ -1101,7 +998,6 @@ void modbusIdle(void) {
#endif #endif
} }
//if (owReady) owLoop();
#ifdef _dmxin #ifdef _dmxin
DMXCheck(); DMXCheck();
#endif #endif
@@ -1109,22 +1005,11 @@ void modbusIdle(void) {
#if defined (_espdmx) #if defined (_espdmx)
dmxout.update(); dmxout.update();
#endif #endif
//modbusloop();
} }
// Loops
void inputLoop(void) { void inputLoop(void) {
if (millis() > nextInputCheck) {
if (millis() > incheck) {
aJsonObject *input = inputs->child; aJsonObject *input = inputs->child;
while (input) { while (input) {
if ((input->type == aJson_Object)) { if ((input->type == aJson_Object)) {
Input in(input); Input in(input);
@@ -1132,35 +1017,31 @@ void inputLoop(void) {
} }
input = input->next; input = input->next;
} }
nextInputCheck = millis() + INTERVAL_CHECK_INPUT;
incheck = millis() + 50;
} }
} }
void modbusLoop(void) { void modbusLoop(void) {
boolean done = false; boolean done = false;
if (millis() > modbuscheck) { if (millis() > nextModbusCheck) {
while (modbusitem && !done) { while (modbusItem && !done) {
if (modbusitem->type == aJson_Array) { if (modbusItem->type == aJson_Array) {
switch (aJson.getArrayItem(modbusitem, 0)->valueint) { switch (aJson.getArrayItem(modbusItem, 0)->valueint) {
case CH_MODBUS: case CH_MODBUS:
//case CH_VCTEMP: //case CH_VCTEMP:
case CH_VC: { case CH_VC: {
Item it(modbusitem); Item it(modbusItem);
it.Poll(); it.Poll();
modbuscheck = millis() + 2000; nextModbusCheck = millis() + INTERVAL_CHECK_MODBUS;
done = true; done = true;
break; //case; break; //case;
} }
} //switch } //switch
}//if }//if
modbusitem = modbusitem->next; modbusItem = modbusItem->next;
if (!modbusitem) { if (!modbusItem) {
modbusitem = items->child; modbusItem = items->child;
return; return;
} //start from 1-st element } //start from 1-st element
} //while } //while
@@ -1168,75 +1049,71 @@ void modbusLoop(void) {
} }
// To be refactored //TODO: refactoring
void thermoLoop(void) { void thermoLoop(void) {
#define T_ATTEMPTS 200 if (millis() < nextThermostatCheck)
#define IET_TEMP 0 return;
#define IET_ATTEMPTS 1
if (millis() > thermocheck) { bool thermostatCheckPrinted = false;
bool thermostatCheckPrinted = false; aJsonObject *item = items->child;
aJsonObject *item = items->child;
while (item) { while (item) {
if ((item->type == aJson_Array) && (aJson.getArrayItem(item, 0)->valueint == CH_THERMO) && if ((item->type == aJson_Array) && (aJson.getArrayItem(item, 0)->valueint == CH_THERMO) &&
(aJson.getArraySize(item) > 4)) { (aJson.getArraySize(item) > 4)) {
int pin = aJson.getArrayItem(item, I_ARG)->valueint; int itemPin = aJson.getArrayItem(item, I_ARG)->valueint;
int temp = aJson.getArrayItem(item, I_VAL)->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; if (itemExtensionArray && (aJson.getArraySize(itemExtensionArray) > 1)) {
int curtemp = aJson.getArrayItem(itemExtensionArray, IET_TEMP)->valueint;
aJsonObject *extArr = aJson.getArrayItem(item, I_EXT); if (!aJson.getArrayItem(itemExtensionArray, IET_ATTEMPTS)->valueint) {
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;
Serial.print(item->name); Serial.print(item->name);
Serial.print(F(" Set:")); Serial.println(F(" Expired"));
Serial.print(temp);
Serial.print(F(" Curtemp:"));
Serial.print(curtemp);
Serial.print(F(" cmd:"));
Serial.print(cmd),
pinMode(pin, OUTPUT); } else {
if (cmd == CMD_OFF || cmd == CMD_HALT || aJson.getArrayItem(extArr, IET_ATTEMPTS)->valueint == 0) { if (!(--aJson.getArrayItem(itemExtensionArray, IET_ATTEMPTS)->valueint))
digitalWrite(pin, LOW); 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")); Serial.println(F(" OFF"));
} else { } //Reached settings
if (curtemp + GIST < temp) { else Serial.println(F(" --")); // Nothing to do
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; nextThermostatCheck = millis() + THERMOSTAT_CHECK_PERIOD;
#ifndef DISABLE_FREERAM_PRINT #ifndef DISABLE_FREERAM_PRINT
(thermostatCheckPrinted) ? Serial.print(F("\nfree:")) : Serial.print(F(" ")); (thermostatCheckPrinted) ? Serial.print(F("\nfree:")) : Serial.print(F(" "));
Serial.print(freeRam()); Serial.print(freeRam());
Serial.print(" "); Serial.print(" ");
#endif #endif
}
} }

View File

@@ -1,56 +1,181 @@
// #include "options.h"
// Created by livello on 13.03.18.
//
#ifndef LIGHTHUB_MAIN_H #ifndef LIGHTHUB_MAIN_H
#define LIGHTHUB_MAIN_H #define LIGHTHUB_MAIN_H
#define TXEnablePin 13
#ifndef SERIAL_BAUD #if defined(__SAM3X8E__)
#define SERIAL_BAUD 115200 #define wdt_res() watchdogReset()
#define wdt_en()
#define wdt_dis()
#endif #endif
#ifndef CUSTOM_FIRMWARE_MAC #if defined(__AVR__)
#define FIRMWARE_MAC {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0} #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 #endif
#include "Arduino.h" #include "Arduino.h"
#include "DallasTemperature.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 watchdogSetup(void);
void callback(char* topic, byte* payload, unsigned int length);
void mqttCallback(char *topic, byte *payload, unsigned int length);
#ifndef __ESP__ #ifndef __ESP__
void printIPAddress(); void printIPAddress();
#endif #endif
void printMACAddress(); void printMACAddress();
void restoreState(); 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 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 applyConfig();
void _loadConfig (int arg_cnt, char **args);
void cmdFunctionLoad(int arg_cnt, char **args);
int loadConfigFromEEPROM(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 mqttConfigRequest(int arg_cnt, char **args);
int mqttConfigResp (char * as);
void _saveConfigToEEPROM(int arg_cnt, char **args); int mqttConfigResp(char *as);
void _setMacAddress(int arg_cnt, char **args);
void _getConfig(int arg_cnt, char **args); void cmdFunctionSave(int arg_cnt, char **args);
void printBool (bool arg);
void saveFlash(short n, char* str); void cmdFunctionSetMac(int arg_cnt, char **args);
void loadFlash(short n, char* str);
int getConfig (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 preTransmission();
void postTransmission(); void postTransmission();
void setup_main(); void setup_main();
void loop_main(); void loop_main();
void owIdle(void); void owIdle(void);
void modbusIdle(void); void modbusIdle(void);
void inputLoop(void); void inputLoop(void);
void modbusLoop(void); void modbusLoop(void);
void thermoLoop(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 #endif //LIGHTHUB_MAIN_H

View File

@@ -3,6 +3,33 @@
#define PIO_SRC_REV v0.99 #define PIO_SRC_REV v0.99
#endif #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 #ifndef OUTTOPIC
#define OUTTOPIC "/myhome/s_out/" #define OUTTOPIC "/myhome/s_out/"
#endif #endif
@@ -55,6 +82,3 @@
#ifndef _dmxout #ifndef _dmxout
#undef _artnet #undef _artnet
#endif #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 e-mail anklimov@gmail.com
*/ */
#define Q(x) #x
#define QUOTE(x) Q(x)
#include <Arduino.h> #include <Arduino.h>
void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0); void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0);
void SetBytes(uint8_t* addr, uint8_t count, char * out); void SetBytes(uint8_t* addr, uint8_t count, char * out);
void SetAddr(char * out, uint8_t* addr); void SetAddr(char * out, uint8_t* addr);

View File

@@ -10,8 +10,8 @@
[platformio] [platformio]
src_dir = lighthub src_dir = lighthub
env_default = env_default =
megaatmega2560 ; megaatmega2560
; due due
; esp8266 ; esp8266
[env:due] [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);