diff --git a/tools/esp8266/.gitignore b/tools/esp8266/.gitignore index 89cc49c..be20b4f 100644 --- a/tools/esp8266/.gitignore +++ b/tools/esp8266/.gitignore @@ -3,3 +3,4 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch +platformio.ini diff --git a/tools/esp8266/app.cpp b/tools/esp8266/app.cpp index c1c3d78..6d92bf3 100644 --- a/tools/esp8266/app.cpp +++ b/tools/esp8266/app.cpp @@ -10,6 +10,9 @@ #include "html/h/setup_html.h" #include "html/h/hoymiles_html.h" +//SD_logger--------------------------------------- +#include +const int chipSelect = 16; //SD-CS pin GPIO16 = D0 //----------------------------------------------------------------------------- app::app() : Main() { @@ -20,6 +23,8 @@ app::app() : Main() { mMqttInterval = MQTT_INTERVAL; mSerialTicker = 0xffff; mSerialInterval = SERIAL_INTERVAL; + mSDlogTicker = 0xffff; + mSDlogInterval = 60; mMqttActive = false; mTicker = 0; @@ -30,6 +35,7 @@ app::app() : Main() { mShowRebootRequest = false; mSerialValues = true; + mSDValues = false; mSerialDebug = false; memset(mPayload, 0, (MAX_NUM_INVERTERS * sizeof(invPayload_t))); @@ -122,6 +128,12 @@ void app::setup(uint32_t timeout) { mSerialDebug = (tmp == 0x01); mSys->Radio.mSerialDebug = mSerialDebug; + // SD logging + mEep->read(ADDR_LOG_INTERVAL, &mSDlogInterval); + mEep->read(ADDR_LOG_ENABLE, &tmp); + mSDValues = (tmp == 0x01); + if (mSDlogInterval < 1) + mSDlogInterval = 1; // mqtt char mqttAddr[MQTT_ADDR_LEN]; @@ -196,6 +208,16 @@ void app::setup(uint32_t timeout) { DPRINTLN(DBG_INFO, F("to configure your device")); DPRINTLN(DBG_INFO, F("----------------------------------------\n")); } + + if(mSDValues == true) + { + if (!SD.begin(chipSelect)) { + DPRINTLN(DBG_INFO, String("SD card failed, or not present")); + // don't do anything more: + return; + } + DPRINTLN(DBG_INFO, String("SD card initialized.")); + } } @@ -309,6 +331,42 @@ void app::loop(void) { } } + if (mSDValues) { + if (++mSDlogTicker >= mSDlogInterval) { + String logFilename = (getDateTimeStr(mTimestamp)); //get current time in format yyyy-mm-dd hh:mm:ss + logFilename.remove(10, 9); //remove hh:mm:ss from yyyy-mm-dd hh:mm:ss including space between dd and hh + logFilename += ".csv"; + File dataFile = SD.open(logFilename, FILE_WRITE); //open or create file on SD card + String logTime = (getDateTimeStr(mTimestamp)); //get current time in format yyyy-mm-dd hh:mm:ss + logTime.remove(0, 11); //remove yyyy-mm-dd from yyyy-mm-dd hh:mm:ss + dataFile.print(logTime); //write timestamp into firs colum in logfile + dataFile.print(","); //write "," to SD card in same line for csv format + mSDlogTicker = 0; + char topic[30], val[10]; + for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { + Inverter<> *iv = mSys->getInverterByPos(id); + if (NULL != iv) { + if (iv->isAvailable(mTimestamp)) { + for (uint8_t i = 0; i < iv->listLen; i++) { + if (0.0f != iv->getValue(i)) { + snprintf(topic, 30, "%s/ch%d/%s", iv->name, iv->assign[i].ch, iv->getFieldName(i)); + dataFile.print(topic); //write to SD card + dataFile.print(","); //write "," to SD card in same line for csv format + snprintf(val, 10, "%.3f %s", iv->getValue(i), iv->getUnit(i)); + dataFile.print(val); //write to SD card + dataFile.print(","); //write "," to SD card in same line for csv format + //DPRINTLN(DBG_INFO, String(topic) + ": " + String(val)); + } + yield(); + } + } + } + } + dataFile.println(" "); //start new line in logfile + dataFile.close(); //close file on SD card + } + } + if(++mSendTicker >= mSendInterval) { mSendTicker = 0; @@ -573,6 +631,11 @@ void app::showSetup(void) { mEep->read(ADDR_SER_DEBUG, &tmp); html.replace(F("{SER_DBG_CB}"), (tmp == 0x01) ? "checked" : ""); + // SD log + mEep->read(ADDR_LOG_ENABLE, &tmp); + html.replace(F("{LOG_INTVL}"), String(mSDlogInterval)); + html.replace(F("{LOG_VAL_CB}"), (tmp == 0x01) ? "checked" : ""); + char mqttAddr[MQTT_ADDR_LEN] = {0}; uint16_t mqttPort; mEep->read(ADDR_MQTT_ADDR, mqttAddr, MQTT_ADDR_LEN); @@ -863,6 +926,12 @@ void app::saveValues(bool webSend = true) { if(mSerialDebug) DPRINTLN(DBG_INFO, "on"); else DPRINTLN(DBG_INFO, "off"); mSys->Radio.mSerialDebug = mSerialDebug; + // SD log + interval = mWeb->arg("logIntvl").toInt(); + mEep->write(ADDR_LOG_INTERVAL, interval); + tmp = (mWeb->arg("logEn") == "on"); + mEep->write(ADDR_LOG_ENABLE, (uint8_t)((tmp) ? 0x01 : 0x00)); + updateCrc(); mEep->commit(); if((mWeb->arg("reboot") == "on")) @@ -962,4 +1031,4 @@ const char* app::getFieldStateClass(uint8_t fieldId) { break; } return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : stateClasses[deviceFieldAssignment[pos].stateClsId]; -} \ No newline at end of file +} diff --git a/tools/esp8266/app.h b/tools/esp8266/app.h index 306cb23..861a93f 100644 --- a/tools/esp8266/app.h +++ b/tools/esp8266/app.h @@ -111,6 +111,7 @@ class app : public Main { // timer uint32_t mTicker; bool mSerialValues; + bool mSDValues; bool mSerialDebug; uint32_t mRxTicker; @@ -125,6 +126,10 @@ class app : public Main { // serial uint16_t mSerialTicker; uint16_t mSerialInterval; + + // SD card + uint16_t mSDlogTicker; + uint16_t mSDlogInterval; }; #endif /*__APP_H__*/ diff --git a/tools/esp8266/defines.h b/tools/esp8266/defines.h index c746930..cc74e79 100644 --- a/tools/esp8266/defines.h +++ b/tools/esp8266/defines.h @@ -69,6 +69,8 @@ typedef struct { #define SER_ENABLE_LEN 1 // uint8_t #define SER_DEBUG_LEN 1 // uint8_t +#define LOG_ENABLE_LEN 1 // uint8_t +#define LOG_INTERVAL_LEN 1 // uint8_t #define SER_INTERVAL_LEN 2 // uint16_t @@ -100,7 +102,9 @@ typedef struct { #define ADDR_SER_ENABLE ADDR_MQTT_PORT + MQTT_PORT_LEN #define ADDR_SER_DEBUG ADDR_SER_ENABLE + SER_ENABLE_LEN #define ADDR_SER_INTERVAL ADDR_SER_DEBUG + SER_DEBUG_LEN -#define ADDR_NEXT ADDR_SER_INTERVAL + SER_INTERVAL_LEN +#define ADDR_LOG_ENABLE ADDR_SER_INTERVAL + SER_INTERVAL_LEN +#define ADDR_LOG_INTERVAL ADDR_LOG_ENABLE + LOG_ENABLE_LEN +#define ADDR_NEXT ADDR_LOG_INTERVAL + LOG_INTERVAL_LEN // #define ADDR_SETTINGS_CRC 950 #define ADDR_SETTINGS_CRC ADDR_NEXT + 2 diff --git a/tools/esp8266/html/h/setup_html.h b/tools/esp8266/html/h/setup_html.h index 22b557a..ade6128 100644 --- a/tools/esp8266/html/h/setup_html.h +++ b/tools/esp8266/html/h/setup_html.h @@ -1,4 +1,4 @@ #ifndef __SETUP_HTML_H__ #define __SETUP_HTML_H__ -const char setup_html[] PROGMEM = "Setup - {DEVICE}

Setup

Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.

WiFi

Device Host Name

ERASE SETTINGS (not WiFi)

Inverter

{INVERTERS}

General

Pinout (Wemos)

{PINOUT}

Radio (NRF24L01+)

MQTT

Serial Console



 

Home

Update Firmware

AHOY - {VERSION}

Factory Reset

Reboot

"; +const char setup_html[] PROGMEM = "Setup - {DEVICE}

Setup

Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.

WiFi

Device Host Name

ERASE SETTINGS (not WiFi)

Inverter

{INVERTERS}

General

Pinout (Wemos)

{PINOUT}

Radio (NRF24L01+)

MQTT

Serial Console



SD card logging


 

Home

Update Firmware

AHOY - {VERSION}

Factory Reset

Reboot

"; #endif /*__SETUP_HTML_H__*/ diff --git a/tools/esp8266/html/setup.html b/tools/esp8266/html/setup.html index 8988ed3..e77965d 100644 --- a/tools/esp8266/html/setup.html +++ b/tools/esp8266/html/setup.html @@ -105,6 +105,12 @@ +

SD card logging

+ +
+ + +

 

diff --git a/tools/esp8266/platformio.ini b/tools/esp8266/platformio.ini index 0728ec4..d524a4a 100644 --- a/tools/esp8266/platformio.ini +++ b/tools/esp8266/platformio.ini @@ -7,6 +7,7 @@ framework = arduino board = d1_mini monitor_speed = 115200 board_build.f_cpu = 80000000L +upload_port = /dev/ttyUSB0 ;build_flags = -DDEBUG_ESP_PORT=Serial lib_deps = @@ -21,17 +22,3 @@ lib_deps = ;esp8266/ESP8266WiFi@^1.0 ;esp8266/SPI@1.0 ;esp8266/Ticker@^1.0 - -[env:node_mcu_v2] -platform = espressif8266 -framework = arduino -board = nodemcuv2 -monitor_speed = 115200 -board_build.f_cpu = 80000000L -upload_port = /dev/ttyUSB0 - -lib_deps = - nrf24/RF24@1.4.2 - paulstoffregen/Time@^1.6.1 - knolleary/PubSubClient@^2.8 - bblanchon/ArduinoJson@^6.19.4