diff --git a/.gitignore b/.gitignore index bebd06e..1c9a165 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,9 @@ .pio .vscode +.vs +*.sln +*.vcxproj* +x64 NerdMinerLog.txt bin/0x10000_firmware.bin logs diff --git a/README.md b/README.md index e38bde5..49158f9 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,9 @@ Every time an stratum job notification is received miner update its current work - LILYGO T-Display S3 AMOLED ([Aliexpress link](https://s.click.aliexpress.com/e/_DmOIK6j)) - LILYGO T-Dongle S3 ([Aliexpress link](https://s.click.aliexpress.com/e/_DmQCPyj)) - ESP32-2432S028R 2,8" ([Aliexpress link](https://s.click.aliexpress.com/e/_DdXkvLv)) +- ESP32-cam [Board Info](https://lastminuteengineers.com/getting-started-with-esp32-cam/) + +* affiliate link ### Flash firmware #### microMiners Flashtool [Recommended] @@ -75,12 +78,32 @@ Update NerdMiner firmware following same flashing steps but only adding 0x10000_ ### NerdMiner configuration After programming, you will only need to setup your Wifi and BTC address. +#### Wifi Accesspoint + 1. Connect to NerdMinerAP - AP: NerdMinerAP - PASS: MineYourCoins 1. Setup your Wifi Network 1. Add your BTCaddress +#### SD card (if available) + +1. Format a SD card using Fat32. +1. Create a file named "config.json" in your card's root containing the the following structure. Adjust the settings to your needs: +{ + "SSID": "myWifiSSID", + "PW": "myWifiPassword", + "PoolUrl": "public-pool.io", + "PoolPort": 21496, + "BtcWallet": "walletID", + "Timezone": 2 +} +1. Insert the SD card. +1. Hold down the "reset configurations" button as described below to reset the configurations and/or boot without settings in your nvmemory. +1. Power down to remove the SD card. It is not needed for mining. + +#### Pool selection + Recommended low difficulty share pools: | Pool URL | Port | Web URL | Status | @@ -99,6 +122,15 @@ Other standard pools not compatible with low difficulty share: | eu.stratum.slushpool.com | 3333 | https://braiins.com/pool | ### Buttons + +#### One button devices: + +- One click > change screen. +- Double click > change screen orientation. +- Tripple click > turn the screen off and on again. +- Hold 5 seconds > **reset the configurations and reboot** your NerdMiner. + +#### Two button devices: With the USB-C port to the right: **TOP BUTTON** diff --git a/lib/TFT_eSPI/Processors/TFT_eSPI_ESP32_S3.h b/lib/TFT_eSPI/Processors/TFT_eSPI_ESP32_S3.h index 4438fe9..f090f24 100644 --- a/lib/TFT_eSPI/Processors/TFT_eSPI_ESP32_S3.h +++ b/lib/TFT_eSPI/Processors/TFT_eSPI_ESP32_S3.h @@ -375,7 +375,7 @@ SPI3_HOST = 2 if ( c & 0x20 ) xset_mask[c] |= (1 << (TFT_D5-MASK_OFFSET)); \ if ( c & 0x40 ) xset_mask[c] |= (1 << (TFT_D6-MASK_OFFSET)); \ if ( c & 0x80 ) xset_mask[c] |= (1 << (TFT_D7-MASK_OFFSET)); \ - } \ + } \ // Mask for the 8 data bits to set pin directions #define GPIO_DIR_MASK ((1 << (TFT_D0-MASK_OFFSET)) | (1 << (TFT_D1-MASK_OFFSET)) | (1 << (TFT_D2-MASK_OFFSET)) | (1 << (TFT_D3-MASK_OFFSET)) | (1 << (TFT_D4-MASK_OFFSET)) | (1 << (TFT_D5-MASK_OFFSET)) | (1 << (TFT_D6-MASK_OFFSET)) | (1 << (TFT_D7-MASK_OFFSET))) diff --git a/platformio.ini b/platformio.ini index aad639e..0d72395 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,7 +10,7 @@ [platformio] globallib_dir = lib -default_envs = ESP32-2432S028R ;NerminerV2, ESP32-devKitv1, NerminerV2-S3-DONGLE, NerminerV2-S3-AMOLED, NerminerV2-T-QT, NerdminerV2-T-Display_V1, ESP32-2432S028R +default_envs = esp32cam ;ESP32-2432S028R, NerminerV2, ESP32-devKitv1, NerminerV2-S3-DONGLE, NerminerV2-S3-AMOLED, NerminerV2-T-QT, NerdminerV2-T-Display_V1, ESP32-2432S028R [env:NerminerV2] platform = espressif32 @@ -23,13 +23,11 @@ monitor_filters = board_build.arduino.memory_type = qio_opi monitor_speed = 115200 upload_speed = 115200 - # 2 x 4.5MB app, 6.875MB SPIFFS ;board_build.partitions = large_spiffs_16MB.csv ;board_build.partitions = default_8MB.csv board_build.partitions = huge_app.csv ;board_build.partitions = default.csv - build_flags = -D LV_LVGL_H_INCLUDE_SIMPLE -D BOARD_HAS_PSRAM @@ -45,7 +43,6 @@ lib_deps = arduino-libraries/NTPClient ;https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4 - [env:ESP32-devKitv1] platform = espressif32 board = esp32dev @@ -57,10 +54,8 @@ monitor_filters = ;board_build.arduino.memory_type = qio_opi monitor_speed = 115200 upload_speed = 115200 - # 2 x 4.5MB app, 6.875MB SPIFFS board_build.partitions = huge_app.csv - build_flags = -D DEVKITV1=1 ;-D DEBUG_MINING=1 @@ -71,7 +66,6 @@ lib_deps = mathertel/OneButton @ ^2.0.3 arduino-libraries/NTPClient - [env:TTGO-T-Display] platform = espressif32 board = esp32dev ;esp-wrover-kit @@ -83,11 +77,8 @@ monitor_filters = board_build.arduino.memory_type = qio_opi monitor_speed = 115200 upload_speed = 115200 - - # 2 x 4.5MB app, 6.875MB SPIFFS board_build.partitions = huge_app.csv - build_flags = ;-D DEBUG_MINING=1 -D TDISPLAY=1 @@ -103,9 +94,7 @@ lib_deps = platform = espressif32 board = lilygo-t-amoled framework = arduino - board_build.partitions = huge_app.csv - build_flags = -DNERMINER_S3_AMOLED -DBOARD_HAS_PSRAM @@ -122,9 +111,7 @@ lib_deps = platform = espressif32 board = esp32-s3-devkitc-1 framework = arduino - board_build.partitions = huge_app.csv - build_flags = -DNERMINER_S3_DONGLE -DBOARD_HAS_PSRAM @@ -135,8 +122,31 @@ lib_deps = https://github.com/tzapu/WiFiManager.git mathertel/OneButton @ ^2.0.3 arduino-libraries/NTPClient - https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4 https://github.com/FastLED/FastLED + ;https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4 + +[env:esp32cam] +platform = espressif32 ;(ESP32-D0WD-V3) +board = esp32cam +framework = arduino +monitor_filters = + esp32_exception_decoder + time + log2file +monitor_speed = 115200 +upload_speed = 921600 +board_build.partitions = huge_app.csv +build_flags = + -D ESP32_CAM + -D MONITOR_SPEED=${this.monitor_speed} +lib_deps = + ;https://github.com/takkaO/OpenFontRender + bblanchon/ArduinoJson@^6.21.2 + https://github.com/tzapu/WiFiManager.git + mathertel/OneButton @ ^2.0.3 + arduino-libraries/NTPClient +lib_ignore = + TFT_eSPI [env:NerminerV2-T-QT] platform = espressif32 diff --git a/src/NerdMinerV2.ino.cpp b/src/NerdMinerV2.ino.cpp index 94e802f..8144dcf 100644 --- a/src/NerdMinerV2.ino.cpp +++ b/src/NerdMinerV2.ino.cpp @@ -10,7 +10,7 @@ #include "wManager.h" #include "mining.h" #include "monitor.h" -#include "drivers/display.h" +#include "drivers/displays/display.h" //3 seconds WDT #define WDT_TIMEOUT 3 @@ -38,7 +38,12 @@ const char* ntpServer = "pool.ntp.org"; /********* INIT *****/ void setup() { - Serial.begin(115200); +#ifdef MONITOR_SPEED + Serial.begin(MONITOR_SPEED); +#else + Serial.begin(115200); +#endif //MONITOR_SPEED + Serial.setTimeout(0); delay(100); @@ -52,7 +57,8 @@ void setup() button1.setPressTicks(5000); button1.attachClick(switchToNextScreen); button1.attachDoubleClick(alternateScreenRotation); - button1.attachLongPressStart(reset_configurations); + button1.attachLongPressStart(reset_configuration); + if(button1.getNumberClicks() == 3) alternateScreenState(); #endif #if defined(PIN_BUTTON_1) && defined(PIN_BUTTON_2) //Button 1 of two button device @@ -64,7 +70,7 @@ void setup() #if defined(PIN_BUTTON_2) //Button 2 of two button device button2.setPressTicks(5000); button2.attachClick(switchToNextScreen); - button2.attachLongPressStart(reset_configurations); + button2.attachLongPressStart(reset_configuration); #endif /******** INIT NERDMINER ************/ diff --git a/src/drivers/devices/device.h b/src/drivers/devices/device.h new file mode 100644 index 0000000..a1c74a8 --- /dev/null +++ b/src/drivers/devices/device.h @@ -0,0 +1,27 @@ +#ifndef __DEVICE_H__ +#define __DEVICE_H__ + +#if defined(NERDMINERV2) +#include "devices/nerdMinerV2.h" +#elif defined(DEVKITV1) +#include "devices/esp32DevKit.h" +#elif defined(TDISPLAY) +#include "devices/lilygoS3TDisplay.h" +#elif defined(NERMINER_S3_AMOLED) +#include "devices/lilygoS3Amoled.h" +#elif defined(NERMINER_S3_DONGLE) +#include "devices/lilygoS3Dongle.h" +#elif defined(ESP32_2432S028R) +#include "devices/esp322432s028r.h" +#elif defined(NERMINER_T_QT) +#include "devices/lilygoT_QT.h" +#elif defined(NERDMINER_T_DISPLAY_V1) +#include "devices/lilygoV1TDisplay.h" +#elif defined(ESP32_CAM) +#include "esp32CAM.h" + +#else +#error "No device defined" +#endif + +#endif // __DEVICE_H__ \ No newline at end of file diff --git a/src/drivers/devices/esp32CAM.h b/src/drivers/devices/esp32CAM.h new file mode 100644 index 0000000..54d7460 --- /dev/null +++ b/src/drivers/devices/esp32CAM.h @@ -0,0 +1,18 @@ +#ifndef _ESP32CAM_H_ +#define _ESP32CAM_H_ + +#define PIN_BUTTON_1 0 +#define LED_PIN 33 + +#define NO_DISPLAY + +// SDMMC interface: 1-bit mode (might cause issues): +#define SDMMC_CLK 14 +#define SDMMC_CMD 15 +#define SDMMC_D0 2 +// additional defines to enable 4-bit mode +#define SDMMC_D1 4 +#define SDMMC_D2 12 +#define SDMMC_D3 13 + +#endif // _ESP32_CAM_H_ diff --git a/src/drivers/displays/amoledDisplayDriver.cpp b/src/drivers/displays/amoledDisplayDriver.cpp index c0eae8b..4abc576 100644 --- a/src/drivers/displays/amoledDisplayDriver.cpp +++ b/src/drivers/displays/amoledDisplayDriver.cpp @@ -1,4 +1,4 @@ -#include "../drivers.h" +#include "DisplayDriver.h" #ifdef AMOLED_DISPLAY diff --git a/src/drivers/display.cpp b/src/drivers/displays/display.cpp similarity index 100% rename from src/drivers/display.cpp rename to src/drivers/displays/display.cpp diff --git a/src/drivers/display.h b/src/drivers/displays/display.h similarity index 94% rename from src/drivers/display.h rename to src/drivers/displays/display.h index 331ea95..2a4a469 100644 --- a/src/drivers/display.h +++ b/src/drivers/displays/display.h @@ -1,7 +1,7 @@ #ifndef DISPLAY_H #define DISPLAY_H -#include "drivers.h" +#include "DisplayDriver.h" extern DisplayDriver *currentDisplayDriver; diff --git a/src/drivers/drivers.h b/src/drivers/displays/displayDriver.h similarity index 73% rename from src/drivers/drivers.h rename to src/drivers/displays/displayDriver.h index 9897db0..939b00c 100644 --- a/src/drivers/drivers.h +++ b/src/drivers/displays/displayDriver.h @@ -1,26 +1,7 @@ -#ifndef DRIVERS_H -#define DRIVERS_H +#ifndef DISPLAYDRIVER_H_ +#define DISPLAYDRIVER_H_ -#if defined(NERDMINERV2) -#include "devices/nerdMinerV2.h" -#elif defined(DEVKITV1) -#include "devices/esp32DevKit.h" -#elif defined(TDISPLAY) -#include "devices/lilygoS3TDisplay.h" -#elif defined(NERMINER_S3_AMOLED) -#include "devices/lilygoS3Amoled.h" -#elif defined(NERMINER_S3_DONGLE) -#include "devices/lilygoS3Dongle.h" -#elif defined(ESP32_2432S028R) -#include "devices/esp322432s028r.h" -#elif defined(NERMINER_T_QT) -#include "devices/lilygoT_QT.h" -#elif defined(NERDMINER_T_DISPLAY_V1) -#include "devices/lilygoV1TDisplay.h" - -#else -#error "No device defined" -#endif +#include "..\devices\device.h" typedef void (*AlternateFunction)(void); typedef void (*DriverInitFunction)(void); @@ -57,4 +38,4 @@ extern DisplayDriver tDisplayV1Driver; #define SCREENS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -#endif // DRIVERS_H +#endif // DISPLAYDRIVER_H_ diff --git a/src/drivers/displays/dongleDisplayDriver.cpp b/src/drivers/displays/dongleDisplayDriver.cpp index 2ba6356..f6b4fe0 100644 --- a/src/drivers/displays/dongleDisplayDriver.cpp +++ b/src/drivers/displays/dongleDisplayDriver.cpp @@ -1,4 +1,4 @@ -#include "../drivers.h" +#include "DisplayDriver.h" #ifdef DONGLE_DISPLAY @@ -45,15 +45,15 @@ extern monitor_data mMonitor; int32_t x = 8, y = 8; \ background.setTextSize(1); \ background.setTextFont(FONT2); \ - \ + \ background.setTextColor(KEY_COLOR); \ - \ + \ render.setFontSize(18); #define CLEAR_SCREEN() \ RESET_SCREEN(); \ background.fillRect(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT, BACK_COLOR); \ - \ + \ #define PRINT_STR(str) \ diff --git a/src/drivers/displays/noDisplayDriver.cpp b/src/drivers/displays/noDisplayDriver.cpp index 23a74bd..636cf81 100644 --- a/src/drivers/displays/noDisplayDriver.cpp +++ b/src/drivers/displays/noDisplayDriver.cpp @@ -1,4 +1,4 @@ -#include "../drivers.h" +#include "DisplayDriver.h" #ifdef NO_DISPLAY diff --git a/src/drivers/displays/tDisplayDriver.cpp b/src/drivers/displays/tDisplayDriver.cpp index 6eb454b..76eede4 100644 --- a/src/drivers/displays/tDisplayDriver.cpp +++ b/src/drivers/displays/tDisplayDriver.cpp @@ -1,4 +1,4 @@ -#include "../drivers.h" +#include "DisplayDriver.h" #ifdef T_DISPLAY diff --git a/src/drivers/storage/SDCard.h b/src/drivers/storage/SDCard.h new file mode 100644 index 0000000..1bcdf65 --- /dev/null +++ b/src/drivers/storage/SDCard.h @@ -0,0 +1,187 @@ +#ifndef _SDCARD_H_ +#define _SDCARD_H_ + +#if defined (SDMMC_D0) && defined (SDMMC_D1) && defined (SDMMC_D2) && defined (SDMMC_D3) +#define BUILD_SDMMC_4 +#include +#elif defined (SDMMC_D0) && !(defined (SDMMC_D1) && defined (SDMMC_D2) && defined (SDMMC_D3)) +#define BUILD_SDMMC_1 +#include +#else +#warning SD card support disabled! +#endif + +#include +#include + +#include "..\devices\device.h" +#include "storage.h" +#include "nvMemory.h" + +// Handles the transfer of settings from sd card to nv memory (wifi credentials are handled by wifimanager) +class SDCard +{ +public: + SDCard(); + ~SDCard(); + void SD2nvMemory(nvMemory* nvMem); + bool loadConfigFile(TSettings* Settings); +private: + bool initSDcard(); + void unmount(); + +#if defined (BUILD_SDMMC_1) || defined(BUILD_SDMMC_4) + fs::SDMMCFS* iSD_; +#elif defined (BUILD_SDSPI) +#error You chose to run the SD card in SPI mode. This is not implemented yet. + fs::SDFS* iSD_; +#endif +}; + + +#if defined (BUILD_SDMMC_1) || defined(BUILD_SDMMC_4) || defined (BUILD_SDSPI) + +SDCard::SDCard() +{ +#if defined (BUILD_SDMMC_1) || defined(BUILD_SDMMC_4) + iSD_ = &SD_MMC; +#elif defined (BUILD_SDSPI) +#error You chose to run the sd card in SPI mode. This is not implemented yet. +#endif +} + +SDCard::~SDCard() +{ + unmount(); +} + +void SDCard::SD2nvMemory(nvMemory* nvMem) +{ + TSettings Settings; + if (loadConfigFile(&Settings)) + { + nvMem->saveConfig(&Settings); + WiFi.begin(Settings.WifiSSID, Settings.WifiPW); + Serial.println("SDCard: Settings transfered to internal memory. Restarting now."); + ESP.restart(); + } +} + +bool SDCard::loadConfigFile(TSettings* Settings) +{ + // Load existing configuration file + // Read configuration from FS json + + if (initSDcard()) + { + if (iSD_->exists(JSON_CONFIG_FILE)) + { + // The file exists, reading and loading + File configFile = iSD_->open(JSON_CONFIG_FILE, "r"); + if (configFile) + { + StaticJsonDocument<512> json; + DeserializationError error = deserializeJson(json, configFile); + configFile.close(); + Serial.println("SDCard: Loading config file"); + serializeJsonPretty(json, Serial); + Serial.print('\n'); + unmount(); + if (!error) + { + strcpy(Settings->WifiSSID, json[JSON_KEY_SSID] | Settings->WifiSSID); + strcpy(Settings->WifiPW, json[JSON_KEY_PASW] | Settings->WifiPW); + strcpy(Settings->PoolAddress, json[JSON_KEY_POOLURL] | Settings->PoolAddress); + strcpy(Settings->BtcWallet, json[JSON_KEY_WALLETID] | Settings->BtcWallet); + if (json.containsKey(JSON_KEY_POOLPORT)) + Settings->PoolPort = json[JSON_KEY_POOLPORT].as(); + if (json.containsKey(JSON_KEY_TIMEZONE)) + Settings->Timezone = json[JSON_KEY_TIMEZONE].as(); + return true; + } + else + { + // Error loading JSON data + Serial.println("SDCard: Error parsing config file!"); + } + } + else + { + Serial.println("SDCard: Error opening config file!"); + } + } + else + { + Serial.println("SDCard: No config file available!"); + } + unmount(); + } + return false; +} + +void SDCard::unmount() +{ + iSD_->end(); + Serial.println("SDCard: Unmounted"); +} + +bool SDCard::initSDcard() +{ + if(iSD_->cardType() != CARD_NONE) + { + Serial.println("SDCard: Already mounted."); + return true; + } + Serial.println("SDCard: Mounting card."); + + bool cardInitialized = false; +#if defined (BUILD_SDMMC_4) + if (iSD_->cardType() == CARD_NONE) + { + iSD_->setPins(SDMMC_CLK, SDMMC_CMD, SDMMC_D0, SDMMC_D1, SDMMC_D2, SDMMC_D3); + Serial.println("SDCard: 4-Bit Mode."); + cardInitialized = iSD_->begin("/sd", false); + } +#elif defined (BUILD_SDMMC_1) +#warning SDMMC: 1-bit mode is not always working. If you experience issues, try other modes. + if (iSD_->cardType() == CARD_NONE) + { + iSD_->setPins(SDMMC_CLK, SDMMC_CMD, SDMMC_D0); + Serial.println("SDCard: 1-Bit Mode."); + cardInitialized = iSD_->begin("/sd", true); + } +#elif defined (BUILD_SDSPI) +#error You chose to run the sd card in SPI mode. This is not implemented yet. +#else + Serial.println("SDCard: interface not available."); + return false; +#endif // dataPinsDefined + if (cardInitialized) + { + if(iSD_->cardType() != CARD_NONE) + { + Serial.println("SDCard: Mounted."); + return true; + } + else + { + Serial.println("SDCard: Mounting failed."); + iSD_->end(); + } + } + return false; +} + +#else + +SDCard::SDCard() {} +SDCard::~SDCard() {} +void SDCard::SD2nvMemory(nvMemory* nvMem) {}; +bool SDCard::loadConfigFile(TSettings* Settings) { return false; } +bool SDCard::initSDcard() { return false; } +void unmount() {} + +#endif //BUILD_SDMMC + + +#endif // _SDCARD_H_ diff --git a/src/drivers/storage/nvMemory.h b/src/drivers/storage/nvMemory.h new file mode 100644 index 0000000..e2ea2c4 --- /dev/null +++ b/src/drivers/storage/nvMemory.h @@ -0,0 +1,171 @@ +#ifndef _NVMEMORY_H_ +#define _NVMEMORY_H_ + +// we only have one implementation right now and nothing to choose from. +#define NVMEM_SPIFFS + +#include "..\devices\device.h" +#include "storage.h" + +// Handles load and store of user settings, except wifi credentials. Those are managed by the wifimanager. +class nvMemory +{ +public: + nvMemory(); + ~nvMemory(); + bool saveConfig(TSettings* Settings); + bool loadConfig(TSettings* Settings); + bool deleteConfig(); +private: + bool init(); + bool Initialized_; +}; + +#ifdef NVMEM_SPIFFS + +#define ESP_DRD_USE_SPIFFS true + +#include +#include +#include + +nvMemory::nvMemory() +{ + Initialized_ = false; +} + +nvMemory::~nvMemory() +{ + if (Initialized_) + SPIFFS.end(); +}; + +bool nvMemory::saveConfig(TSettings* Settings) +{ + if (init()) + { + // Save Config in JSON format + Serial.println(F("SPIFS: Saving configuration.")); + + // Create a JSON document + StaticJsonDocument<512> json; + json[JSON_KEY_POOLURL] = Settings->PoolAddress; + json[JSON_KEY_POOLPORT] = Settings->PoolPort; + json[JSON_KEY_WALLETID] = Settings->BtcWallet; + json[JSON_KEY_TIMEZONE] = Settings->Timezone; + json[JSON_KEY_TIMEZONE] = Settings->saveStats; + + // Open config file + File configFile = SPIFFS.open(JSON_CONFIG_FILE, "w"); + if (!configFile) + { + // Error, file did not open + Serial.println("SPIFS: Failed to open config file for writing"); + return false; + } + + // Serialize JSON data to write to file + serializeJsonPretty(json, Serial); + Serial.print('\n'); + if (serializeJson(json, configFile) == 0) + { + // Error writing file + Serial.println(F("SPIFS: Failed to write to file")); + return false; + } + // Close file + configFile.close(); + return true; + }; + return false; +} + +bool nvMemory::loadConfig(TSettings* Settings) +{ + // Uncomment if we need to format filesystem + // SPIFFS.format(); + + // Load existing configuration file + // Read configuration from FS json + + if (init()) + { + if (SPIFFS.exists(JSON_CONFIG_FILE)) + { + // The file exists, reading and loading + File configFile = SPIFFS.open(JSON_CONFIG_FILE, "r"); + if (configFile) + { + Serial.println("SPIFS: Loading config file"); + StaticJsonDocument<512> json; + DeserializationError error = deserializeJson(json, configFile); + configFile.close(); + serializeJsonPretty(json, Serial); + Serial.print('\n'); + if (!error) + { + strcpy(Settings->PoolAddress, json[JSON_KEY_POOLURL] | Settings->PoolAddress); + strcpy(Settings->BtcWallet, json[JSON_KEY_WALLETID] | Settings->BtcWallet); + if (json.containsKey(JSON_KEY_POOLPORT)) + Settings->PoolPort = json[JSON_KEY_POOLPORT].as(); + if (json.containsKey(JSON_KEY_TIMEZONE)) + Settings->Timezone = json[JSON_KEY_TIMEZONE].as(); + if (json.containsKey(JSON_KEY_STATS2NV)) + Settings->saveStats = json[JSON_KEY_STATS2NV].as(); + return true; + } + else + { + // Error loading JSON data + Serial.println("SPIFS: Error parsing config file!"); + } + } + else + { + Serial.println("SPIFS: Error opening config file!"); + } + } + else + { + Serial.println("SPIFS: No config file available!"); + } + } + return false; +} + +bool nvMemory::deleteConfig() +{ + Serial.println("SPIFS: Erasing config file.."); + return SPIFFS.remove(JSON_CONFIG_FILE); //Borramos fichero +} + +bool nvMemory::init() +{ + if (!Initialized_) + { + Serial.println("SPIFS: Mounting File System..."); + // May need to make it begin(true) first time you are using SPIFFS + Initialized_ = SPIFFS.begin(false) || SPIFFS.begin(true); + Initialized_ ? Serial.println("SPIFS: Mounted") : Serial.println("SPIFS: Mounting failed."); + } + else + { + Serial.println("SPIFS: Already Mounted"); + } + return Initialized_; +}; + +#else +#error We need some kind of permanent storage implementation! + +nvMemory::nvMemory() {} +nvMemory::~nvMemory() {} +bool nvMemory::saveConfig(TSettings* Settings) { return false; } +bool nvMemory::loadConfig(TSettings* Settings) { return false; } +bool nvMemory::deleteConfig() { return false; } +bool nvMemory::init() { return false; } + + +#endif //NVMEM_TYPE + +#endif // _NVMEMORY_H_ diff --git a/src/drivers/storage/storage.h b/src/drivers/storage/storage.h new file mode 100644 index 0000000..348b1b7 --- /dev/null +++ b/src/drivers/storage/storage.h @@ -0,0 +1,33 @@ +#ifndef _STORAGE_H_ +#define _STORAGE_H_ + +#define DEFAULT_SSID "NMAP" +#define DEFAULT_WIFIPW "1234567890" +#define DEFAULT_POOLURL "public-pool.io" +#define DEFAULT_WALLETID "yourBtcAddress" +#define DEFAULT_POOLPORT 21496 +#define DEFAULT_TIMEZONE 2 +#define DEFAULT_SAVESTATS false + +// JSON config file +#define JSON_CONFIG_FILE "/config.json" +#define JSON_KEY_SSID "SSID" +#define JSON_KEY_PASW "PW" +#define JSON_KEY_POOLURL "PoolUrl" +#define JSON_KEY_WALLETID "BtcWallet" +#define JSON_KEY_POOLPORT "PoolPort" +#define JSON_KEY_TIMEZONE "Timezone" +#define JSON_KEY_STATS2NV "saveStatsToNVS" + +struct TSettings +{ + char WifiSSID[80]{ DEFAULT_SSID }; + char WifiPW[80]{ DEFAULT_WIFIPW }; + char PoolAddress[80]{ DEFAULT_POOLURL }; + char BtcWallet[80]{ DEFAULT_WALLETID }; + uint32_t PoolPort{ DEFAULT_POOLPORT }; + uint32_t Timezone{ DEFAULT_TIMEZONE }; + bool saveStats{ DEFAULT_SAVESTATS }; +}; + +#endif // _STORAGE_H_ \ No newline at end of file diff --git a/src/mining.cpp b/src/mining.cpp index 9bf3fce..63c1004 100644 --- a/src/mining.cpp +++ b/src/mining.cpp @@ -10,7 +10,8 @@ #include "mining.h" #include "utils.h" #include "monitor.h" -#include "drivers/display.h" +#include "drivers/displays/display.h" +#include "drivers/storage/storage.h" nvs_handle_t stat_handle; @@ -28,11 +29,12 @@ uint32_t valids; // increased if blockhash <= target double best_diff = 0.0; // Variables to hold data from custom textboxes -extern char poolString[80]; -extern int portNumber; -extern char btcString[80]; +extern TSettings Settings; + IPAddress serverIP(1, 1, 1, 1); //Temporally save poolIPaddres -extern bool saveStatsToNVS; //Track mining stats in non volatile memory + +//Track mining stats in non volatile memory +extern TSettings Settings; //Global work data static WiFiClient client; @@ -59,14 +61,14 @@ bool checkPoolConnection(void) { //Resolve first time pool DNS and save IP if(serverIP == IPAddress(1,1,1,1)) { - WiFi.hostByName(poolString, serverIP); + WiFi.hostByName(Settings.PoolAddress, serverIP); Serial.printf("Resolved DNS and save ip (first time) got: %s\n", serverIP.toString()); } //Try connecting pool IP - if (!client.connect(serverIP, portNumber)) { - Serial.println("Imposible to connect to : " + String(poolString)); - WiFi.hostByName(poolString, serverIP); + if (!client.connect(serverIP, Settings.PoolPort)) { + Serial.println("Imposible to connect to : " + String(Settings.PoolAddress)); + WiFi.hostByName(Settings.PoolAddress, serverIP); Serial.printf("Resolved DNS got: %s\n", serverIP.toString()); vTaskDelay(1000 / portTICK_PERIOD_MS); return false; @@ -166,7 +168,7 @@ void runStratumWorker(void *name) { continue; } - strcpy(mWorker.wName, btcString); + strcpy(mWorker.wName, Settings.BtcWallet); strcpy(mWorker.wPass, "x"); // STEP 2: Pool authorize work (Block Info) tx_mining_auth(client, mWorker.wName, mWorker.wPass); //Don't verifies authoritzation, TODO @@ -386,7 +388,7 @@ void runMiner(void * task_id) { #define REDRAW_EVERY 10 void restoreStat() { - if(!saveStatsToNVS) return; + if(!Settings.saveStats) return; esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { Serial.printf("[MONITOR] NVS partition is full or has invalid version, erasing...\n"); @@ -405,7 +407,7 @@ void restoreStat() { } void saveStat() { - if(!saveStatsToNVS) return; + if(!Settings.saveStats) return; Serial.printf("[MONITOR] Saving stats\n"); nvs_set_blob(stat_handle, "best_diff", &best_diff, sizeof(double)); nvs_set_u32(stat_handle, "Mhashes", Mhashes); @@ -447,8 +449,8 @@ void runMonitor(void *name) if (elapsedKHs == 0) { Serial.printf(">>> [i] Miner: newJob>%s / inRun>%s) - Client: connected>%s / subscribed>%s / wificonnected>%s\n", - mMiner.newJob ? "true" : "false", mMiner.inRun ? "true" : "false", - client.connected() ? "true" : "false", isMinerSuscribed ? "true" : "false", WiFi.status() == WL_CONNECTED ? "true" : "false"); + mMiner.newJob ? "true" : "false", mMiner.inRun ? "true" : "false", + client.connected() ? "true" : "false", isMinerSuscribed ? "true" : "false", WiFi.status() == WL_CONNECTED ? "true" : "false"); } #ifdef DEBUG_MEMORY diff --git a/src/monitor.cpp b/src/monitor.cpp index 34e6976..4b33a00 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -7,8 +7,8 @@ #include "mining.h" #include "utils.h" #include "monitor.h" +#include "drivers/storage/storage.h" -extern char poolString[80]; extern uint32_t templates; extern uint32_t hashes; extern uint32_t Mhashes; @@ -23,7 +23,7 @@ extern double best_diff; // track best diff extern monitor_data mMonitor; -extern int GMTzone; //Gotten from saved config +extern TSettings Settings; //Gotten from saved config WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); @@ -39,7 +39,7 @@ void setup_monitor(void){ // Adjust offset depending on your zone // GMT +2 in seconds (zona horaria de Europa Central) - timeClient.setTimeOffset(3600 * GMTzone); + timeClient.setTimeOffset(3600 * Settings.Timezone); Serial.println("TimeClient setup done"); } @@ -171,7 +171,6 @@ unsigned long mTriggerUpdate = 0; unsigned long initialMillis = millis(); unsigned long initialTime = 0; unsigned long mPoolUpdate = 0; -extern char btcString[80]; void getTime(unsigned long* currentHours, unsigned long* currentMinutes, unsigned long* currentSeconds){ @@ -296,7 +295,7 @@ pool_data updatePoolData(void){ HTTPClient http; http.setReuse(true); try { - http.begin(String(getPublicPool)+btcString); + http.begin(String(getPublicPool)+ Settings.BtcWallet); int httpCode = http.GET(); if (httpCode > 0) { diff --git a/src/wManager.cpp b/src/wManager.cpp index 1e94ae4..4906ae9 100644 --- a/src/wManager.cpp +++ b/src/wManager.cpp @@ -1,221 +1,148 @@ -#define ESP_DRD_USE_SPIFFS true // Include Libraries //#include ".h" #include -#include -#include #include -#include + #include "wManager.h" #include "monitor.h" -#include "drivers/display.h" +#include "drivers/displays/display.h" +#include "drivers/storage/SDCard.h" +#include "drivers/storage/nvMemory.h" +#include "drivers/storage/storage.h" -// JSON configuration file -#define JSON_CONFIG_FILE "/config.json" // Flag for saving data bool shouldSaveConfig = false; // Variables to hold data from custom textboxes -char poolString[80] = "public-pool.io"; -int portNumber = 21496;//3333; -char btcString[80] = "yourBtcAddress"; -int GMTzone = 2; //Currently selected in spain -bool saveStatsToNVS = false; //Track mining stats in non volatile memory - +TSettings Settings; // Define WiFiManager Object WiFiManager wm; extern monitor_data mMonitor; -void saveConfigFile() -// Save Config in JSON format -{ - Serial.println(F("Saving configuration...")); - - // Create a JSON document - StaticJsonDocument<512> json; - json["poolString"] = poolString; - json["portNumber"] = portNumber; - json["btcString"] = btcString; - json["gmtZone"] = GMTzone; - json["saveStatsToNVS"] = String(saveStatsToNVS); - - // Open config file - File configFile = SPIFFS.open(JSON_CONFIG_FILE, "w"); - if (!configFile) - { - // Error, file did not open - Serial.println("failed to open config file for writing"); - } - - // Serialize JSON data to write to file - serializeJsonPretty(json, Serial); - if (serializeJson(json, configFile) == 0) - { - // Error writing file - Serial.println(F("Failed to write to file")); - } - // Close file - configFile.close(); -} - -bool loadConfigFile() -// Load existing configuration file -{ - // Uncomment if we need to format filesystem - // SPIFFS.format(); - - // Read configuration from FS json - Serial.println("Mounting File System..."); - - // May need to make it begin(true) first time you are using SPIFFS - if (SPIFFS.begin(false) || SPIFFS.begin(true)) - { - Serial.println("mounted file system"); - if (SPIFFS.exists(JSON_CONFIG_FILE)) - { - // The file exists, reading and loading - Serial.println("reading config file"); - File configFile = SPIFFS.open(JSON_CONFIG_FILE, "r"); - if (configFile) - { - Serial.println("Opened configuration file"); - StaticJsonDocument<512> json; - DeserializationError error = deserializeJson(json, configFile); - configFile.close(); - serializeJsonPretty(json, Serial); - if (!error) - { - Serial.println("Parsing JSON"); - - strcpy(poolString, json["poolString"]); - strcpy(btcString, json["btcString"]); - portNumber = json["portNumber"].as(); - GMTzone = json["gmtZone"].as(); - if(json.containsKey("saveStatsToNVS")) - saveStatsToNVS = json["saveStatsToNVS"].as(); - return true; - } - else - { - // Error loading JSON data - Serial.println("Failed to load json config"); - } - } - } - } - else - { - // Error mounting file system - Serial.println("Failed to mount FS"); - } - - return false; -} - +nvMemory nvMem; void saveConfigCallback() // Callback notifying us of the need to save configuration { - Serial.println("Should save config"); - shouldSaveConfig = true; - //wm.setConfigPortalBlocking(false); + Serial.println("Should save config"); + shouldSaveConfig = true; + //wm.setConfigPortalBlocking(false); } -void configModeCallback(WiFiManager *myWiFiManager) +void configModeCallback(WiFiManager* myWiFiManager) // Called when config mode launched { - Serial.println("Entered Configuration Mode"); + Serial.println("Entered Configuration Mode"); - Serial.print("Config SSID: "); - Serial.println(myWiFiManager->getConfigPortalSSID()); + Serial.print("Config SSID: "); + Serial.println(myWiFiManager->getConfigPortalSSID()); - Serial.print("Config IP Address: "); - Serial.println(WiFi.softAPIP()); + Serial.print("Config IP Address: "); + Serial.println(WiFi.softAPIP()); +} + +void reset_configuration() +{ + Serial.println("Erasing Config, restarting"); + nvMem.deleteConfig(); + wm.resetSettings(); + ESP.restart(); } void init_WifiManager() { - Serial.begin(115200); - //Serial.setTxTimeoutMs(10); +#ifdef MONITOR_SPEED + Serial.begin(MONITOR_SPEED); +#else + Serial.begin(115200); +#endif //MONITOR_SPEED + //Serial.setTxTimeoutMs(10); - //Init pin 15 to eneble 5V external power (LilyGo bug) - #ifdef PIN_ENABLE5V + //Init pin 15 to eneble 5V external power (LilyGo bug) +#ifdef PIN_ENABLE5V pinMode(PIN_ENABLE5V, OUTPUT); digitalWrite(PIN_ENABLE5V, HIGH); - #endif +#endif - // Change to true when testing to force configuration every time we run - bool forceConfig = false; + // Change to true when testing to force configuration every time we run + bool forceConfig = false; - #if defined(PIN_BUTTON_2) +#if defined(PIN_BUTTON_2) // Check if button2 is pressed to enter configMode with actual configuration - if(!digitalRead(PIN_BUTTON_2)){ - Serial.println(F("Button pressed to force start config mode")); - forceConfig = true; - wm.setBreakAfterConfig(true); //Set to detect config edition and save + if (!digitalRead(PIN_BUTTON_2)) { + Serial.println(F("Button pressed to force start config mode")); + forceConfig = true; + wm.setBreakAfterConfig(true); //Set to detect config edition and save } - #endif - - bool spiffsSetup = loadConfigFile(); - if (!spiffsSetup) - { - Serial.println(F("Forcing config mode as there is no saved config")); - forceConfig = true; - - } +#endif + // Explicitly set WiFi mode + WiFi.mode(WIFI_STA); - // Explicitly set WiFi mode - WiFi.mode(WIFI_STA); + if (!nvMem.loadConfig(&Settings)) + { + //No config file on internal flash. + SDCard SDCrd; + if (SDCrd.loadConfigFile(&Settings)) + { + //Config file on SD card. + SDCrd.SD2nvMemory(&nvMem); // reboot on success. + } + else + { + //No config file on SD card. Starting wifi config server. + forceConfig = true; + } + }; - // Reset settings (only for development) - //wm.resetSettings(); + // Reset settings (only for development) + //wm.resetSettings(); - //Set dark theme - //wm.setClass("invert"); // dark theme - - // Set config save notify callback - wm.setSaveConfigCallback(saveConfigCallback); + //Set dark theme + //wm.setClass("invert"); // dark theme - // Set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode - wm.setAPCallback(configModeCallback); + // Set config save notify callback + wm.setSaveConfigCallback(saveConfigCallback); - //Advanced settings - wm.setConfigPortalBlocking(false); //Hacemos que el portal no bloquee el firmware - wm.setConnectTimeout(50); // how long to try to connect for before continuing - //wm.setConfigPortalTimeout(30); // auto close configportal after n seconds - // wm.setCaptivePortalEnable(false); // disable captive portal redirection - // wm.setAPClientCheck(true); // avoid timeout if client connected to softap - //wm.setTimeout(120); - //wm.setConfigPortalTimeout(120); //seconds - - // Custom elements + // Set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode + wm.setAPCallback(configModeCallback); - // Text box (String) - 80 characters maximum - WiFiManagerParameter pool_text_box("Poolurl", "Pool url", poolString, 80); + //Advanced settings + wm.setConfigPortalBlocking(false); //Hacemos que el portal no bloquee el firmware + wm.setConnectTimeout(50); // how long to try to connect for before continuing + //wm.setConfigPortalTimeout(30); // auto close configportal after n seconds + // wm.setCaptivePortalEnable(false); // disable captive portal redirection + // wm.setAPClientCheck(true); // avoid timeout if client connected to softap + //wm.setTimeout(120); + //wm.setConfigPortalTimeout(120); //seconds - // Need to convert numerical input to string to display the default value. - char convertedValue[6]; - sprintf(convertedValue, "%d", portNumber); - - // Text box (Number) - 7 characters maximum - WiFiManagerParameter port_text_box_num("Poolport", "Pool port", convertedValue, 7); + // Custom elements - // Text box (String) - 80 characters maximum - WiFiManagerParameter addr_text_box("btcAddress", "Your BTC address", btcString, 80); + // Text box (String) - 80 characters maximum + WiFiManagerParameter pool_text_box("Poolurl", "Pool url", Settings.PoolAddress, 80); + + // Need to convert numerical input to string to display the default value. + char convertedValue[6]; + sprintf(convertedValue, "%d", Settings.PoolPort); + + // Text box (Number) - 7 characters maximum + WiFiManagerParameter port_text_box_num("Poolport", "Pool port", convertedValue, 7); + + // Text box (String) - 80 characters maximum + WiFiManagerParameter addr_text_box("btcAddress", "Your BTC address", Settings.BtcWallet, 80); // Text box (Number) - 2 characters maximum char charZone[6]; - sprintf(charZone, "%d", GMTzone); + sprintf(charZone, "%d", Settings.Timezone); WiFiManagerParameter time_text_box_num("TimeZone", "TimeZone fromUTC (-12/+12)", charZone, 3); WiFiManagerParameter features_html("

"); char checkboxParams[24] = "type=\"checkbox\""; - if (saveStatsToNVS) + if (Settings.saveStats) { strcat(checkboxParams, " checked"); } @@ -229,109 +156,103 @@ void init_WifiManager() wm.addParameter(&features_html); wm.addParameter(&save_stats_to_nvs); - Serial.println("AllDone: "); - if (forceConfig) - // Run if we need a configuration - { - //No configuramos timeout al modulo - wm.setConfigPortalBlocking(true); //Hacemos que el portal SI bloquee el firmware - drawSetupScreen(); - if (!wm.startConfigPortal("NerdMinerAP","MineYourCoins")) + Serial.println("AllDone: "); + if (forceConfig) { - Serial.println("failed to connect and hit timeout"); - //Could be break forced after edditing, so save new config - strncpy(poolString, pool_text_box.getValue(), sizeof(poolString)); - portNumber = atoi(port_text_box_num.getValue()); - strncpy(btcString, addr_text_box.getValue(), sizeof(btcString)); - GMTzone = atoi(time_text_box_num.getValue()); - saveStatsToNVS = (strncmp(save_stats_to_nvs.getValue(), "T", 1) == 0); - saveConfigFile(); - delay(3000); - //reset and try again, or maybe put it to deep sleep - ESP.restart(); - delay(5000); + // Run if we need a configuration + //No configuramos timeout al modulo + wm.setConfigPortalBlocking(true); //Hacemos que el portal SI bloquee el firmware + drawSetupScreen(); + + if (!wm.startConfigPortal(DEFAULT_SSID, DEFAULT_WIFIPW)) + { + Serial.println("failed to connect and hit timeout"); + //Could be break forced after edditing, so save new config + + strncpy(Settings.PoolAddress, pool_text_box.getValue(), sizeof(Settings.PoolAddress)); + Settings.PoolPort = atoi(port_text_box_num.getValue()); + strncpy(Settings.BtcWallet, addr_text_box.getValue(), sizeof(Settings.BtcWallet)); + Settings.Timezone = atoi(time_text_box_num.getValue()); + Settings.saveStats = (strncmp(save_stats_to_nvs.getValue(), "T", 1) == 0); + + nvMem.saveConfig(&Settings); + delay(3000); + //reset and try again, or maybe put it to deep sleep + ESP.restart(); + delay(5000); + } } - } - else - { - //Tratamos de conectar con la configuraciĆ³n inicial ya almacenada + else + { + //Tratamos de conectar con la configuraciĆ³n inicial ya almacenada + mMonitor.NerdStatus = NM_Connecting; + wm.setCaptivePortalEnable(false); // disable captive portal redirection + if (!wm.autoConnect(Settings.WifiSSID, Settings.WifiPW)) + { + Serial.println("Failed to connect and hit timeout"); + //delay(3000); + // if we still have not connected restart and try all over again + //ESP.restart(); + //delay(5000); + } + } + mMonitor.NerdStatus = NM_Connecting; - wm.setCaptivePortalEnable(false); // disable captive portal redirection - if (!wm.autoConnect("NerdMinerAP","MineYourCoins")) - { - Serial.println("Failed to connect and hit timeout"); - //delay(3000); - // if we still have not connected restart and try all over again - //ESP.restart(); - //delay(5000); + + //Conectado a la red Wifi + if (WiFi.status() == WL_CONNECTED) { + //tft.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen); + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + // Lets deal with the user config values + + // Copy the string value + strncpy(Settings.PoolAddress, pool_text_box.getValue(), sizeof(Settings.PoolAddress)); + Serial.print("PoolString: "); + Serial.println(Settings.PoolAddress); + + //Convert the number value + Settings.PoolPort = atoi(port_text_box_num.getValue()); + Serial.print("portNumber: "); + Serial.println(Settings.PoolPort); + + // Copy the string value + strncpy(Settings.BtcWallet, addr_text_box.getValue(), sizeof(Settings.BtcWallet)); + Serial.print("btcString: "); + Serial.println(Settings.BtcWallet); + + //Convert the number value + Settings.Timezone = atoi(time_text_box_num.getValue()); + Serial.print("TimeZone fromUTC: "); + Serial.println(Settings.Timezone); + } - } - mMonitor.NerdStatus = NM_Connecting; - - //Conectado a la red Wifi - if(WiFi.status() == WL_CONNECTED){ - //tft.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen); - Serial.println(""); - Serial.println("WiFi connected"); - Serial.print("IP address: "); - Serial.println(WiFi.localIP()); - - // Lets deal with the user config values - - // Copy the string value - strncpy(poolString, pool_text_box.getValue(), sizeof(poolString)); - Serial.print("PoolString: "); - Serial.println(poolString); - - //Convert the number value - portNumber = atoi(port_text_box_num.getValue()); - Serial.print("portNumber: "); - Serial.println(portNumber); - - // Copy the string value - strncpy(btcString, addr_text_box.getValue(), sizeof(btcString)); - Serial.print("btcString: "); - Serial.println(btcString); - - //Convert the number value - GMTzone = atoi(time_text_box_num.getValue()); - Serial.print("TimeZone fromUTC: "); - Serial.println(GMTzone); - } - - // Save the custom parameters to FS - if (shouldSaveConfig) - { - saveConfigFile(); - } + // Save the custom parameters to FS + if (shouldSaveConfig) + { + nvMem.saveConfig(&Settings); + } } -void reset_configurations() { - Serial.println("Erasing Config, restarting"); - wm.resetSettings(); - SPIFFS.remove(JSON_CONFIG_FILE); //Borramos fichero - ESP.restart(); -} - - //----------------- MAIN PROCESS WIFI MANAGER -------------- int oldStatus = 0; void wifiManagerProcess() { - - wm.process(); // avoid delays() in loop when non-blocking and other long running code - - int newStatus = WiFi.status(); - if (newStatus != oldStatus) { - if (newStatus == WL_CONNECTED) { - Serial.println("CONNECTED - Current ip: " + WiFi.localIP().toString()); - } else { - Serial.print("[Error] - current status: "); - Serial.println(newStatus); + + wm.process(); // avoid delays() in loop when non-blocking and other long running code + + int newStatus = WiFi.status(); + if (newStatus != oldStatus) { + if (newStatus == WL_CONNECTED) { + Serial.println("CONNECTED - Current ip: " + WiFi.localIP().toString()); + } else { + Serial.print("[Error] - current status: "); + Serial.println(newStatus); + } + oldStatus = newStatus; } - oldStatus = newStatus; - } } - - diff --git a/src/wManager.h b/src/wManager.h index 870b435..ef2bd37 100644 --- a/src/wManager.h +++ b/src/wManager.h @@ -1,3 +1,8 @@ +#ifndef _WMANAGER_H +#define _WMANAGER_H + void init_WifiManager(); void wifiManagerProcess(); -void reset_configurations(); \ No newline at end of file +void reset_configuration(); + +#endif // _WMANAGER_H