diff --git a/README.md b/README.md index d7b3606..540a153 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,9 @@ platformio device monitor -b 115200 * WIFI_MANAGER_DISABLE //Disable wifi manager for esp8266 * DHT_DISABLE //disable DHT Input support * RESTART_LAN_ON_MQTT_ERRORS //reinit LAN if many mqtt errors occured +* WITH_STREAMING_LIB use streaming libriary for serial debug output otherwise use PrintEx library +* DEVICE_NAME short handy device name which is used instead of mac for download config http://{MY_CONFIG_SERVER}/{DEVICE_NAME}_config.json +* SYSLOG_ENABLE enable UDP SYSLOG support feature(under DEVELOPMENT) that must be configured through config file @@ -176,5 +179,8 @@ platformio device monitor -b 115200 * DHT support enabled * Wifi manager for esp8266 enabled * RESTART_LAN_ON_MQTT_ERRORS disabled +* WITH_STREAMING_LIB disabled +* DEVICE_NAME disabled +* SYSLOG_ENABLE disabled If you've using Arduino IDE to compile & flash firmware, it will use Default options above and you will not able to configure additional compilers options except edit "options.h" file diff --git a/build_flags_mega2560-net.sh b/build_flags_mega2560-net.sh deleted file mode 100644 index 3f2c34c..0000000 --- a/build_flags_mega2560-net.sh +++ /dev/null @@ -1,30 +0,0 @@ -#! /bin/bash -# usage: -# first make your own copy of template -# cp build_flags_template.sh build_flags_ENVNAME.sh -# then edit, change or comment something - export FLAGS="-DMY_CONFIG_SERVER=lazyhome.ru" - #export FLAGS="$FLAGS -DWATCH_DOG_TICKER_DISABLE" - #export FLAGS="$FLAGS -DUSE_1W_PIN=12" - #export FLAGS="$FLAGS -DSD_CARD_INSERTED" - export FLAGS="$FLAGS -DSERIAL_BAUD=115200" - #export FLAGS="$FLAGS -DWiz5500" - #export FLAGS="$FLAGS -DDISABLE_FREERAM_PRINT" - export FLAGS="$FLAGS -DCUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:fe" -# export FLAGS="$FLAGS -DDMX_DISABLE" -# export FLAGS="$FLAGS -DARTNET_ENABLE" -# export FLAGS="$FLAGS -DMODBUS_DISABLE" -# export FLAGS="$FLAGS -DOWIRE_DISABLE" -# export FLAGS="$FLAGS -DAVR_DMXOUT_PIN=18" -# export FLAGS="$FLAGS -DLAN_INIT_DELAY=2000" -# export FLAGS="$FLAGS -DCONTROLLINO" -# export FLAGS="$FLAGS -DESP_WIFI_AP=MYAP" -# export FLAGS="$FLAGS -DESP_WIFI_PWD=MYPWD" -# export FLAGS="$FLAGS -DWIFI_MANAGER_DISABLE" - export FLAGS="$FLAGS -DDHT_DISABLE" -# export FLAGS="$FLAGS -DRESET_PIN=5" -# export FLAGS="$FLAGS -DDHCP_RETRY_INTERVAL=60000" -# export FLAGS="$FLAGS -DRESTART_LAN_ON_MQTT_ERRORS" -# export FLAGS="$FLAGS -DW5500_CS_PIN=53" - export FLAGS="$FLAGS -DPIO_SRC_REV="$(git log --pretty=format:%h_%ad -1 --date=short) - echo $FLAGS diff --git a/build_flags_mega2560.sh b/build_flags_mega2560.sh deleted file mode 100644 index ee99442..0000000 --- a/build_flags_mega2560.sh +++ /dev/null @@ -1,30 +0,0 @@ -#! /bin/bash -# usage: -# first make your own copy of template -# cp build_flags_template.sh build_flags_ENVNAME.sh -# then edit, change or comment something - export FLAGS="-DMY_CONFIG_SERVER=lazyhome.ru" - #export FLAGS="$FLAGS -DWATCH_DOG_TICKER_DISABLE" - #export FLAGS="$FLAGS -DUSE_1W_PIN=12" - #export FLAGS="$FLAGS -DSD_CARD_INSERTED" - export FLAGS="$FLAGS -DSERIAL_BAUD=115200" - #export FLAGS="$FLAGS -DWiz5500" - #export FLAGS="$FLAGS -DDISABLE_FREERAM_PRINT" - export FLAGS="$FLAGS -DCUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:ed" -# export FLAGS="$FLAGS -DDMX_DISABLE" -# export FLAGS="$FLAGS -DARTNET_ENABLE" -# export FLAGS="$FLAGS -DMODBUS_DISABLE" - export FLAGS="$FLAGS -DOWIRE_DISABLE" -# export FLAGS="$FLAGS -DAVR_DMXOUT_PIN=18" -# export FLAGS="$FLAGS -DLAN_INIT_DELAY=2000" -# export FLAGS="$FLAGS -DCONTROLLINO" -# export FLAGS="$FLAGS -DESP_WIFI_AP=MYAP" -# export FLAGS="$FLAGS -DESP_WIFI_PWD=MYPWD" -# export FLAGS="$FLAGS -DWIFI_MANAGER_DISABLE" - export FLAGS="$FLAGS -DDHT_DISABLE" -# export FLAGS="$FLAGS -DRESET_PIN=5" -# export FLAGS="$FLAGS -DDHCP_RETRY_INTERVAL=60000" -# export FLAGS="$FLAGS -DRESTART_LAN_ON_MQTT_ERRORS" -# export FLAGS="$FLAGS -DW5500_CS_PIN=53" - export FLAGS="$FLAGS -DPIO_SRC_REV="$(git log --pretty=format:%h_%ad -1 --date=short) - echo $FLAGS diff --git a/build_flags_template.sh b/build_flags_template.sh index e66e237..86372f0 100644 --- a/build_flags_template.sh +++ b/build_flags_template.sh @@ -25,5 +25,7 @@ # export FLAGS="$FLAGS -DDHCP_RETRY_INTERVAL=60000" # export FLAGS="$FLAGS -DRESTART_LAN_ON_MQTT_ERRORS" # export FLAGS="$FLAGS -DW5500_CS_PIN=53" +#export FLAGS="$FLAGS -DSYSLOG_ENABLE" +#export FLAGS="$FLAGS -DDEVICE_NAME=MYDEVICE" export FLAGS="$FLAGS -DPIO_SRC_REV="$(git log --pretty=format:%h_%ad -1 --date=short) echo $FLAGS diff --git a/lighthub/main.cpp b/lighthub/main.cpp index 5d3fafe..f1a0a23 100644 --- a/lighthub/main.cpp +++ b/lighthub/main.cpp @@ -67,6 +67,14 @@ PWM Out #include "Arduino.h" #include "main.h" #include "options.h" +#include "utils.h" +#ifdef WITH_STREAMING_LIB +#include "Streaming.h" +#else +#include "PrintEx.h" +using namespace ios; +#endif + #if defined(__SAM3X8E__) DueFlashStorage EEPROM; @@ -77,7 +85,7 @@ EthernetClient ethClient; EthernetClient ethClient; #endif -#ifdef ESP8266 +#ifdef ARDUINO_ARCH_ESP8266 #include #include WiFiClient ethClient; @@ -106,8 +114,7 @@ WiFiClient ethClient; EthernetClient ethClient; #endif -#ifndef SYSLOG_DISABLE -//#include +#ifdef SYSLOG_ENABLE #include EthernetUDP udpSyslogClient; Syslog udpSyslog(udpSyslogClient, SYSLOG_PROTO_IETF); @@ -153,51 +160,37 @@ bool wifiInitialized; int mqttErrorRate; -void watchdogSetup(void) { -//Serial.begin(115200); -//debugSerial.println("Watchdog armed."); -} //Do not remove - strong re-definition WDT Init for DUE - - -// MQTT Callback routine - +void watchdogSetup(void) {} //Do not remove - strong re-definition WDT Init for DUE void mqttCallback(char *topic, byte *payload, unsigned int length) { - - debugSerial.print(F("\n[")); - debugSerial.print(topic); - debugSerial.print(F("] ")); + debugSerial< nextLanCheckTime) + onInitialStateInitLAN(); break; case HAVE_IP_ADDRESS: if (!configOk) - lanStatus = getConfig(0, NULL); //got config from server or load from NVRAM + lanStatus = loadConfigFromHttp(0, NULL); else lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER; #ifdef _artnet if (artnet) artnet->begin(); @@ -271,7 +267,7 @@ lan_status lanLoop() { mqttClient.unsubscribe(buf); lanStatus = OPERATION;//3; - debugSerial.println(F("Accepting commands...")); + debugSerial< 0) switch (Ethernet.maintain()) { case NO_LINK: - debugSerial.println(F("No link")); + debugSerial<valuestring; int syslogPort = aJson.getArrayItem(udpSyslogArr, 1)->valueint; char *syslogDeviceHostname = aJson.getArrayItem(udpSyslogArr, 2)->valuestring; char *syslogAppname = aJson.getArrayItem(udpSyslogArr, 3)->valuestring; - debugSerial.println("debugSerial:"); - debugSerial.println(syslogServer); - debugSerial.println(syslogPort); - debugSerial.println(syslogDeviceHostname); - debugSerial.println(syslogAppname); + debugSerial<= 4) user = aJson.getArrayItem(mqttArr, 3)->valuestring; if (!loadFlash(OFFSET_MQTT_PWD, passwordBuf, sizeof(passwordBuf)) && (n >= 5)) { password = aJson.getArrayItem(mqttArr, 4)->valuestring; - debugSerial.println(F("Using MQTT password from config")); + debugSerial<50){ - debugSerial.print(F("Too many MQTT connection errors. Restart LAN")); + debugSerial< 0) { delay(500); wifi_connection_wait -= 500; - debugSerial.print("."); + debugSerial<<"."); } wifiInitialized = true; } #endif -#if defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) +#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) if (WiFi.status() == WL_CONNECTED) { - debugSerial.print(F("WiFi connected. IP address: ")); - debugSerial.println(WiFi.localIP()); + debugSerial<valuestring; if (owEmit) { strncpy(addrbuf, owEmit, sizeof(addrbuf)); - debugSerial.print(owEmit); - debugSerial.print(F("=")); - debugSerial.println(val); + debugSerial<valuestring; - } else debugSerial.println(F("1w-item not found in config")); + } else debugSerial<=1 ) { DMXoutSetup(maxChannels = aJson.getArrayItem(dmxoutArr, 1)->valueint); - //,aJson.getArrayItem(dmxoutArr, 0)->valueint); - debugSerial.print(F("DMX out started. Channels: ")); - debugSerial.println(maxChannels); + debugSerial<child; owReady = owSetup(&Changed); - if (owReady) debugSerial.println(F("One wire Ready")); + if (owReady) debugSerial<type == aJson_Object)) { DeviceAddress addr; - //debugSerial.print(F("Add:")),debugSerial.println(item->name); + //debugSerial<name); SetAddr(item->name, addr); owAdd(addr); } @@ -716,10 +703,7 @@ void applyConfig() { int k; pinMode(pin, OUTPUT); digitalWrite(pin, k = ((cmd == CMD_ON) ? HIGH : LOW)); - debugSerial.print(F("Pin:")); - debugSerial.print(pin); - debugSerial.print(F("=")); - debugSerial.println(k); + debugSerial< 0) { - // HTTP header has been send and Server response header has been handled debugSerial.printf("[HTTP] GET... code: %d\n", httpResponseCode); - // file found at server if (httpResponseCode == HTTP_CODE_OK) { String response = httpClient.getString(); - debugSerial.println(response); + debugSerial<>>")); + debugSerial<<(F(">>>")); cmdAdd("help", cmdFunctionHelp); cmdAdd("save", cmdFunctionSave); cmdAdd("load", cmdFunctionLoad); @@ -1287,7 +1237,7 @@ void setupCmdArduino() { void loop_main() { wdt_res(); cmdPoll(); - if (lanLoop() > 1) { + if (lanLoop() > HAVE_IP_ADDRESS) { mqttClient.loop(); #ifdef _artnet if (artnet) artnet->read(); @@ -1302,7 +1252,6 @@ void loop_main() { // unsigned long lastpacket = DMXSerial.noDataSince(); DMXCheck(); #endif - // if (lastpacket && (lastpacket%10==0)) debugSerial.println(lastpacket); if (items) { #ifndef MODBUS_DISABLE @@ -1320,8 +1269,8 @@ void loop_main() { dmxout.update(); #endif -#ifndef SYSLOG_DISABLE -// debugSerial.print(F("#")); +#ifdef SYSLOG_ENABLE +// debugSerial<valueint; if (!aJson.getArrayItem(thermoExtensionArray, IET_ATTEMPTS)->valueint) { - debugSerial.print(thermoItem->name); - debugSerial.println(F(" Expired")); + debugSerial<name<valueint)) @@ -1445,27 +1389,22 @@ void thermoLoop(void) { if (curTemp > THERMO_OVERHEAT_CELSIUS) mqttClient.publish("/alarm/ovrht", thermoItem->name); - debugSerial.print(thermoItem->name); - debugSerial.print(F(" Set:")); - debugSerial.print(thermoSetting); - debugSerial.print(F(" Cur:")); - debugSerial.print(curTemp); - debugSerial.print(F(" cmd:")); - debugSerial.print(thermoStateCommand); + debugSerial << endl << thermoItem->name << F("Set:") << thermoSetting << F(" Cur:") << curTemp + << F(" cmd:") << thermoStateCommand; pinMode(thermoPin, OUTPUT); if (thermoDisabledOrDisconnected(thermoExtensionArray, thermoStateCommand)) { digitalWrite(thermoPin, LOW); - debugSerial.println(F(" OFF")); + debugSerial<= thermoSetting) { digitalWrite(thermoPin, LOW); - debugSerial.println(F(" OFF")); + debugSerial<valueint == 0) mqttClient.publish("/alarmoff/snsr", thermoItem->name); att->valueint = (int) T_ATTEMPTS; } - } } - } diff --git a/lighthub/main.h b/lighthub/main.h index 5e4f782..e56b11d 100644 --- a/lighthub/main.h +++ b/lighthub/main.h @@ -1,9 +1,6 @@ +#pragma once #include "options.h" -#ifndef LIGHTHUB_MAIN_H -#define LIGHTHUB_MAIN_H - - #if defined(__SAM3X8E__) #define wdt_res() watchdogReset() #define wdt_en() @@ -172,7 +169,7 @@ void applyConfig(); void cmdFunctionLoad(int arg_cnt, char **args); -int loadConfigFromEEPROM(int arg_cnt, char **args); +int loadConfigFromEEPROM(); void cmdFunctionReq(int arg_cnt, char **args); @@ -196,7 +193,7 @@ void saveFlash(short n, IPAddress& ip); int ipLoadFromFlash(short n, IPAddress &ip); -lan_status getConfig(int arg_cnt=0, char **args=NULL); +lan_status loadConfigFromHttp(int arg_cnt = 0, char **args = NULL); void preTransmission(); @@ -238,4 +235,7 @@ void onInitialStateInitLAN(); void ip_ready_config_loaded_connecting_to_broker(); -#endif //LIGHTHUB_MAIN_H +void printCurentLanConfig(); + +void printFreeRam(); + diff --git a/lighthub/options.h b/lighthub/options.h index 00a9fcc..b991274 100644 --- a/lighthub/options.h +++ b/lighthub/options.h @@ -112,9 +112,11 @@ #define dmxin DmxDue1 #endif -#if defined(ESP8266) +#if defined(ARDUINO_ARCH_ESP8266) #undef _dmxin #undef _modbus +#define WITH_STREAMING_LIB + #ifndef DMX_DISABLE #define _espdmx #endif diff --git a/lighthub/owTerm.cpp b/lighthub/owTerm.cpp index adedd89..e2d44d6 100644 --- a/lighthub/owTerm.cpp +++ b/lighthub/owTerm.cpp @@ -47,7 +47,7 @@ int owUpdate() { short sr; //net.setStrongPullup(); - Serial.println(F("Searching")); + debugSerial.println(F("Searching")); if (net) net->reset_search(); for (short i = 0; i < t_count; i++) wstat[i] &= ~SW_FIND; //absent @@ -58,18 +58,18 @@ int owUpdate() { if (!memcmp(term[i], term[t_count], 8)) { ifind = i; wstat[i] |= SW_FIND; - Serial.print(F(" Node:")); - PrintBytes(term[t_count], 8); - Serial.println(F(" alive")); + debugSerial.print(F(" Node:")); + PrintBytes(term[t_count], 8,0); + debugSerial.println(F(" alive")); break; }; //alive if (ifind < 0 && sensors) { wstat[t_count] = SW_FIND; //Newly detected - Serial.print(F("dev#")); - Serial.print(t_count); - Serial.print(F(" Addr:")); - PrintBytes(term[t_count], 8); - Serial.println(); + debugSerial.print(F("dev#")); + debugSerial.print(t_count); + debugSerial.print(F(" Addr:")); + PrintBytes(term[t_count], 8,0); + debugSerial.println(); if (term[t_count][0] == 0x28) { sensors->setResolution(term[t_count], TEMPERATURE_PRECISION); net->setStrongPullup(); @@ -80,8 +80,8 @@ int owUpdate() { }//if } //while - Serial.print(F("1-wire count: ")); - Serial.println(t_count); + debugSerial.print(F("1-wire count: ")); + debugSerial.println(t_count); #endif } @@ -91,12 +91,12 @@ int owSetup(owChangedType owCh) { //// todo - move memory allocation to here if (net) return true; // Already initialized #ifdef DS2482_100_I2C_TO_1W_BRIDGE - Serial.println(F("DS2482_100_I2C_TO_1W_BRIDGE init")); + debugSerial.println(F("DS2482_100_I2C_TO_1W_BRIDGE init")); net = new OneWire; #else - Serial.print(F("One wire setup on PIN:")); - Serial.println(QUOTE(USE_1W_PIN)); -net = new OneWire (USE_1W_PIN); + debugSerial.print(F("One wire setup on PIN:")); + debugSerial.println(QUOTE(USE_1W_PIN)); + net = new OneWire (USE_1W_PIN); #endif @@ -112,29 +112,29 @@ net = new OneWire (USE_1W_PIN); #ifdef DS2482_100_I2C_TO_1W_BRIDGE Wire.begin(); if (net->checkPresence()) { - Serial.println(F("DS2482-100 present")); + debugSerial.println(F("DS2482-100 present")); net->deviceReset(); #ifdef APU_OFF - Serial.println(F("APU off")); + debugSerial.println(F("APU off")); #else net->setActivePullup(); #endif - Serial.println(F("\tChecking for 1-Wire devices...")); + debugSerial.println(F("\tChecking for 1-Wire devices...")); if (net->wireReset()) - Serial.println(F("\tReset done")); + debugSerial.println(F("\tReset done")); sensors->begin(); owChanged = owCh; //owUpdate(); - //Serial.println(F("\t1-w Updated")); + //debugSerial.println(F("\t1-w Updated")); sensors->setWaitForConversion(false); return true; } #endif - Serial.println(F("\tDS2482 error")); + debugSerial.println(F("\tDS2482 error")); return false; // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement @@ -158,7 +158,7 @@ int sensors_loop(void) { case 0x28: // Thermomerer t = sensors->getTempC(term[si]);//*10.0; - //Serial.println("o"); + //debugSerial.println("o"); if (owChanged) owChanged(si, term[si], t); sensors->requestTemperaturesByAddress(term[si]); si++; @@ -192,11 +192,11 @@ void owAdd(DeviceAddress addr) { memcpy(term[t_count], addr, 8); //term[t_count]=addr; - Serial.print(F("dev#")); - Serial.print(t_count); - Serial.print(F(" Addr:")); - PrintBytes(term[t_count], 8); - Serial.println(); + debugSerial.print(F("dev#")); + debugSerial.print(t_count); + debugSerial.print(F(" Addr:")); + PrintBytes(term[t_count], 8,0); + debugSerial.println(); if (term[t_count][0] == 0x28) { sensors->setResolution(term[t_count], TEMPERATURE_PRECISION); net->setStrongPullup(); diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index ac5357e..d959d67 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -19,6 +19,7 @@ e-mail anklimov@gmail.com */ #include "utils.h" +#include "options.h" #if defined(__SAM3X8E__) || defined(ARDUINO_ARCH_STM32F1) #include @@ -134,5 +135,61 @@ void parseBytes(const char *str, char separator, byte *bytes, int maxBytes, int str++; // Point to next character after separator } } + +#define ARDBUFFER 16 //Buffer for storing intermediate strings. Performance may vary depending on size. + +int log(const char *str, ...)//TODO: __FlashStringHelper str support +{ + int i, count=0, j=0, flag=0; + char temp[ARDBUFFER+1]; + for(i=0; str[i]!='\0';i++) if(str[i]=='%') count++; //Evaluate number of arguments required to be printed + + va_list argv; + va_start(argv, count); + for(i=0,j=0; str[i]!='\0';i++) //Iterate over formatting string + { + if(str[i]=='%') + { + //Clear buffer + temp[j] = '\0'; + Serial.print(temp); + j=0; + temp[0] = '\0'; + + //Process argument + switch(str[++i]) + { + case 'd': debugSerial.print(va_arg(argv, int)); + break; + case 'l': debugSerial.print(va_arg(argv, long)); + break; + case 'f': debugSerial.print(va_arg(argv, double)); + break; + case 'c': debugSerial.print((char)va_arg(argv, int)); + break; + case 's': debugSerial.print(va_arg(argv, char *)); + break; + default: ; + }; + } + else + { + //Add to buffer + temp[j] = str[i]; + j = (j+1)%ARDBUFFER; + if(j==0) //If buffer is full, empty buffer. + { + temp[ARDBUFFER] = '\0'; + debugSerial.print(temp); + temp[0]='\0'; + } + } + }; + + Serial.println(); //Print trailing newline + return count + 1; //Return number of arguments detected +} + + #pragma message(VAR_NAME_VALUE(debugSerial)) #pragma message(VAR_NAME_VALUE(SERIAL_BAUD)) \ No newline at end of file diff --git a/lighthub/utils.h b/lighthub/utils.h index 1725b59..4a1945a 100644 --- a/lighthub/utils.h +++ b/lighthub/utils.h @@ -25,10 +25,11 @@ e-mail anklimov@gmail.com #include -void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0); +void PrintBytes(uint8_t* addr, uint8_t count, bool newline); void SetBytes(uint8_t* addr, uint8_t count, char * out); void SetAddr(char * out, uint8_t* addr); uint8_t HEX2DEC(char i); int getInt(char ** chan); unsigned long freeRam (); -void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base); \ No newline at end of file +void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base); +int log(const char *str, ...); \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index f87439d..01596bd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,10 +10,10 @@ [platformio] src_dir = lighthub env_default = - megaatmega2560 +; megaatmega2560 ; megaatmega2560-net ; due -; esp8266 + esp8266 ; esp32 ; megaatmega2560-5500 ; due-5500 @@ -43,6 +43,8 @@ lib_deps = Adafruit Unified Sensor DHT sensor library for ESPx DHT sensor library + Streaming + https://github.com/Chris--A/PrintEx.git [env:stm32] platform = ststm32 @@ -119,6 +121,7 @@ lib_deps = Adafruit Unified Sensor DHT sensor library https://github.com/arcao/Syslog.git + Streaming [env:esp8266] platform = espressif8266 @@ -142,6 +145,8 @@ lib_deps = DHT sensor library WifiManager https://github.com/arcao/Syslog.git + https://github.com/livello/PrintEx.git#is-select-redecl + Streaming [env:megaatmega2560-net] platform = atmelavr @@ -174,6 +179,7 @@ framework = arduino board = due ;lib_ldf_mode = chain+ build_flags = -D Wiz5500 -D ARTNET_ENABLE +build_flags = !sh build_flags_due-5500.sh lib_deps = https://github.com/sebnil/DueFlashStorage https://github.com/anklimov/Arduino-Temperature-Control-Library.git @@ -192,6 +198,9 @@ lib_deps = Adafruit Unified Sensor DHT sensor library https://github.com/arcao/Syslog.git +; Streaming +; PrintEx + https://github.com/livello/PrintEx.git#is-select-redecl [env:controllino] platform = atmelavr