Merge pull request #197 from BitMaker-hub/dev

New board, sd card config, touch control
This commit is contained in:
BitMaker 2023-10-06 00:00:27 +02:00 committed by GitHub
commit 68c088f30a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 2843 additions and 2102 deletions

3
.gitignore vendored
View File

@ -1,5 +1,8 @@
.pio .pio
.vscode .vscode
.vs
*.sln
*.vcxproj*
NerdMinerLog.txt NerdMinerLog.txt
bin/0x10000_firmware.bin bin/0x10000_firmware.bin
logs logs

View File

@ -37,13 +37,16 @@ Every time an stratum job notification is received miner update its current work
- 3D BOX [here](3d_files/) - 3D BOX [here](3d_files/)
#### Current Supported Boards #### Current Supported Boards
- LILYGO T-Display S3 ([Aliexpress link](https://s.click.aliexpress.com/e/_Ddy7739)) - LILYGO T-Display S3 ([Aliexpress link*](https://s.click.aliexpress.com/e/_Ddy7739))
- ESP32-WROOM-32, ESP32-Devkit1.. ([Aliexpress link](https://s.click.aliexpress.com/e/_DCzlUiX)) - ESP32-WROOM-32, ESP32-Devkit1.. ([Aliexpress link*](https://s.click.aliexpress.com/e/_DCzlUiX))
- LILYGO T-QT pro ([Aliexpress link](https://s.click.aliexpress.com/e/_DBQIr43)) - LILYGO T-QT pro ([Aliexpress link*](https://s.click.aliexpress.com/e/_DBQIr43))
- LILYGO T-Display 1.14 ([Aliexpress link](https://s.click.aliexpress.com/e/_DEqGvSJ)) - LILYGO T-Display 1.14 ([Aliexpress link*](https://s.click.aliexpress.com/e/_DEqGvSJ))
- LILYGO T-Display S3 AMOLED ([Aliexpress link](https://s.click.aliexpress.com/e/_DmOIK6j)) - 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)) - 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-2432S028R 2,8" ([Aliexpress link*](https://s.click.aliexpress.com/e/_DdXkvLv) / Dev support: @nitroxgas / ⚡jadeddonald78@walletofsatoshi.com)
- ESP32-cam ([Board Info](https://lastminuteengineers.com/getting-started-with-esp32-cam/) / Dev support: @elmo128)
*Affiliate links
### Flash firmware ### Flash firmware
#### microMiners Flashtool [Recommended] #### microMiners Flashtool [Recommended]
@ -53,17 +56,17 @@ Easyiest way to flash firmware. Build your own miner using the folowing firwmare
1. Go to NM2 flasher online: https://bitmaker-hub.github.io/diyflasher/ 1. Go to NM2 flasher online: https://bitmaker-hub.github.io/diyflasher/
#### Standard tool #### Standard tool
Create your own miner using the online firwmare flash tool **ESPtool** and the **binary files** that you will find in the src/bin folder. Create your own miner using the online firwmare flash tool **ESPtool** and one of the **binary files** that you will find in the ``bin`` folder.
If you want you can compile the entire project using Arduino, PlatformIO or Expressif IDF. If you want you can compile the entire project using Arduino, PlatformIO or Expressif IDF.
1. Get a TTGO T-display S3 or any supported board 1. Get a TTGO T-display S3 or any supported board
1. Download this repository 1. Download this repository
1. Go to ESPtool online: https://espressif.github.io/esptool-js/ 1. Go to ESPtool online: https://espressif.github.io/esptool-js/
1. Load the firmware with the binaries from the src/bin folder. 1. Load the firmware with the binary from one of the sub-folders of ``bin`` corresponding to your board.
1. Plug your board and select each file from src/bin with its address 1. Plug your board and select each file from the sub-folder (``.bin`` files).
### Update firmware ### Update firmware
Update NerdMiner firmware following same flashing steps but only adding 0x10000_firmware file. Update NerdMiner firmware following same flashing steps but only using the file 0x10000_firmware.bin.
#### Build troubleshooting #### Build troubleshooting
1. Online ESPtool works with chrome, chromium, brave 1. Online ESPtool works with chrome, chromium, brave
@ -72,15 +75,36 @@ Update NerdMiner firmware following same flashing steps but only adding 0x10000_
1. In extreme case you can "Erase all flash" on ESPtool to clean all current configuration before uploading firmware. There has been cases that experimented Wifi failures until this was made. 1. In extreme case you can "Erase all flash" on ESPtool to clean all current configuration before uploading firmware. There has been cases that experimented Wifi failures until this was made.
1. In case of ESP32-WROOM Boards, could be necessary to put your board on boot mode. Hold boot button, press reset button and then program. 1. In case of ESP32-WROOM Boards, could be necessary to put your board on boot mode. Hold boot button, press reset button and then program.
### NerdMiner configuration ## NerdMiner configuration
After programming, you will only need to setup your Wifi and BTC address. After programming, you will only need to setup your Wifi and BTC address.
#### Wifi Accesspoint
1. Connect to NerdMinerAP 1. Connect to NerdMinerAP
- AP: NerdMinerAP - AP: NerdMinerAP
- PASS: MineYourCoins - PASS: MineYourCoins
1. Setup your Wifi Network 1. Setup your Wifi Network
1. Add your BTCaddress 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",
"WifiPW": "myWifiPassword",
"PoolUrl": "public-pool.io",
"PoolPort": 21496,
"BtcWallet": "walletID",
"Timezone": 2,
"SaveStats": false
}
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: Recommended low difficulty share pools:
| Pool URL | Port | Web URL | Status | | Pool URL | Port | Web URL | Status |
@ -99,6 +123,15 @@ Other standard pools not compatible with low difficulty share:
| eu.stratum.slushpool.com | 3333 | https://braiins.com/pool | | eu.stratum.slushpool.com | 3333 | https://braiins.com/pool |
### Buttons ### 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: With the USB-C port to the right:
**TOP BUTTON** **TOP BUTTON**
@ -137,16 +170,17 @@ With the USB-C port to the right:
- [x] Add best difficulty on miner screen - [x] Add best difficulty on miner screen
- [x] Add suport to standard ESP32 dev-kit / ESP32-WROOM - [x] Add suport to standard ESP32 dev-kit / ESP32-WROOM
- [x] Code changes to support adding multiple boards - [x] Code changes to support adding multiple boards
- [x] Create a daisy chain protocol via UART or I2C to support ESP32 hashboards
- [x] Add support to TTGO T-display 1.14 - [x] Add support to TTGO T-display 1.14
- [x] Add support to Amoled - [x] Add support to Amoled
### On process ### On process
- [ ] Create a daisy chain protocol via UART or I2C to support ESP32 hashboards
- [ ] Create new screen like clockMiner but with BTC price - [ ] Create new screen like clockMiner but with BTC price
- [ ] Add support to control BM1397 - [ ] Add support to control BM1397
### Donations/Project contributions ### Donations/Project contributions
If you would like to contribute and help dev team with this project you can send a donation to the following LN address ⚡teamnerdminer@getalby.com⚡ If you would like to contribute and help dev team with this project you can send a donation to the following LN address ⚡teamnerdminer@getalby.com⚡ or using one of the affiliate links above.
If you want to order a fully assembled Nerdminer you can contribute to my job at [bitronics.store](https://bitronics.store).
Enjoy Enjoy

View File

@ -149,6 +149,9 @@
#ifdef NERMINER_S3_DONGLE #ifdef NERMINER_S3_DONGLE
#include <User_Setups/Setup209_LilyGo_T_Dongle_S3.h> // For the LilyGo T-Dongle S3 based ESP32 with ST7735 80 x 160 TFT #include <User_Setups/Setup209_LilyGo_T_Dongle_S3.h> // For the LilyGo T-Dongle S3 based ESP32 with ST7735 80 x 160 TFT
#endif #endif
#ifdef ESP32_CAM
#include <User_Setups/Setup212_ESP32Cam_DongleDisplay.h> // For the LilyGo T-Dongle S3 based ESP32 with ST7735 80 x 160 TFT
#endif
//#include <User_Setups/Setup301_BW16_ST7735.h> // Setup file for Bw16-based boards with ST7735 160 x 80 TFT //#include <User_Setups/Setup301_BW16_ST7735.h> // Setup file for Bw16-based boards with ST7735 160 x 80 TFT
//#include <User_Setups/SetupX_Template.h> // Template file for a setup //#include <User_Setups/SetupX_Template.h> // Template file for a setup

View File

@ -0,0 +1,56 @@
// Config for esp32cam, using dongledriver w ESP32 and ST7735 80 x 160 display
#define USER_SETUP_ID 212
#define ST7735_DRIVER // Configure all registers
#define TFT_WIDTH 80
#define TFT_HEIGHT 160
// #define ST7735_INITB
// #define ST7735_GREENTAB
// #define ST7735_GREENTAB2
// #define ST7735_GREENTAB3
// #define ST7735_GREENTAB128 // For 128 x 128 display
#define ST7735_GREENTAB160x80 // For 160 x 80 display (BGR, inverted, 26 offset)
// #define ST7735_REDTAB
//#define ST7735_BLACKTAB
// #define ST7735_REDTAB160x80 // For 160 x 80 display with 24 pixel offset
//#define TFT_RGB_ORDER TFT_RGB // Colour order Red-Green-Blue
#define TFT_RGB_ORDER TFT_BGR // Colour order Blue-Green-Red
//#define TFT_INVERSION_ON
//#define TFT_INVERSION_OFF
// Generic ESP32 setup
#define TFT_MISO 2
#define TFT_MOSI 15
#define TFT_SCLK 14
#define TFT_CS 12
#define TFT_DC 0
#define TFT_RST 22 // Connect reset to ensure display initialises (not really required).
#if (TFT_MISO == 16) || (TFT_MOSI == 16)|| (TFT_SCLK == 16)|| (TFT_CS == 16)|| (TFT_DC == 16)|| (TFT_RST == 16)
#warning: Using GPIO16 for display might crash on initializing the display!
#endif
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT
#define SPI_FREQUENCY 27000000
//#define SPI_FREQUENCY 40000000
#define SPI_READ_FREQUENCY 20000000
//#define SPI_TOUCH_FREQUENCY 2500000
// #define SUPPORT_TRANSACTIONS

View File

@ -10,7 +10,9 @@
[platformio] [platformio]
globallib_dir = lib globallib_dir = lib
default_envs = 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] [env:NerminerV2]
platform = espressif32 platform = espressif32
@ -23,13 +25,11 @@ monitor_filters =
board_build.arduino.memory_type = qio_opi board_build.arduino.memory_type = qio_opi
monitor_speed = 115200 monitor_speed = 115200
upload_speed = 115200 upload_speed = 115200
# 2 x 4.5MB app, 6.875MB SPIFFS # 2 x 4.5MB app, 6.875MB SPIFFS
;board_build.partitions = large_spiffs_16MB.csv ;board_build.partitions = large_spiffs_16MB.csv
;board_build.partitions = default_8MB.csv ;board_build.partitions = default_8MB.csv
board_build.partitions = huge_app.csv board_build.partitions = huge_app.csv
;board_build.partitions = default.csv ;board_build.partitions = default.csv
build_flags = build_flags =
-D LV_LVGL_H_INCLUDE_SIMPLE -D LV_LVGL_H_INCLUDE_SIMPLE
-D BOARD_HAS_PSRAM -D BOARD_HAS_PSRAM
@ -40,11 +40,12 @@ build_flags =
lib_deps = lib_deps =
https://github.com/takkaO/OpenFontRender https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2 bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
mathertel/OneButton @ ^2.0.3 mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient arduino-libraries/NTPClient
;https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4 ;https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4
;--------------------------------------------------------------------
[env:ESP32-devKitv1] [env:ESP32-devKitv1]
platform = espressif32 platform = espressif32
@ -57,20 +58,19 @@ monitor_filters =
;board_build.arduino.memory_type = qio_opi ;board_build.arduino.memory_type = qio_opi
monitor_speed = 115200 monitor_speed = 115200
upload_speed = 115200 upload_speed = 115200
# 2 x 4.5MB app, 6.875MB SPIFFS # 2 x 4.5MB app, 6.875MB SPIFFS
board_build.partitions = huge_app.csv board_build.partitions = huge_app.csv
build_flags = build_flags =
-D DEVKITV1=1 -D DEVKITV1=1
;-D DEBUG_MINING=1 ;-D DEBUG_MINING=1
lib_deps = lib_deps =
https://github.com/takkaO/OpenFontRender https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2 bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
mathertel/OneButton @ ^2.0.3 mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient arduino-libraries/NTPClient
;--------------------------------------------------------------------
[env:TTGO-T-Display] [env:TTGO-T-Display]
platform = espressif32 platform = espressif32
@ -83,29 +83,26 @@ monitor_filters =
board_build.arduino.memory_type = qio_opi board_build.arduino.memory_type = qio_opi
monitor_speed = 115200 monitor_speed = 115200
upload_speed = 115200 upload_speed = 115200
# 2 x 4.5MB app, 6.875MB SPIFFS # 2 x 4.5MB app, 6.875MB SPIFFS
board_build.partitions = huge_app.csv board_build.partitions = huge_app.csv
build_flags = build_flags =
;-D DEBUG_MINING=1 ;-D DEBUG_MINING=1
-D TDISPLAY=1 -D TDISPLAY=1
lib_deps = lib_deps =
https://github.com/takkaO/OpenFontRender https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2 bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
mathertel/OneButton @ ^2.0.3 mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient arduino-libraries/NTPClient
;https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4 ;https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4
;--------------------------------------------------------------------
[env:NerminerV2-S3-AMOLED] [env:NerminerV2-S3-AMOLED]
platform = espressif32 platform = espressif32
board = lilygo-t-amoled board = lilygo-t-amoled
framework = arduino framework = arduino
board_build.partitions = huge_app.csv board_build.partitions = huge_app.csv
build_flags = build_flags =
-DNERMINER_S3_AMOLED -DNERMINER_S3_AMOLED
-DBOARD_HAS_PSRAM -DBOARD_HAS_PSRAM
@ -113,18 +110,18 @@ build_flags =
lib_deps = lib_deps =
https://github.com/takkaO/OpenFontRender https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2 bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
mathertel/OneButton @ ^2.0.3 mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient arduino-libraries/NTPClient
https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4 https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4
;--------------------------------------------------------------------
[env:NerminerV2-S3-DONGLE] [env:NerminerV2-S3-DONGLE]
platform = espressif32 platform = espressif32
board = esp32-s3-devkitc-1 board = esp32-s3-devkitc-1
framework = arduino framework = arduino
board_build.partitions = huge_app.csv board_build.partitions = huge_app.csv
build_flags = build_flags =
-DNERMINER_S3_DONGLE -DNERMINER_S3_DONGLE
-DBOARD_HAS_PSRAM -DBOARD_HAS_PSRAM
@ -132,11 +129,42 @@ build_flags =
lib_deps = lib_deps =
https://github.com/takkaO/OpenFontRender https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2 bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
mathertel/OneButton @ ^2.0.3 mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient arduino-libraries/NTPClient
https://github.com/golden-guy/Arduino_wolfssl.git#v5.5.4
https://github.com/FastLED/FastLED 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
board_build.arduino.memory_type = dio_qspi
build_flags =
-D ESP32_CAM
-D BOARD_HAS_PSRAM
-D MONITOR_SPEED=${this.monitor_speed}
;-D DEBUG_MINING
;-D DEBUG_MEMORY
lib_deps =
bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient
https://github.com/takkaO/OpenFontRender
lib_ignore =
;TFT_eSPI
;--------------------------------------------------------------------
[env:NerminerV2-T-QT] [env:NerminerV2-T-QT]
platform = espressif32 platform = espressif32
@ -157,10 +185,12 @@ build_flags =
lib_deps = lib_deps =
https://github.com/takkaO/OpenFontRender https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2 bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
mathertel/OneButton @ ^2.0.3 mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient arduino-libraries/NTPClient
;--------------------------------------------------------------------
[env:ESP32-2432S028R] [env:ESP32-2432S028R]
platform = espressif32 platform = espressif32
board = esp32dev board = esp32dev
@ -170,8 +200,8 @@ upload_speed = 921600
;build_type = debug ;build_type = debug
board_build.partitions = huge_app.csv board_build.partitions = huge_app.csv
build_flags = build_flags =
;-DDEBUG_MEMORY=1
-D ESP32_2432S028R=1 -D ESP32_2432S028R=1
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-DUSER_SETUP_LOADED=1 -DUSER_SETUP_LOADED=1
-DILI9341_2_DRIVER=1 -DILI9341_2_DRIVER=1
-DTFT_WIDTH=240 -DTFT_WIDTH=240
@ -183,7 +213,11 @@ build_flags =
-DTFT_DC=2 -DTFT_DC=2
-DTFT_RST=12 -DTFT_RST=12
-DTFT_BL=21 -DTFT_BL=21
-DTOUCH_CS=33 -DETOUCH_CS=33
-DTOUCH_CLK=25
-DTOUCH_MISO=39
-DTOUCH_MOSI=32
-DTOUCH_IRQ=36
-DLOAD_GLCD=1 -DLOAD_GLCD=1
-DLOAD_FONT2=1 -DLOAD_FONT2=1
-DLOAD_GFXFF=1 -DLOAD_GFXFF=1
@ -194,10 +228,13 @@ build_flags =
lib_deps = lib_deps =
https://github.com/takkaO/OpenFontRender https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2 bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
mathertel/OneButton @ ^2.0.3 mathertel/OneButton @ ^2.0.3
arduino-libraries/NTPClient arduino-libraries/NTPClient
bodmer/TFT_eSPI @ ^2.5.31 bodmer/TFT_eSPI @ ^2.5.31
https://github.com/achillhasler/TFT_eTouch
;--------------------------------------------------------------------
[env:NerdminerV2-T-Display_V1] [env:NerdminerV2-T-Display_V1]
platform = espressif32 platform = espressif32
@ -216,7 +253,6 @@ build_flags =
lib_deps = lib_deps =
https://github.com/takkaO/OpenFontRender https://github.com/takkaO/OpenFontRender
bblanchon/ArduinoJson@^6.21.2 bblanchon/ArduinoJson@^6.21.2
https://github.com/tzapu/WiFiManager.git https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2
mathertel/OneButton @ ^2.0.3 mathertel/OneButton @ ^2.0.3
https://github.com/arduino-libraries/NTPClient https://github.com/arduino-libraries/NTPClient

View File

@ -10,7 +10,8 @@
#include "wManager.h" #include "wManager.h"
#include "mining.h" #include "mining.h"
#include "monitor.h" #include "monitor.h"
#include "drivers/display.h" #include "drivers/displays/display.h"
#include "drivers/storage/SDCard.h"
//3 seconds WDT //3 seconds WDT
#define WDT_TIMEOUT 3 #define WDT_TIMEOUT 3
@ -25,9 +26,10 @@
OneButton button2(PIN_BUTTON_2); OneButton button2(PIN_BUTTON_2);
#endif #endif
extern monitor_data mMonitor; extern monitor_data mMonitor;
SDCard SDCrd = SDCard();
/**********************⚡ GLOBAL Vars *******************************/ /**********************⚡ GLOBAL Vars *******************************/
unsigned long start = millis(); unsigned long start = millis();
@ -38,7 +40,12 @@ const char* ntpServer = "pool.ntp.org";
/********* INIT *****/ /********* INIT *****/
void setup() void setup()
{ {
#ifdef MONITOR_SPEED
Serial.begin(MONITOR_SPEED);
#else
Serial.begin(115200); Serial.begin(115200);
#endif //MONITOR_SPEED
Serial.setTimeout(0); Serial.setTimeout(0);
delay(100); delay(100);
@ -52,7 +59,8 @@ void setup()
button1.setPressTicks(5000); button1.setPressTicks(5000);
button1.attachClick(switchToNextScreen); button1.attachClick(switchToNextScreen);
button1.attachDoubleClick(alternateScreenRotation); button1.attachDoubleClick(alternateScreenRotation);
button1.attachLongPressStart(reset_configurations); button1.attachLongPressStart(reset_configuration);
button1.attachMultiClick(alternateScreenState);
#endif #endif
#if defined(PIN_BUTTON_1) && defined(PIN_BUTTON_2) //Button 1 of two button device #if defined(PIN_BUTTON_1) && defined(PIN_BUTTON_2) //Button 1 of two button device
@ -64,7 +72,7 @@ void setup()
#if defined(PIN_BUTTON_2) //Button 2 of two button device #if defined(PIN_BUTTON_2) //Button 2 of two button device
button2.setPressTicks(5000); button2.setPressTicks(5000);
button2.attachClick(switchToNextScreen); button2.attachClick(switchToNextScreen);
button2.attachLongPressStart(reset_configurations); button2.attachLongPressStart(reset_configuration);
#endif #endif
/******** INIT NERDMINER ************/ /******** INIT NERDMINER ************/

View File

@ -0,0 +1,27 @@
#ifndef __DEVICE_H__
#define __DEVICE_H__
#if defined(NERDMINERV2)
#include "nerdMinerV2.h"
#elif defined(DEVKITV1)
#include "esp32DevKit.h"
#elif defined(TDISPLAY)
#include "lilygoS3TDisplay.h"
#elif defined(NERMINER_S3_AMOLED)
#include "lilygoS3Amoled.h"
#elif defined(NERMINER_S3_DONGLE)
#include "lilygoS3Dongle.h"
#elif defined(ESP32_2432S028R)
#include "esp322432s028r.h"
#elif defined(NERMINER_T_QT)
#include "lilygoT_QT.h"
#elif defined(NERDMINER_T_DISPLAY_V1)
#include "lilygoV1TDisplay.h"
#elif defined(ESP32_CAM)
#include "esp32CAM.h"
#else
#error "No device defined"
#endif
#endif // __DEVICE_H__

View File

@ -0,0 +1,36 @@
#ifndef _ESP32CAM_H_
#define _ESP32CAM_H_
#define PIN_BUTTON_1 0
#define LED_PIN 33
#define DONGLE_DISPLAY // NO_DISPLAY
// example how to configure SD card.
// if you would define everything,
// to select 1 bit mode, make sure SDMMC_D1-3 are undefined
// to use spi mode, make sure all SDMMC_x pins are undefined
/*
// use 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
*/
// use SPI interface
// (default SPI unit provided by <SPI.h>)
// setup SPI pins.
#define SDSPI_CS 13
// The following pins can be retreived from the TFT_eSPI lib,
// if a display that is using it is activated.
#define SDSPI_CLK 14
#define SDSPI_MOSI 15
#define SDSPI_MISO 2
#endif // _ESP32_CAM_H_

View File

@ -1,4 +1,4 @@
#include "../drivers.h" #include "DisplayDriver.h"
#ifdef AMOLED_DISPLAY #ifdef AMOLED_DISPLAY

View File

@ -1,7 +1,7 @@
#ifndef DISPLAY_H #ifndef DISPLAY_H
#define DISPLAY_H #define DISPLAY_H
#include "drivers.h" #include "DisplayDriver.h"
extern DisplayDriver *currentDisplayDriver; extern DisplayDriver *currentDisplayDriver;

View File

@ -1,26 +1,7 @@
#ifndef DRIVERS_H #ifndef DISPLAYDRIVER_H_
#define DRIVERS_H #define DISPLAYDRIVER_H_
#if defined(NERDMINERV2) #include "../devices/device.h"
#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
typedef void (*AlternateFunction)(void); typedef void (*AlternateFunction)(void);
typedef void (*DriverInitFunction)(void); typedef void (*DriverInitFunction)(void);
@ -57,4 +38,4 @@ extern DisplayDriver tDisplayV1Driver;
#define SCREENS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define SCREENS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif // DRIVERS_H #endif // DISPLAYDRIVER_H_

View File

@ -1,4 +1,4 @@
#include "../drivers.h" #include "DisplayDriver.h"
#ifdef DONGLE_DISPLAY #ifdef DONGLE_DISPLAY
@ -9,7 +9,10 @@
#include "version.h" #include "version.h"
#include "monitor.h" #include "monitor.h"
#include "OpenFontRender.h" #include "OpenFontRender.h"
#ifdef USE_LED
#include <FastLED.h> #include <FastLED.h>
#endif
#define WIDTH 160 #define WIDTH 160
#define HEIGHT 80 #define HEIGHT 80
@ -26,6 +29,7 @@ OpenFontRender render;
TFT_eSPI tft = TFT_eSPI(); TFT_eSPI tft = TFT_eSPI();
TFT_eSprite background = TFT_eSprite(&tft); TFT_eSprite background = TFT_eSprite(&tft);
#ifdef USE_LED
#define MAX_BRIGHTNESS 16 #define MAX_BRIGHTNESS 16
#define SLOW_FADE 1; #define SLOW_FADE 1;
#define FAST_FADE 4; #define FAST_FADE 4;
@ -34,6 +38,7 @@ CRGB leds(0, 0, 0);
int brightness = 0; int brightness = 0;
int fadeDirection = 1; int fadeDirection = 1;
int fadeAmount = 0; int fadeAmount = 0;
#endif // USE_LED
extern monitor_data mMonitor; extern monitor_data mMonitor;
@ -74,8 +79,10 @@ extern monitor_data mMonitor;
void dongleDisplay_Init(void) void dongleDisplay_Init(void)
{ {
#ifdef USE_LED
FastLED.addLeds<APA102, LED_DI_PIN, LED_CI_PIN, BGR>(&leds, 1); FastLED.addLeds<APA102, LED_DI_PIN, LED_CI_PIN, BGR>(&leds, 1);
FastLED.show(); FastLED.show();
#endif // USE_LED
tft.init(); tft.init();
tft.setRotation(3); tft.setRotation(3);

View File

@ -1,8 +1,9 @@
#include "../drivers.h" #include "DisplayDriver.h"
#ifdef ESP32_2432S028R #ifdef ESP32_2432S028R
#include <TFT_eSPI.h> #include <TFT_eSPI.h>
#include <TFT_eTouch.h>
#include "media/images_320_170.h" #include "media/images_320_170.h"
#include "media/images_bottom_320_70.h" #include "media/images_bottom_320_70.h"
#include "media/myFonts.h" #include "media/myFonts.h"
@ -10,39 +11,52 @@
#include "version.h" #include "version.h"
#include "monitor.h" #include "monitor.h"
#include "OpenFontRender.h" #include "OpenFontRender.h"
#include <SPI.h>
#define WIDTH 340 #define WIDTH 130 //320
#define HEIGHT 240 #define HEIGHT 170
OpenFontRender render; OpenFontRender render;
TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in platformio.ini
TFT_eSprite background = TFT_eSprite(&tft); // Invoke library sprite TFT_eSprite background = TFT_eSprite(&tft); // Invoke library sprite
SPIClass hSPI(HSPI);
TFT_eTouch<TFT_eSPI> touch(tft, ETOUCH_CS, 0xFF, hSPI);
extern monitor_data mMonitor; extern monitor_data mMonitor;
extern pool_data pData; extern pool_data pData;
extern DisplayDriver *currentDisplayDriver;
bool hasChangedScreen = true;
void esp32_2432S028R_Init(void) void esp32_2432S028R_Init(void)
{ {
tft.init(); tft.init();
tft.setRotation(1); tft.setRotation(1);
tft.setSwapBytes(true); // Swap the colour byte order when rendering tft.setSwapBytes(true); // Swap the colour byte order when rendering
hSPI.begin(TOUCH_CLK, TOUCH_MISO, TOUCH_MOSI, ETOUCH_CS);
touch.init();
TFT_eTouchBase::Calibation calibation = { 233, 3785, 3731, 120, 2 };
touch.setCalibration(calibation);
//background.createSprite(WIDTH, HEIGHT); // Background Sprite //background.createSprite(WIDTH, HEIGHT); // Background Sprite
background.setSwapBytes(true); background.setSwapBytes(true);
render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background) render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background)
render.setLineSpaceRatio(0.9); // Espaciado entre texto render.setLineSpaceRatio(0.9); // Espaciado entre texto
// Load the font and check it can be read OK // Load the font and check it can be read OK
// if (render.loadFont(NotoSans_Bold, sizeof(NotoSans_Bold))) { // if (render.loadFont(NotoSans_Bold, sizeof(NotoSans_Bold)))
if (render.loadFont(DigitalNumbers, sizeof(DigitalNumbers))) if (render.loadFont(DigitalNumbers, sizeof(DigitalNumbers)))
{ {
Serial.println("Initialise error"); Serial.println("Initialise error");
return; return;
} }
pinMode(LED_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT);
pData.bestDifficulty = "0"; pData.bestDifficulty = "0";
pData.workersHash = "0"; pData.workersHash = "0";
pData.workersCount = 0; pData.workersCount = 0;
//Serial.println("=========== Fim Display ==============") ;
} }
void esp32_2432S028R_AlternateScreenState(void) void esp32_2432S028R_AlternateScreenState(void)
@ -55,44 +69,114 @@ void esp32_2432S028R_AlternateScreenState(void)
void esp32_2432S028R_AlternateRotation(void) void esp32_2432S028R_AlternateRotation(void)
{ {
tft.getRotation() == 1 ? tft.setRotation(3) : tft.setRotation(1); tft.getRotation() == 1 ? tft.setRotation(3) : tft.setRotation(1);
hasChangedScreen = true;
} }
bool bottomScreenBlue = true;
void printPoolData(){ void printPoolData(){
pData = updatePoolData(); pData = getPoolData();
background.createSprite(320,70); //Background Sprite background.createSprite(320,70); //Background Sprite
background.setSwapBytes(true); background.setSwapBytes(true);
if (bottomScreenBlue) {
background.pushImage(0, 0, 320, 70, bottonPoolScreen); background.pushImage(0, 0, 320, 70, bottonPoolScreen);
//background.fillRect(295,43,25,10,TFT_CYAN);
} else {
background.pushImage(0, 0, 320, 70, bottonPoolScreen_g);
}
//background.setTextDatum(MC_DATUM); //background.setTextDatum(MC_DATUM);
render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background) render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background)
render.setLineSpaceRatio(1); render.setLineSpaceRatio(1);
render.setFontSize(24); render.setFontSize(24);
render.cdrawString(String(pData.workersCount).c_str(), 160, 35, TFT_BLACK); render.cdrawString(String(pData.workersCount).c_str(), 155, 35, TFT_BLACK);
render.setFontSize(18); render.setFontSize(18);
render.setAlignment(Align::BottomRight); render.setAlignment(Align::BottomRight);
render.drawString(pData.workersHash.c_str(), 293, 51, TFT_BLACK); render.cdrawString(pData.workersHash.c_str(), 265, 34, TFT_BLACK);
render.setAlignment(Align::TopLeft); render.setAlignment(Align::BottomLeft);
render.cdrawString(pData.bestDifficulty.c_str(), 50, 34, TFT_BLACK); render.cdrawString(pData.bestDifficulty.c_str(), 54, 34, TFT_BLACK);
background.pushSprite(0,170); background.pushSprite(0,170);
background.deleteSprite(); background.deleteSprite();
} }
void esp32_2432S028R_MinerScreen(unsigned long mElapsed) void printheap(){
{ //Serial.print("============ Free Heap:");
mining_data data = getMiningData(mElapsed); //Serial.println(ESP.getFreeHeap());
}
// Create background sprite to print data at once void createBackgroundSprite(int16_t wdt, int16_t hgt){ // Set the background and link the render, used multiple times to fit in heap
background.createSprite(initWidth,initHeight); //Background Sprite background.createSprite(wdt, hgt) ; //Background Sprite
printheap();
background.setColorDepth(16); background.setColorDepth(16);
background.setSwapBytes(true); background.setSwapBytes(true);
render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background) render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background)
render.setLineSpaceRatio(0.9); render.setLineSpaceRatio(0.9);
}
void esp32_2432S028R_MinerScreen(unsigned long mElapsed)
{
if (hasChangedScreen) tft.pushImage(0, 0, initWidth, initHeight, MinerScreen);
hasChangedScreen = false;
mining_data data = getMiningData(mElapsed);
//Serial.println("Proximo sprite...");
int wdtOffset = 190;
// Recreate sprite to the right side of the screen
createBackgroundSprite(WIDTH-5, HEIGHT-7);
//Print background screen //Print background screen
background.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen); background.pushImage(-190, 0, MinerWidth, MinerHeight, MinerScreen);
// Total hashes
render.setFontSize(18);
render.rdrawString(data.totalMHashes.c_str(), 268-wdtOffset, 138, TFT_BLACK);
// Block templates
render.setFontSize(18);
render.setAlignment(Align::TopLeft);
render.drawString(data.templates.c_str(), 189-wdtOffset, 20, 0xDEDB);
// Best diff
render.drawString(data.bestDiff.c_str(), 189-wdtOffset, 48, 0xDEDB);
// 32Bit shares
render.setFontSize(18);
render.drawString(data.completedShares.c_str(), 189-wdtOffset, 76, 0xDEDB);
// Hores
render.setFontSize(14);
render.rdrawString(data.timeMining.c_str(), 315-wdtOffset, 104, 0xDEDB);
// Valid Blocks
render.setFontSize(24);
render.setAlignment(Align::TopCenter);
render.drawString(data.valids.c_str(), 290-wdtOffset, 56, 0xDEDB);
// Print Temp
render.setFontSize(10);
render.rdrawString(data.temp.c_str(), 239-wdtOffset, 1, TFT_BLACK);
render.setFontSize(4);
render.rdrawString(String(0).c_str(), 244-wdtOffset, 3, TFT_BLACK);
// Print Hour
render.setFontSize(10);
render.rdrawString(data.currentTime.c_str(), 286-wdtOffset, 1, TFT_BLACK);
// Push prepared background to screen
background.pushSprite(190, 0);
// Delete sprite to free the memory heap
background.deleteSprite();
printheap();
//Serial.println("=========== Mining Display ==============") ;
// Create background sprite to print data at once
createBackgroundSprite(WIDTH-7, HEIGHT-100); // initHeight); //Background Sprite
//Print background screen
background.pushImage(0, -90, MinerWidth, MinerHeight, MinerScreen);
Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n",
data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str());
@ -101,47 +185,16 @@ void esp32_2432S028R_MinerScreen(unsigned long mElapsed)
render.setFontSize(35); render.setFontSize(35);
render.setCursor(19, 118); render.setCursor(19, 118);
render.setFontColor(TFT_BLACK); render.setFontColor(TFT_BLACK);
render.rdrawString(data.currentHashRate.c_str(), 118, 114-90, TFT_BLACK);
render.rdrawString(data.currentHashRate.c_str(), 118, 114, TFT_BLACK);
// Total hashes
render.setFontSize(18);
render.rdrawString(data.totalMHashes.c_str(), 268, 138, TFT_BLACK);
// Block templates
render.setFontSize(18);
render.drawString(data.templates.c_str(), 186, 20, 0xDEDB);
// Best diff
render.drawString(data.bestDiff.c_str(), 186, 48, 0xDEDB);
// 32Bit shares
render.setFontSize(18);
render.drawString(data.completedShares.c_str(), 186, 76, 0xDEDB);
// Hores
render.setFontSize(14);
render.rdrawString(data.timeMining.c_str(), 315, 104, 0xDEDB);
// Valid Blocks
render.setFontSize(24);
render.drawString(data.valids.c_str(), 285, 56, 0xDEDB);
// Print Temp
render.setFontSize(10);
render.rdrawString(data.temp.c_str(), 239, 1, TFT_BLACK);
render.setFontSize(4);
render.rdrawString(String(0).c_str(), 244, 3, TFT_BLACK);
// Print Hour
render.setFontSize(10);
render.rdrawString(data.currentTime.c_str(), 286, 1, TFT_BLACK);
// Push prepared background to screen // Push prepared background to screen
background.pushSprite(0, 0); background.pushSprite(0, 90);
// Delete sprite to free the memory heap // Delete sprite to free the memory heap
background.deleteSprite(); background.deleteSprite();
//delay(50);
#ifdef ESP32_2432S028R
printPoolData(); printPoolData();
#endif
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
// Print heap // Print heap
@ -151,47 +204,53 @@ void esp32_2432S028R_MinerScreen(unsigned long mElapsed)
void esp32_2432S028R_ClockScreen(unsigned long mElapsed) void esp32_2432S028R_ClockScreen(unsigned long mElapsed)
{ {
if (hasChangedScreen) tft.pushImage(0, 0, minerClockWidth, minerClockHeight, minerClockScreen);
hasChangedScreen = false;
clock_data data = getClockData(mElapsed); clock_data data = getClockData(mElapsed);
// Create background sprite to print data at once
background.createSprite(initWidth,initHeight); //Background Sprite
background.setColorDepth(16);
background.setSwapBytes(true);
render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background)
render.setLineSpaceRatio(0.9);
// Print background screen
background.pushImage(0, 0, minerClockWidth, minerClockHeight, minerClockScreen);
Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n",
data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str());
// Create background sprite to print data at once
createBackgroundSprite(270,36);
// Print background screen
background.pushImage(0, -130, minerClockWidth, minerClockHeight, minerClockScreen);
// Hashrate // Hashrate
render.setFontSize(25); render.setFontSize(25);
render.setCursor(19, 122);
render.setFontColor(TFT_BLACK); render.setFontColor(TFT_BLACK);
render.rdrawString(data.currentHashRate.c_str(), 94, 129, TFT_BLACK); render.rdrawString(data.currentHashRate.c_str(), 95, 0, TFT_BLACK);
// Print BlockHeight
render.setFontSize(18);
render.rdrawString(data.blockHeight.c_str(), 254, 9, TFT_BLACK);
// Push prepared background to screen
background.pushSprite(0, 130);
// Delete sprite to free the memory heap
background.deleteSprite();
createBackgroundSprite(169,105);
// Print background screen
background.pushImage(-130, -3, minerClockWidth, minerClockHeight, minerClockScreen);
// Print BTC Price // Print BTC Price
background.setFreeFont(FSSB9); background.setFreeFont(FSSB9);
background.setTextSize(1); background.setTextSize(1);
background.setTextDatum(TL_DATUM); background.setTextDatum(TL_DATUM);
background.setTextColor(TFT_BLACK); background.setTextColor(TFT_BLACK);
background.drawString(data.btcPrice.c_str(), 202, 3, GFXFF); background.drawString(data.btcPrice.c_str(), 202-130, 0, GFXFF);
// Print BlockHeight
render.setFontSize(18);
render.rdrawString(data.blockHeight.c_str(), 254, 140, TFT_BLACK);
// Print Hour // Print Hour
background.setFreeFont(FF23); background.setFreeFont(FF23);
background.setTextSize(2); background.setTextSize(2);
background.setTextColor(0xDEDB, TFT_BLACK); background.setTextColor(0xDEDB, TFT_BLACK);
background.drawString(data.currentTime.c_str(), 0, 50, GFXFF);
background.drawString(data.currentTime.c_str(), 130, 50, GFXFF);
// Push prepared background to screen // Push prepared background to screen
background.pushSprite(0, 0); background.pushSprite(130, 3);
// Delete sprite to free the memory heap // Delete sprite to free the memory heap
background.deleteSprite(); background.deleteSprite();
@ -208,17 +267,15 @@ void esp32_2432S028R_ClockScreen(unsigned long mElapsed)
void esp32_2432S028R_GlobalHashScreen(unsigned long mElapsed) void esp32_2432S028R_GlobalHashScreen(unsigned long mElapsed)
{ {
if (hasChangedScreen) tft.pushImage(0, 0, globalHashWidth, globalHashHeight, globalHashScreen);
hasChangedScreen = false;
coin_data data = getCoinData(mElapsed); coin_data data = getCoinData(mElapsed);
// Create background sprite to print data at once // Create background sprite to print data at once
background.createSprite(initWidth,initHeight); //Background Sprite createBackgroundSprite(169,105);
background.setColorDepth(16);
background.setSwapBytes(true);
render.setDrawer(background); // Link drawing object to background instance (so font will be rendered on background)
render.setLineSpaceRatio(0.9);
// Print background screen // Print background screen
background.pushImage(0, 0, globalHashWidth, globalHashHeight, globalHashScreen); background.pushImage(-160, -3, minerClockWidth, minerClockHeight, globalHashScreen);
//background.fillScreen(TFT_BLUE);
Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n", Serial.printf(">>> Completed %s share(s), %s Khashes, avg. hashrate %s KH/s\n",
data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str()); data.completedShares.c_str(), data.totalKHashes.c_str(), data.currentHashRate.c_str());
@ -228,52 +285,68 @@ void esp32_2432S028R_GlobalHashScreen(unsigned long mElapsed)
background.setTextSize(1); background.setTextSize(1);
background.setTextDatum(TL_DATUM); background.setTextDatum(TL_DATUM);
background.setTextColor(TFT_BLACK); background.setTextColor(TFT_BLACK);
background.drawString(data.btcPrice.c_str(), 198, 3, GFXFF); background.drawString(data.btcPrice.c_str(), 198-160, 0, GFXFF);
// Print Hour // Print Hour
background.setFreeFont(FSSB9); background.setFreeFont(FSSB9);
background.setTextSize(1); background.setTextSize(1);
background.setTextDatum(TL_DATUM); background.setTextDatum(TL_DATUM);
background.setTextColor(TFT_BLACK); background.setTextColor(TFT_BLACK);
background.drawString(data.currentTime.c_str(), 268, 3, GFXFF); background.drawString(data.currentTime.c_str(), 268-160, 0, GFXFF);
// Print Last Pool Block // Print Last Pool Block
background.setFreeFont(FSS9); background.setFreeFont(FSS9);
background.setTextDatum(TR_DATUM); background.setTextDatum(TR_DATUM);
background.setTextColor(0x9C92); background.setTextColor(0x9C92);
background.drawString(data.halfHourFee.c_str(), 302, 52, GFXFF); background.drawString(data.halfHourFee.c_str(), 302-160, 49, GFXFF);
// Print Difficulty // Print Difficulty
background.setFreeFont(FSS9); background.setFreeFont(FSS9);
background.setTextDatum(TR_DATUM); background.setTextDatum(TR_DATUM);
background.setTextColor(0x9C92); background.setTextColor(0x9C92);
background.drawString(data.netwrokDifficulty.c_str(), 302, 88, GFXFF); background.drawString(data.netwrokDifficulty.c_str(), 302-160, 85, GFXFF);
// Push prepared background to screen
background.pushSprite(160, 3);
// Delete sprite to free the memory heap
background.deleteSprite();
// Create background sprite to print data at once
createBackgroundSprite(280,30);
// Print background screen
background.pushImage(0, -139, minerClockWidth, minerClockHeight, globalHashScreen);
//background.fillSprite(TFT_CYAN);
// Print Global Hashrate // Print Global Hashrate
render.setFontSize(17); render.setFontSize(17);
render.rdrawString(data.globalHashRate.c_str(), 274, 145, TFT_BLACK); render.rdrawString(data.globalHashRate.c_str(), 274, 145-139, TFT_BLACK);
// Print BlockHeight
render.setFontSize(28);
render.rdrawString(data.blockHeight.c_str(), 140, 104, 0xDEDB);
// Draw percentage rectangle // Draw percentage rectangle
int x2 = 2 + (138 * data.progressPercent / 100); int x2 = 2 + (138 * data.progressPercent / 100);
background.fillRect(2, 149, x2, 168, 0xDEDB); background.fillRect(2, 149-139, x2, 168, 0xDEDB);
// Print Remaining BLocks // Print Remaining BLocks
background.setTextFont(FONT2); background.setTextFont(FONT2);
background.setTextSize(1); background.setTextSize(1);
background.setTextDatum(MC_DATUM); background.setTextDatum(MC_DATUM);
background.setTextColor(TFT_BLACK); background.setTextColor(TFT_BLACK);
background.drawString(data.remainingBlocks.c_str(), 72, 159, FONT2); background.drawString(data.remainingBlocks.c_str(), 72, 159-139, FONT2);
// Push prepared background to screen // Push prepared background to screen
background.pushSprite(0, 0); background.pushSprite(0, 139);
// Delete sprite to free the memory heap // Delete sprite to free the memory heap
background.deleteSprite(); background.deleteSprite();
// Create background sprite to print data at once
createBackgroundSprite(140,40);
// Print background screen
background.pushImage(-5, -100, minerClockWidth, minerClockHeight, globalHashScreen);
//background.fillSprite(TFT_CYAN);
// Print BlockHeight
render.setFontSize(28);
render.rdrawString(data.blockHeight.c_str(), 140-5, 104-100, 0xDEDB);
// Push prepared background to screen
background.pushSprite(5, 100);
// Delete sprite to free the memory heap
background.deleteSprite();
#ifdef ESP32_2432S028R #ifdef ESP32_2432S028R
printPoolData(); printPoolData();
#endif #endif
@ -292,6 +365,7 @@ void esp32_2432S028R_LoadingScreen(void)
tft.drawString(CURRENT_VERSION, 24, 147, FONT2); tft.drawString(CURRENT_VERSION, 24, 147, FONT2);
delay(2000); delay(2000);
tft.fillScreen(TFT_BLACK); tft.fillScreen(TFT_BLACK);
tft.pushImage(0, 0, initWidth, initHeight, MinerScreen);
} }
void esp32_2432S028R_SetupScreen(void) void esp32_2432S028R_SetupScreen(void)
@ -305,10 +379,43 @@ void esp32_2432S028R_AnimateCurrentScreen(unsigned long frame)
// Variables para controlar el parpadeo con millis() // Variables para controlar el parpadeo con millis()
unsigned long previousMillis = 0; unsigned long previousMillis = 0;
unsigned long previousTouchMillis = 0;
char currentScreen = 0;
void esp32_2432S028R_DoLedStuff(unsigned long frame) void esp32_2432S028R_DoLedStuff(unsigned long frame)
{ {
unsigned long currentMillis = millis(); unsigned long currentMillis = millis();
// / Check the touch coordinates 110x185 210x240
if (currentMillis - previousTouchMillis >= 500)
{
int16_t t_x , t_y; // To store the touch coordinates
bool pressed = touch.getXY(t_x, t_y);
if (pressed) {
if (((t_x > 109)&&(t_x < 211)) && ((t_y > 185)&&(t_y < 241))) bottomScreenBlue ^= true;
else
if (t_x > 160) {
// next screen
Serial.print(t_x);
Serial.print(":x Próxima Tela y:");
Serial.println(t_y);
currentDisplayDriver->current_cyclic_screen = (currentDisplayDriver->current_cyclic_screen + 1) % currentDisplayDriver->num_cyclic_screens;
} else if (t_x < 160)
{
// Previus screen
Serial.print(t_x);
Serial.print(":x Tela anterior y:");
Serial.println(t_y);
/* Serial.println(currentDisplayDriver->current_cyclic_screen); */
currentDisplayDriver->current_cyclic_screen = currentDisplayDriver->current_cyclic_screen - 1;
if (currentDisplayDriver->current_cyclic_screen<0) currentDisplayDriver->current_cyclic_screen = currentDisplayDriver->num_cyclic_screens - 1;
Serial.println(currentDisplayDriver->current_cyclic_screen);
}
}
previousTouchMillis = currentMillis;
}
if (currentScreen != currentDisplayDriver->current_cyclic_screen) hasChangedScreen ^= true;
currentScreen = currentDisplayDriver->current_cyclic_screen;
switch (mMonitor.NerdStatus) switch (mMonitor.NerdStatus)
{ {
@ -332,6 +439,8 @@ void esp32_2432S028R_DoLedStuff(unsigned long frame)
} }
break; break;
} }
} }
CyclicScreenFunction esp32_2432S028RCyclicScreens[] = {esp32_2432S028R_MinerScreen, esp32_2432S028R_ClockScreen, esp32_2432S028R_GlobalHashScreen}; CyclicScreenFunction esp32_2432S028RCyclicScreens[] = {esp32_2432S028R_MinerScreen, esp32_2432S028R_ClockScreen, esp32_2432S028R_GlobalHashScreen};

View File

@ -1,4 +1,4 @@
#include "../drivers.h" #include "DisplayDriver.h"
#ifdef NO_DISPLAY #ifdef NO_DISPLAY

View File

@ -1,4 +1,4 @@
#include "../drivers.h" #include "DisplayDriver.h"
#ifdef T_DISPLAY #ifdef T_DISPLAY

View File

@ -1,4 +1,4 @@
#include "../drivers.h" #include "DisplayDriver.h"
#ifdef V1_DISPLAY #ifdef V1_DISPLAY

View File

@ -1,4 +1,4 @@
#include "../drivers.h" #include "DisplayDriver.h"
#ifdef T_QT_DISPLAY #ifdef T_QT_DISPLAY

View File

@ -0,0 +1,195 @@
#include <FS.h>
#include <ArduinoJson.h>
#include <WiFi.h>
#include "storage.h"
#include "nvMemory.h"
#include "../devices/device.h"
#include "SDCard.h"
#if defined (BUILD_SDMMC_1) || defined(BUILD_SDMMC_4)
#include <SD_MMC.h>
#elif defined (BUILD_SDSPI)
#include <SD.h>
#include <SPI.h>
#endif // interface type
#if defined (BUILD_SDMMC_1) || defined(BUILD_SDMMC_4) || defined (BUILD_SDSPI)
/// @param int ID only relevant in SPI mode, if you want to set up a custom SPI unit. Ignored in SD bus mode.
SDCard::SDCard(int ID):cardInitialized_(false),cardBusy_(false)
{
#if defined (BUILD_SDMMC_1) || defined(BUILD_SDMMC_4)
iSD_ = &SD_MMC;
#elif defined (BUILD_SDSPI)
if(ID>=0)
{
ispi_ = new SPIClass(ID);
newInstance_ = true;
}
else
{
ispi_ = &SPI;
newInstance_ = false;
}
iSD_ = &SD;
#endif // interface type
initSDcard();
}
SDCard::~SDCard()
{
iSD_->end();
#ifdef BUILD_SDSPI
if(newInstance_)
{
ispi_->end();
delete ispi_;
}
#endif // BUILD_SDSPI
Serial.println("SDCard: Unmounted");
}
/// @brief Check if the card is accessed right now.
/// @return true if active
bool SDCard::cardBusy()
{
return cardBusy_;
}
/// @brief Transfer settings from config file on a SD card to the device.
/// @param nvMemory* where to save
/// @param TSettings* passing a struct is required, to save memory
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();
}
}
/// @brief Retreives settings from a config file on a SD card.
/// @param TSettings* Struct to update with new Settings
/// @return true on success
bool SDCard::loadConfigFile(TSettings* Settings)
{
// Load existing configuration file
// Read configuration from FS json
if (cardAvailable())
{
if (iSD_->exists(JSON_CONFIG_FILE))
{
// The file exists, reading and loading
File configFile = iSD_->open(JSON_CONFIG_FILE, "r");
if (configFile)
{
cardBusy_ = true;
StaticJsonDocument<512> json;
DeserializationError error = deserializeJson(json, configFile);
configFile.close();
cardBusy_ = false;
Serial.println("SDCard: Loading config file");
if (!error)
{
serializeJsonPretty(json, Serial);
Serial.print('\n');
Settings->WifiSSID = json[JSON_KEY_SSID] | Settings->WifiSSID;
Settings->WifiPW = json[JSON_KEY_PASW] | Settings->WifiPW;
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<int>();
if (json.containsKey(JSON_KEY_TIMEZONE))
Settings->Timezone = json[JSON_KEY_TIMEZONE].as<int>();
if (json.containsKey(JSON_KEY_STATS2NV))
Settings->saveStats = json[JSON_KEY_STATS2NV].as<bool>();
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!");
}
}
return false;
}
/// @brief Check if a SD card is inserted.
/// @return true if inserted.
bool SDCard::cardAvailable()
{
if (cardInitialized_)
{
if (iSD_->cardType() != CARD_NONE)
{
Serial.println("SDCard: Inserted.");
return true;
}
else
{
Serial.println("SDCard: Not inserted.");
}
}
else
{
Serial.println("SDCard: Interface not initialized.");
}
return false;
}
/// @brief Init SD card interface. Normaly not required, as this is called by the constructor.
/// @return true on success
bool SDCard::initSDcard()
{
if (!cardAvailable())
{
Serial.println("SDCard: init SD card interface.");
#if defined (BUILD_SDMMC_4)
iSD_->setPins(SDMMC_CLK, SDMMC_CMD, SDMMC_D0, SDMMC_D1, SDMMC_D2, SDMMC_D3);
cardInitialized_ = iSD_->begin("/sd", false);
Serial.println("SDCard: 4-Bit Mode.");
}
#elif defined (BUILD_SDMMC_1)
#warning SDMMC : 1 - bit mode is not always working. If you experience issues, try other modes.
iSD_->setPins(SDMMC_CLK, SDMMC_CMD, SDMMC_D0);
cardInitialized_ = iSD_->begin("/sd", true);
Serial.println("SDCard: 1-Bit Mode.");
}
#elif defined (BUILD_SDSPI)
ispi_->begin(SDSPI_CLK, SDSPI_MISO, SDSPI_MOSI, SDSPI_CS);
cardInitialized_ = iSD_->begin(SDSPI_CS, *ispi_);
Serial.println("SDCard: SPI mode.");
}
#else
Serial.println("SDCard: interface not defined.");
return false;
#endif // dataPinsDefined
cardAvailable();
return cardInitialized_;
}
#else
SDCard::SDCard(int ID) {}
SDCard::~SDCard() {}
void SDCard::SD2nvMemory(nvMemory* nvMem, TSettings* Settings) {};
bool SDCard::loadConfigFile(TSettings* Settings) { return false; }
bool SDCard::initSDcard() { return false; }
bool SDCard::cardAvailable() { return false; }
bool SDCard::cardBusy() { return false; }
#endif //BUILD_SDMMC

View File

@ -0,0 +1,71 @@
#ifndef _SDCARD_H_
#define _SDCARD_H_
#include "storage.h"
#include "nvMemory.h"
#include "../devices/device.h"
// configuration example and description in /devices/esp32cam.h
// select interface and options according to provided pins
#if defined (SDMMC_D0) && defined (SDMMC_D1) && defined (SDMMC_D2) && defined (SDMMC_D3)
#define BUILD_SDMMC_4
#undef BUILD_SDMMC_1
#undef BUILD_SDSPI
#include <SD_MMC.h>
#warning SD card support in 4-Bit mode enabled!
#elif defined (SDMMC_D0) && !(defined (SDMMC_D1) && defined (SDMMC_D2) && defined (SDMMC_D3))
#define BUILD_SDMMC_1
#undef BUILD_SDMMC_4
#undef BUILD_SDSPI
#include <SD_MMC.h>
#warning SD card support in 1-Bit mode enabled!
#elif defined (SDSPI_CS)
#undef BUILD_SDMMC_1
#undef BUILD_SDMMC_4
#define BUILD_SDSPI
#include <SPI.h>
#include <SD.h>
#include "..\lib\TFT_eSPI\User_Setup_Select.h"
#ifndef NO_DISPLAY
#if !defined(SDSPI_CLK) && defined(TFT_CLK)
#define SDSPI_CLK TFT_CLK
#endif // SDSPI_CLK
#if !defined(SDSPI_MOSI) && defined(TFT_MOSI)
#define SDSPI_MOSI TFT_MOSI
#endif // SDSPI_MOSI
#if !defined(SDSPI_MISO) && defined(TFT_MISO)
#define SDSPI_MISO TFT_MISO
#endif // SDSPI_MISO
#elif !defined(SDSPI_CLK) || !defined(SDSPI_MOSI) || !defined(SDSPI_MISO)
#error: Please define SDSPI pins!
#endif // NO_DISPLAY
#warning SD card support in SPI mode enabled!
#endif
class SDCard
{
public:
SDCard(int ID=-1);
~SDCard();
void SD2nvMemory(nvMemory* nvMem, TSettings* Settings);
bool loadConfigFile(TSettings* Settings);
bool cardAvailable();
bool cardBusy();
private:
bool initSDcard();
bool cardInitialized_;
bool cardBusy_;
#if defined (BUILD_SDMMC_1) || defined(BUILD_SDMMC_4)
fs::SDMMCFS* iSD_;
#elif defined (BUILD_SDSPI)
SPIClass* ispi_;
fs::SDFS* iSD_;
bool newInstance_;
#endif
};
#endif // _SDCARD_H_

View File

@ -0,0 +1,155 @@
#include "nvMemory.h"
#ifdef NVMEM_SPIFFS
#include <SPIFFS.h>
#include <FS.h>
#include <ArduinoJson.h>
#include "../devices/device.h"
#include "storage.h"
nvMemory::nvMemory() : Initialized_(false){};
nvMemory::~nvMemory()
{
if (Initialized_)
SPIFFS.end();
};
/// @brief Save settings to config file on SPIFFS
/// @param TSettings* Settings to be saved.
/// @return true on success
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_SPIFFS_KEY_POOLURL] = Settings->PoolAddress;
json[JSON_SPIFFS_KEY_POOLPORT] = Settings->PoolPort;
json[JSON_SPIFFS_KEY_WALLETID] = Settings->BtcWallet;
json[JSON_SPIFFS_KEY_TIMEZONE] = Settings->Timezone;
json[JSON_SPIFFS_KEY_STATS2NV] = 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;
}
/// @brief Load settings from config file located in SPIFFS.
/// @param TSettings* Struct to update with new settings.
/// @return true on success
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)
{
Settings->PoolAddress = json[JSON_SPIFFS_KEY_POOLURL] | Settings->PoolAddress;
strcpy(Settings->BtcWallet, json[JSON_SPIFFS_KEY_WALLETID] | Settings->BtcWallet);
if (json.containsKey(JSON_SPIFFS_KEY_POOLPORT))
Settings->PoolPort = json[JSON_SPIFFS_KEY_POOLPORT].as<int>();
if (json.containsKey(JSON_SPIFFS_KEY_TIMEZONE))
Settings->Timezone = json[JSON_SPIFFS_KEY_TIMEZONE].as<int>();
if (json.containsKey(JSON_SPIFFS_KEY_STATS2NV))
Settings->saveStats = json[JSON_SPIFFS_KEY_STATS2NV].as<bool>();
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;
}
/// @brief Delete config file from SPIFFS
/// @return true on successs
bool nvMemory::deleteConfig()
{
Serial.println("SPIFS: Erasing config file..");
return SPIFFS.remove(JSON_CONFIG_FILE); //Borramos fichero
}
/// @brief Prepare and mount SPIFFS
/// @return true on success
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
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

View File

@ -0,0 +1,28 @@
#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_;
};
#ifndef NVMEM_SPIFFS
#error We need some kind of permanent storage implementation!
#endif //NVMEM_TYPE
#endif // _NVMEMORY_H_

View File

@ -0,0 +1,48 @@
#ifndef _STORAGE_H_
#define _STORAGE_H_
#include <Arduino.h>
// config files
// default settings
#define DEFAULT_SSID "NerdMinerAP"
#define DEFAULT_WIFIPW "MineYourCoins"
#define DEFAULT_POOLURL "public-pool.io"
#define DEFAULT_WALLETID "yourBtcAddress"
#define DEFAULT_POOLPORT 21496
#define DEFAULT_TIMEZONE 2
#define DEFAULT_SAVESTATS false
// JSON config files
#define JSON_CONFIG_FILE "/config.json"
// JSON config file SD card (for user interaction, readme.md)
#define JSON_KEY_SSID "SSID"
#define JSON_KEY_PASW "WifiPW"
#define JSON_KEY_POOLURL "PoolUrl"
#define JSON_KEY_WALLETID "BtcWallet"
#define JSON_KEY_POOLPORT "PoolPort"
#define JSON_KEY_TIMEZONE "Timezone"
#define JSON_KEY_STATS2NV "SaveStats"
// JSON config file SPIFFS (different for backward compatibility with existing devices)
#define JSON_SPIFFS_KEY_POOLURL "poolString"
#define JSON_SPIFFS_KEY_POOLPORT "portNumber"
#define JSON_SPIFFS_KEY_WALLETID "btcString"
#define JSON_SPIFFS_KEY_TIMEZONE "gmtZone"
#define JSON_SPIFFS_KEY_STATS2NV "saveStatsToNVS"
// settings
struct TSettings
{
String WifiSSID{ DEFAULT_SSID };
String WifiPW{ DEFAULT_WIFIPW };
String PoolAddress{ DEFAULT_POOLURL };
char BtcWallet[80]{ DEFAULT_WALLETID };
int PoolPort{ DEFAULT_POOLPORT };
int Timezone{ DEFAULT_TIMEZONE };
bool saveStats{ DEFAULT_SAVESTATS };
};
#endif // _STORAGE_H_

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,8 @@
#include "mining.h" #include "mining.h"
#include "utils.h" #include "utils.h"
#include "monitor.h" #include "monitor.h"
#include "drivers/display.h" #include "drivers/displays/display.h"
#include "drivers/storage/storage.h"
nvs_handle_t stat_handle; nvs_handle_t stat_handle;
@ -28,11 +29,10 @@ uint32_t valids; // increased if blockhash <= target
double best_diff = 0.0; double best_diff = 0.0;
// Variables to hold data from custom textboxes // Variables to hold data from custom textboxes
extern char poolString[80]; //Track mining stats in non volatile memory
extern int portNumber; extern TSettings Settings;
extern char btcString[80];
IPAddress serverIP(1, 1, 1, 1); //Temporally save poolIPaddres IPAddress serverIP(1, 1, 1, 1); //Temporally save poolIPaddres
extern bool saveStatsToNVS; //Track mining stats in non volatile memory
//Global work data //Global work data
static WiFiClient client; static WiFiClient client;
@ -59,14 +59,14 @@ bool checkPoolConnection(void) {
//Resolve first time pool DNS and save IP //Resolve first time pool DNS and save IP
if(serverIP == IPAddress(1,1,1,1)) { if(serverIP == IPAddress(1,1,1,1)) {
WiFi.hostByName(poolString, serverIP); WiFi.hostByName(Settings.PoolAddress.c_str(), serverIP);
Serial.printf("Resolved DNS and save ip (first time) got: %s\n", serverIP.toString()); Serial.printf("Resolved DNS and save ip (first time) got: %s\n", serverIP.toString());
} }
//Try connecting pool IP //Try connecting pool IP
if (!client.connect(serverIP, portNumber)) { if (!client.connect(serverIP, Settings.PoolPort)) {
Serial.println("Imposible to connect to : " + String(poolString)); Serial.println("Imposible to connect to : " + Settings.PoolAddress);
WiFi.hostByName(poolString, serverIP); WiFi.hostByName(Settings.PoolAddress.c_str(), serverIP);
Serial.printf("Resolved DNS got: %s\n", serverIP.toString()); Serial.printf("Resolved DNS got: %s\n", serverIP.toString());
vTaskDelay(1000 / portTICK_PERIOD_MS); vTaskDelay(1000 / portTICK_PERIOD_MS);
return false; return false;
@ -116,7 +116,7 @@ void runStratumWorker(void *name) {
Serial.printf("\n[WORKER] Started. Running %s on core %d\n", (char *)name, xPortGetCoreID()); Serial.printf("\n[WORKER] Started. Running %s on core %d\n", (char *)name, xPortGetCoreID());
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
Serial.printf("### [Total Heap / Free heap]: %d / %d \n", ESP.getHeapSize(), ESP.getFreeHeap()); Serial.printf("### [Total Heap / Free heap / Min free heap]: %d / %d / %d \n", ESP.getHeapSize(), ESP.getFreeHeap(), ESP.getMinFreeHeap());
#endif #endif
// connect to pool // connect to pool
@ -166,7 +166,7 @@ void runStratumWorker(void *name) {
continue; continue;
} }
strcpy(mWorker.wName, btcString); strcpy(mWorker.wName, Settings.BtcWallet);
strcpy(mWorker.wPass, "x"); strcpy(mWorker.wPass, "x");
// STEP 2: Pool authorize work (Block Info) // STEP 2: Pool authorize work (Block Info)
tx_mining_auth(client, mWorker.wName, mWorker.wPass); //Don't verifies authoritzation, TODO tx_mining_auth(client, mWorker.wName, mWorker.wPass); //Don't verifies authoritzation, TODO
@ -386,7 +386,7 @@ void runMiner(void * task_id) {
#define REDRAW_EVERY 10 #define REDRAW_EVERY 10
void restoreStat() { void restoreStat() {
if(!saveStatsToNVS) return; if(!Settings.saveStats) return;
esp_err_t ret = nvs_flash_init(); esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { 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"); Serial.printf("[MONITOR] NVS partition is full or has invalid version, erasing...\n");
@ -405,7 +405,7 @@ void restoreStat() {
} }
void saveStat() { void saveStat() {
if(!saveStatsToNVS) return; if(!Settings.saveStats) return;
Serial.printf("[MONITOR] Saving stats\n"); Serial.printf("[MONITOR] Saving stats\n");
nvs_set_blob(stat_handle, "best_diff", &best_diff, sizeof(double)); nvs_set_blob(stat_handle, "best_diff", &best_diff, sizeof(double));
nvs_set_u32(stat_handle, "Mhashes", Mhashes); nvs_set_u32(stat_handle, "Mhashes", Mhashes);
@ -452,7 +452,7 @@ void runMonitor(void *name)
} }
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
Serial.printf("### [Total Heap / Free heap]: %d / %d \n", ESP.getHeapSize(), ESP.getFreeHeap()); Serial.printf("### [Total Heap / Free heap / Min free heap]: %d / %d / %d \n", ESP.getHeapSize(), ESP.getFreeHeap(), ESP.getMinFreeHeap());
Serial.printf("### Max stack usage: %d\n", uxTaskGetStackHighWaterMark(NULL)); Serial.printf("### Max stack usage: %d\n", uxTaskGetStackHighWaterMark(NULL));
#endif #endif

View File

@ -7,8 +7,8 @@
#include "mining.h" #include "mining.h"
#include "utils.h" #include "utils.h"
#include "monitor.h" #include "monitor.h"
#include "drivers/storage/storage.h"
extern char poolString[80];
extern uint32_t templates; extern uint32_t templates;
extern uint32_t hashes; extern uint32_t hashes;
extern uint32_t Mhashes; extern uint32_t Mhashes;
@ -23,7 +23,8 @@ extern double best_diff; // track best diff
extern monitor_data mMonitor; extern monitor_data mMonitor;
extern int GMTzone; //Gotten from saved config //from saved config
extern TSettings Settings;
WiFiUDP ntpUDP; WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
@ -39,7 +40,7 @@ void setup_monitor(void){
// Adjust offset depending on your zone // Adjust offset depending on your zone
// GMT +2 in seconds (zona horaria de Europa Central) // GMT +2 in seconds (zona horaria de Europa Central)
timeClient.setTimeOffset(3600 * GMTzone); timeClient.setTimeOffset(3600 * Settings.Timezone);
Serial.println("TimeClient setup done"); Serial.println("TimeClient setup done");
} }
@ -171,7 +172,6 @@ unsigned long mTriggerUpdate = 0;
unsigned long initialMillis = millis(); unsigned long initialMillis = millis();
unsigned long initialTime = 0; unsigned long initialTime = 0;
unsigned long mPoolUpdate = 0; unsigned long mPoolUpdate = 0;
extern char btcString[80];
void getTime(unsigned long* currentHours, unsigned long* currentMinutes, unsigned long* currentSeconds){ void getTime(unsigned long* currentHours, unsigned long* currentMinutes, unsigned long* currentSeconds){
@ -287,7 +287,7 @@ coin_data getCoinData(unsigned long mElapsed)
return data; return data;
} }
pool_data updatePoolData(void){ pool_data getPoolData(void){
//pool_data pData; //pool_data pData;
if((mPoolUpdate == 0) || (millis() - mPoolUpdate > UPDATE_POOL_min * 60 * 1000)){ if((mPoolUpdate == 0) || (millis() - mPoolUpdate > UPDATE_POOL_min * 60 * 1000)){
if (WiFi.status() != WL_CONNECTED) return pData; if (WiFi.status() != WL_CONNECTED) return pData;
@ -296,27 +296,41 @@ pool_data updatePoolData(void){
HTTPClient http; HTTPClient http;
http.setReuse(true); http.setReuse(true);
try { try {
http.begin(String(getPublicPool)+btcString); String btcWallet = Settings.BtcWallet;
Serial.println(btcWallet);
if (btcWallet.indexOf(".")>0) btcWallet = btcWallet.substring(0,btcWallet.indexOf("."));
http.begin(String(getPublicPool)+btcWallet);
int httpCode = http.GET(); int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
if (httpCode > 0) {
String payload = http.getString(); String payload = http.getString();
// Serial.println(payload); // Serial.println(payload);
DynamicJsonDocument doc(1024); StaticJsonDocument<300> filter;
deserializeJson(doc, payload); filter["bestDifficulty"] = true;
filter["workersCount"] = true;
filter["workers"][0]["sessionId"] = true;
filter["workers"][0]["hashRate"] = true;
DynamicJsonDocument doc(2048);
deserializeJson(doc, payload, DeserializationOption::Filter(filter));
//Serial.println(serializeJsonPretty(doc, Serial));
if (doc.containsKey("workersCount")) pData.workersCount = doc["workersCount"].as<int>(); if (doc.containsKey("workersCount")) pData.workersCount = doc["workersCount"].as<int>();
const JsonArray& workers = doc["workers"].as<JsonArray>(); const JsonArray& workers = doc["workers"].as<JsonArray>();
float totalhashs = 0; float totalhashs = 0;
for (const JsonObject& worker : workers) { for (const JsonObject& worker : workers) {
totalhashs += worker["hashRate"].as<float>(); totalhashs += worker["hashRate"].as<double>();
/* Serial.print(worker["sessionId"].as<String>()+": ");
Serial.print(" - "+worker["hashRate"].as<String>()+": ");
Serial.println(totalhashs); */
} }
pData.workersHash = String(totalhashs/1000); char totalhashs_s[16] = {0};
suffix_string(totalhashs, totalhashs_s, 16, 0);
pData.workersHash = String(totalhashs_s);
String temp = ""; double temp;
if (doc.containsKey("bestDifficulty")) { if (doc.containsKey("bestDifficulty")) {
temp = doc["bestDifficulty"].as<float>(); temp = doc["bestDifficulty"].as<double>();
pData.bestDifficulty = String(temp); char best_diff_string[16] = {0};
suffix_string(temp, best_diff_string, 16, 0);
pData.bestDifficulty = String(best_diff_string);
} }
doc.clear(); doc.clear();
mPoolUpdate = millis(); mPoolUpdate = millis();

View File

@ -111,7 +111,7 @@ void setup_monitor(void);
mining_data getMiningData(unsigned long mElapsed); mining_data getMiningData(unsigned long mElapsed);
clock_data getClockData(unsigned long mElapsed); clock_data getClockData(unsigned long mElapsed);
coin_data getCoinData(unsigned long mElapsed); coin_data getCoinData(unsigned long mElapsed);
pool_data updatePoolData(void); pool_data getPoolData(void);
clock_data_t getClockData_t(unsigned long mElapsed); clock_data_t getClockData_t(unsigned long mElapsed);

View File

@ -2,120 +2,32 @@
// Include Libraries // Include Libraries
//#include ".h" //#include ".h"
#include <WiFi.h> #include <WiFi.h>
#include <SPIFFS.h>
#include <FS.h>
#include <WiFiManager.h> #include <WiFiManager.h>
#include <ArduinoJson.h>
#include "wManager.h" #include "wManager.h"
#include "monitor.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 // Flag for saving data
bool shouldSaveConfig = false; bool shouldSaveConfig = false;
// Variables to hold data from custom textboxes // Variables to hold data from custom textboxes
char poolString[80] = "public-pool.io"; TSettings Settings;
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
// Define WiFiManager Object // Define WiFiManager Object
WiFiManager wm; WiFiManager wm;
extern monitor_data mMonitor; extern monitor_data mMonitor;
void saveConfigFile() nvMemory nvMem;
// 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<int>();
GMTzone = json["gmtZone"].as<int>();
if(json.containsKey("saveStatsToNVS"))
saveStatsToNVS = json["saveStatsToNVS"].as<int>();
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;
}
extern SDCard SDCrd;
void saveConfigCallback() void saveConfigCallback()
// Callback notifying us of the need to save configuration // Callback notifying us of the need to save configuration
@ -125,7 +37,7 @@ void saveConfigCallback()
//wm.setConfigPortalBlocking(false); //wm.setConfigPortalBlocking(false);
} }
void configModeCallback(WiFiManager *myWiFiManager) void configModeCallback(WiFiManager* myWiFiManager)
// Called when config mode launched // Called when config mode launched
{ {
Serial.println("Entered Configuration Mode"); Serial.println("Entered Configuration Mode");
@ -137,40 +49,58 @@ void configModeCallback(WiFiManager *myWiFiManager)
Serial.println(WiFi.softAPIP()); Serial.println(WiFi.softAPIP());
} }
void reset_configuration()
{
Serial.println("Erasing Config, restarting");
nvMem.deleteConfig();
wm.resetSettings();
ESP.restart();
}
void init_WifiManager() void init_WifiManager()
{ {
#ifdef MONITOR_SPEED
Serial.begin(MONITOR_SPEED);
#else
Serial.begin(115200); Serial.begin(115200);
#endif //MONITOR_SPEED
//Serial.setTxTimeoutMs(10); //Serial.setTxTimeoutMs(10);
//Init pin 15 to eneble 5V external power (LilyGo bug) //Init pin 15 to eneble 5V external power (LilyGo bug)
#ifdef PIN_ENABLE5V #ifdef PIN_ENABLE5V
pinMode(PIN_ENABLE5V, OUTPUT); pinMode(PIN_ENABLE5V, OUTPUT);
digitalWrite(PIN_ENABLE5V, HIGH); digitalWrite(PIN_ENABLE5V, HIGH);
#endif #endif
// Change to true when testing to force configuration every time we run // Change to true when testing to force configuration every time we run
bool forceConfig = false; bool forceConfig = false;
#if defined(PIN_BUTTON_2) #if defined(PIN_BUTTON_2)
// Check if button2 is pressed to enter configMode with actual configuration // Check if button2 is pressed to enter configMode with actual configuration
if(!digitalRead(PIN_BUTTON_2)){ if (!digitalRead(PIN_BUTTON_2)) {
Serial.println(F("Button pressed to force start config mode")); Serial.println(F("Button pressed to force start config mode"));
forceConfig = true; forceConfig = true;
wm.setBreakAfterConfig(true); //Set to detect config edition and save wm.setBreakAfterConfig(true); //Set to detect config edition and save
} }
#endif #endif
bool spiffsSetup = loadConfigFile();
if (!spiffsSetup)
{
Serial.println(F("Forcing config mode as there is no saved config"));
forceConfig = true;
}
// Explicitly set WiFi mode // Explicitly set WiFi mode
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
if (!nvMem.loadConfig(&Settings))
{
//No config file on internal flash.
if (SDCrd.loadConfigFile(&Settings))
{
//Config file on SD card.
SDCrd.SD2nvMemory(&nvMem, &Settings); // reboot on success.
}
else
{
//No config file on SD card. Starting wifi config server.
forceConfig = true;
}
};
// Reset settings (only for development) // Reset settings (only for development)
//wm.resetSettings(); //wm.resetSettings();
@ -195,27 +125,27 @@ void init_WifiManager()
// Custom elements // Custom elements
// Text box (String) - 80 characters maximum // Text box (String) - 80 characters maximum
WiFiManagerParameter pool_text_box("Poolurl", "Pool url", poolString, 80); WiFiManagerParameter pool_text_box("Poolurl", "Pool url", Settings.PoolAddress.c_str(), 80);
// Need to convert numerical input to string to display the default value. // Need to convert numerical input to string to display the default value.
char convertedValue[6]; char convertedValue[6];
sprintf(convertedValue, "%d", portNumber); sprintf(convertedValue, "%d", Settings.PoolPort);
// Text box (Number) - 7 characters maximum // Text box (Number) - 7 characters maximum
WiFiManagerParameter port_text_box_num("Poolport", "Pool port", convertedValue, 7); WiFiManagerParameter port_text_box_num("Poolport", "Pool port", convertedValue, 7);
// Text box (String) - 80 characters maximum // Text box (String) - 80 characters maximum
WiFiManagerParameter addr_text_box("btcAddress", "Your BTC address", btcString, 80); WiFiManagerParameter addr_text_box("btcAddress", "Your BTC address", Settings.BtcWallet, 80);
// Text box (Number) - 2 characters maximum // Text box (Number) - 2 characters maximum
char charZone[6]; 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 time_text_box_num("TimeZone", "TimeZone fromUTC (-12/+12)", charZone, 3);
WiFiManagerParameter features_html("<hr><br><label style=\"font-weight: bold;margin-bottom: 25px;display: inline-block;\">Features</label>"); WiFiManagerParameter features_html("<hr><br><label style=\"font-weight: bold;margin-bottom: 25px;display: inline-block;\">Features</label>");
char checkboxParams[24] = "type=\"checkbox\""; char checkboxParams[24] = "type=\"checkbox\"";
if (saveStatsToNVS) if (Settings.saveStats)
{ {
strcat(checkboxParams, " checked"); strcat(checkboxParams, " checked");
} }
@ -231,33 +161,36 @@ void init_WifiManager()
Serial.println("AllDone: "); Serial.println("AllDone: ");
if (forceConfig) if (forceConfig)
// Run if we need a configuration
{ {
// Run if we need a configuration
//No configuramos timeout al modulo //No configuramos timeout al modulo
wm.setConfigPortalBlocking(true); //Hacemos que el portal SI bloquee el firmware wm.setConfigPortalBlocking(true); //Hacemos que el portal SI bloquee el firmware
drawSetupScreen(); drawSetupScreen();
if (!wm.startConfigPortal("NerdMinerAP","MineYourCoins"))
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 //Could be break forced after edditing, so save new config
strncpy(poolString, pool_text_box.getValue(), sizeof(poolString)); Serial.println("failed to connect and hit timeout");
portNumber = atoi(port_text_box_num.getValue()); Settings.PoolAddress = pool_text_box.getValue();
strncpy(btcString, addr_text_box.getValue(), sizeof(btcString)); Settings.PoolPort = atoi(port_text_box_num.getValue());
GMTzone = atoi(time_text_box_num.getValue()); strncpy(Settings.BtcWallet, addr_text_box.getValue(), sizeof(Settings.BtcWallet));
saveStatsToNVS = (strncmp(save_stats_to_nvs.getValue(), "T", 1) == 0); Settings.Timezone = atoi(time_text_box_num.getValue());
saveConfigFile(); Serial.println(save_stats_to_nvs.getValue());
Settings.saveStats = (strncmp(save_stats_to_nvs.getValue(), "T", 1) == 0);
nvMem.saveConfig(&Settings);
delay(3000); delay(3000);
//reset and try again, or maybe put it to deep sleep //reset and try again, or maybe put it to deep sleep
ESP.restart(); ESP.restart();
delay(5000); delay(5000);
} };
} }
else else
{ {
//Tratamos de conectar con la configuración inicial ya almacenada //Tratamos de conectar con la configuración inicial ya almacenada
mMonitor.NerdStatus = NM_Connecting; mMonitor.NerdStatus = NM_Connecting;
wm.setCaptivePortalEnable(false); // disable captive portal redirection wm.setCaptivePortalEnable(false); // disable captive portal redirection
if (!wm.autoConnect("NerdMinerAP","MineYourCoins")) if (!wm.autoConnect(Settings.WifiSSID.c_str(), Settings.WifiPW.c_str()))
{ {
Serial.println("Failed to connect and hit timeout"); Serial.println("Failed to connect and hit timeout");
//delay(3000); //delay(3000);
@ -270,7 +203,7 @@ void init_WifiManager()
mMonitor.NerdStatus = NM_Connecting; mMonitor.NerdStatus = NM_Connecting;
//Conectado a la red Wifi //Conectado a la red Wifi
if(WiFi.status() == WL_CONNECTED){ if (WiFi.status() == WL_CONNECTED) {
//tft.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen); //tft.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen);
Serial.println(""); Serial.println("");
Serial.println("WiFi connected"); Serial.println("WiFi connected");
@ -280,41 +213,35 @@ void init_WifiManager()
// Lets deal with the user config values // Lets deal with the user config values
// Copy the string value // Copy the string value
strncpy(poolString, pool_text_box.getValue(), sizeof(poolString)); Settings.PoolAddress = pool_text_box.getValue();
//strncpy(Settings.PoolAddress, pool_text_box.getValue(), sizeof(Settings.PoolAddress));
Serial.print("PoolString: "); Serial.print("PoolString: ");
Serial.println(poolString); Serial.println(Settings.PoolAddress);
//Convert the number value //Convert the number value
portNumber = atoi(port_text_box_num.getValue()); Settings.PoolPort = atoi(port_text_box_num.getValue());
Serial.print("portNumber: "); Serial.print("portNumber: ");
Serial.println(portNumber); Serial.println(Settings.PoolPort);
// Copy the string value // Copy the string value
strncpy(btcString, addr_text_box.getValue(), sizeof(btcString)); strncpy(Settings.BtcWallet, addr_text_box.getValue(), sizeof(Settings.BtcWallet));
Serial.print("btcString: "); Serial.print("btcString: ");
Serial.println(btcString); Serial.println(Settings.BtcWallet);
//Convert the number value //Convert the number value
GMTzone = atoi(time_text_box_num.getValue()); Settings.Timezone = atoi(time_text_box_num.getValue());
Serial.print("TimeZone fromUTC: "); Serial.print("TimeZone fromUTC: ");
Serial.println(GMTzone); Serial.println(Settings.Timezone);
} }
// Save the custom parameters to FS // Save the custom parameters to FS
if (shouldSaveConfig) if (shouldSaveConfig)
{ {
saveConfigFile(); 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 -------------- //----------------- MAIN PROCESS WIFI MANAGER --------------
int oldStatus = 0; int oldStatus = 0;
@ -333,5 +260,3 @@ void wifiManagerProcess() {
oldStatus = newStatus; oldStatus = newStatus;
} }
} }

View File

@ -1,3 +1,8 @@
#ifndef _WMANAGER_H
#define _WMANAGER_H
void init_WifiManager(); void init_WifiManager();
void wifiManagerProcess(); void wifiManagerProcess();
void reset_configurations(); void reset_configuration();
#endif // _WMANAGER_H