Merge pull request #197 from BitMaker-hub/dev
New board, sd card config, touch control
This commit is contained in:
commit
68c088f30a
3
.gitignore
vendored
3
.gitignore
vendored
@ -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
|
||||||
|
64
README.md
64
README.md
@ -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
|
||||||
|
@ -375,7 +375,7 @@ SPI3_HOST = 2
|
|||||||
if ( c & 0x20 ) xset_mask[c] |= (1 << (TFT_D5-MASK_OFFSET)); \
|
if ( c & 0x20 ) xset_mask[c] |= (1 << (TFT_D5-MASK_OFFSET)); \
|
||||||
if ( c & 0x40 ) xset_mask[c] |= (1 << (TFT_D6-MASK_OFFSET)); \
|
if ( c & 0x40 ) xset_mask[c] |= (1 << (TFT_D6-MASK_OFFSET)); \
|
||||||
if ( c & 0x80 ) xset_mask[c] |= (1 << (TFT_D7-MASK_OFFSET)); \
|
if ( c & 0x80 ) xset_mask[c] |= (1 << (TFT_D7-MASK_OFFSET)); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
// Mask for the 8 data bits to set pin directions
|
// 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)))
|
#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)))
|
||||||
|
@ -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
|
||||||
|
56
lib/TFT_eSPI/User_Setups/Setup212_ESP32Cam_DongleDisplay.h
Normal file
56
lib/TFT_eSPI/User_Setups/Setup212_ESP32Cam_DongleDisplay.h
Normal 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
|
@ -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
|
||||||
|
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
#ifdef MONITOR_SPEED
|
||||||
|
Serial.begin(MONITOR_SPEED);
|
||||||
|
#else
|
||||||
|
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 ************/
|
||||||
|
27
src/drivers/devices/device.h
Normal file
27
src/drivers/devices/device.h
Normal 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__
|
36
src/drivers/devices/esp32CAM.h
Normal file
36
src/drivers/devices/esp32CAM.h
Normal 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_
|
@ -1,4 +1,4 @@
|
|||||||
#include "../drivers.h"
|
#include "DisplayDriver.h"
|
||||||
|
|
||||||
#ifdef AMOLED_DISPLAY
|
#ifdef AMOLED_DISPLAY
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
@ -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_
|
@ -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);
|
||||||
|
@ -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);
|
||||||
background.pushImage(0, 0, 320, 70, bottonPoolScreen);
|
if (bottomScreenBlue) {
|
||||||
|
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,97 +185,72 @@ 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
|
||||||
printheap();
|
printheap();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../drivers.h"
|
#include "DisplayDriver.h"
|
||||||
|
|
||||||
#ifdef NO_DISPLAY
|
#ifdef NO_DISPLAY
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../drivers.h"
|
#include "DisplayDriver.h"
|
||||||
|
|
||||||
#ifdef T_DISPLAY
|
#ifdef T_DISPLAY
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../drivers.h"
|
#include "DisplayDriver.h"
|
||||||
|
|
||||||
#ifdef V1_DISPLAY
|
#ifdef V1_DISPLAY
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "../drivers.h"
|
#include "DisplayDriver.h"
|
||||||
|
|
||||||
#ifdef T_QT_DISPLAY
|
#ifdef T_QT_DISPLAY
|
||||||
|
|
||||||
|
195
src/drivers/storage/SDCard.cpp
Normal file
195
src/drivers/storage/SDCard.cpp
Normal 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
|
71
src/drivers/storage/SDCard.h
Normal file
71
src/drivers/storage/SDCard.h
Normal 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_
|
155
src/drivers/storage/nvMemory.cpp
Normal file
155
src/drivers/storage/nvMemory.cpp
Normal 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
|
28
src/drivers/storage/nvMemory.h
Normal file
28
src/drivers/storage/nvMemory.h
Normal 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_
|
48
src/drivers/storage/storage.h
Normal file
48
src/drivers/storage/storage.h
Normal 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
@ -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);
|
||||||
@ -447,12 +447,12 @@ void runMonitor(void *name)
|
|||||||
if (elapsedKHs == 0)
|
if (elapsedKHs == 0)
|
||||||
{
|
{
|
||||||
Serial.printf(">>> [i] Miner: newJob>%s / inRun>%s) - Client: connected>%s / subscribed>%s / wificonnected>%s\n",
|
Serial.printf(">>> [i] Miner: newJob>%s / inRun>%s) - Client: connected>%s / subscribed>%s / wificonnected>%s\n",
|
||||||
mMiner.newJob ? "true" : "false", mMiner.inRun ? "true" : "false",
|
mMiner.newJob ? "true" : "false", mMiner.inRun ? "true" : "false",
|
||||||
client.connected() ? "true" : "false", isMinerSuscribed ? "true" : "false", WiFi.status() == WL_CONNECTED ? "true" : "false");
|
client.connected() ? "true" : "false", isMinerSuscribed ? "true" : "false", WiFi.status() == WL_CONNECTED ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
#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
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
421
src/wManager.cpp
421
src/wManager.cpp
@ -2,220 +2,150 @@
|
|||||||
|
|
||||||
// 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
|
||||||
{
|
{
|
||||||
Serial.println("Should save config");
|
Serial.println("Should save config");
|
||||||
shouldSaveConfig = true;
|
shouldSaveConfig = true;
|
||||||
//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");
|
||||||
|
|
||||||
Serial.print("Config SSID: ");
|
Serial.print("Config SSID: ");
|
||||||
Serial.println(myWiFiManager->getConfigPortalSSID());
|
Serial.println(myWiFiManager->getConfigPortalSSID());
|
||||||
|
|
||||||
Serial.print("Config IP Address: ");
|
Serial.print("Config IP Address: ");
|
||||||
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()
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
#ifdef MONITOR_SPEED
|
||||||
//Serial.setTxTimeoutMs(10);
|
Serial.begin(MONITOR_SPEED);
|
||||||
|
#else
|
||||||
|
Serial.begin(115200);
|
||||||
|
#endif //MONITOR_SPEED
|
||||||
|
//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
|
||||||
|
// Explicitly set WiFi mode
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
|
||||||
bool spiffsSetup = loadConfigFile();
|
if (!nvMem.loadConfig(&Settings))
|
||||||
if (!spiffsSetup)
|
{
|
||||||
{
|
//No config file on internal flash.
|
||||||
Serial.println(F("Forcing config mode as there is no saved config"));
|
if (SDCrd.loadConfigFile(&Settings))
|
||||||
forceConfig = true;
|
{
|
||||||
|
//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)
|
||||||
|
//wm.resetSettings();
|
||||||
|
|
||||||
// Explicitly set WiFi mode
|
//Set dark theme
|
||||||
WiFi.mode(WIFI_STA);
|
//wm.setClass("invert"); // dark theme
|
||||||
|
|
||||||
// Reset settings (only for development)
|
// Set config save notify callback
|
||||||
//wm.resetSettings();
|
wm.setSaveConfigCallback(saveConfigCallback);
|
||||||
|
|
||||||
//Set dark theme
|
// Set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
|
||||||
//wm.setClass("invert"); // dark theme
|
wm.setAPCallback(configModeCallback);
|
||||||
|
|
||||||
// Set config save notify callback
|
//Advanced settings
|
||||||
wm.setSaveConfigCallback(saveConfigCallback);
|
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
|
||||||
|
|
||||||
// Set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
|
// Custom elements
|
||||||
wm.setAPCallback(configModeCallback);
|
|
||||||
|
|
||||||
//Advanced settings
|
// Text box (String) - 80 characters maximum
|
||||||
wm.setConfigPortalBlocking(false); //Hacemos que el portal no bloquee el firmware
|
WiFiManagerParameter pool_text_box("Poolurl", "Pool url", Settings.PoolAddress.c_str(), 80);
|
||||||
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
|
// Need to convert numerical input to string to display the default value.
|
||||||
|
char convertedValue[6];
|
||||||
|
sprintf(convertedValue, "%d", Settings.PoolPort);
|
||||||
|
|
||||||
// Text box (String) - 80 characters maximum
|
// Text box (Number) - 7 characters maximum
|
||||||
WiFiManagerParameter pool_text_box("Poolurl", "Pool url", poolString, 80);
|
WiFiManagerParameter port_text_box_num("Poolport", "Pool port", convertedValue, 7);
|
||||||
|
|
||||||
// Need to convert numerical input to string to display the default value.
|
// Text box (String) - 80 characters maximum
|
||||||
char convertedValue[6];
|
WiFiManagerParameter addr_text_box("btcAddress", "Your BTC address", Settings.BtcWallet, 80);
|
||||||
sprintf(convertedValue, "%d", portNumber);
|
|
||||||
|
|
||||||
// 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", btcString, 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");
|
||||||
}
|
}
|
||||||
@ -229,109 +159,104 @@ void init_WifiManager()
|
|||||||
wm.addParameter(&features_html);
|
wm.addParameter(&features_html);
|
||||||
wm.addParameter(&save_stats_to_nvs);
|
wm.addParameter(&save_stats_to_nvs);
|
||||||
|
|
||||||
Serial.println("AllDone: ");
|
Serial.println("AllDone: ");
|
||||||
if (forceConfig)
|
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("failed to connect and hit timeout");
|
// Run if we need a configuration
|
||||||
//Could be break forced after edditing, so save new config
|
//No configuramos timeout al modulo
|
||||||
strncpy(poolString, pool_text_box.getValue(), sizeof(poolString));
|
wm.setConfigPortalBlocking(true); //Hacemos que el portal SI bloquee el firmware
|
||||||
portNumber = atoi(port_text_box_num.getValue());
|
drawSetupScreen();
|
||||||
strncpy(btcString, addr_text_box.getValue(), sizeof(btcString));
|
|
||||||
GMTzone = atoi(time_text_box_num.getValue());
|
if (wm.startConfigPortal(DEFAULT_SSID, DEFAULT_WIFIPW))
|
||||||
saveStatsToNVS = (strncmp(save_stats_to_nvs.getValue(), "T", 1) == 0);
|
{
|
||||||
saveConfigFile();
|
//Could be break forced after edditing, so save new config
|
||||||
delay(3000);
|
Serial.println("failed to connect and hit timeout");
|
||||||
//reset and try again, or maybe put it to deep sleep
|
Settings.PoolAddress = pool_text_box.getValue();
|
||||||
ESP.restart();
|
Settings.PoolPort = atoi(port_text_box_num.getValue());
|
||||||
delay(5000);
|
strncpy(Settings.BtcWallet, addr_text_box.getValue(), sizeof(Settings.BtcWallet));
|
||||||
|
Settings.Timezone = atoi(time_text_box_num.getValue());
|
||||||
|
Serial.println(save_stats_to_nvs.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
|
||||||
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;
|
||||||
|
wm.setCaptivePortalEnable(false); // disable captive portal redirection
|
||||||
|
if (!wm.autoConnect(Settings.WifiSSID.c_str(), Settings.WifiPW.c_str()))
|
||||||
|
{
|
||||||
|
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;
|
mMonitor.NerdStatus = NM_Connecting;
|
||||||
wm.setCaptivePortalEnable(false); // disable captive portal redirection
|
|
||||||
if (!wm.autoConnect("NerdMinerAP","MineYourCoins"))
|
//Conectado a la red Wifi
|
||||||
{
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
Serial.println("Failed to connect and hit timeout");
|
//tft.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen);
|
||||||
//delay(3000);
|
Serial.println("");
|
||||||
// if we still have not connected restart and try all over again
|
Serial.println("WiFi connected");
|
||||||
//ESP.restart();
|
Serial.print("IP address: ");
|
||||||
//delay(5000);
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
// Lets deal with the user config values
|
||||||
|
|
||||||
|
// Copy the string value
|
||||||
|
Settings.PoolAddress = pool_text_box.getValue();
|
||||||
|
//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;
|
// Save the custom parameters to FS
|
||||||
|
if (shouldSaveConfig)
|
||||||
//Conectado a la red Wifi
|
{
|
||||||
if(WiFi.status() == WL_CONNECTED){
|
nvMem.saveConfig(&Settings);
|
||||||
//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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
void wifiManagerProcess() {
|
void wifiManagerProcess() {
|
||||||
|
|
||||||
wm.process(); // avoid delays() in loop when non-blocking and other long running code
|
wm.process(); // avoid delays() in loop when non-blocking and other long running code
|
||||||
|
|
||||||
int newStatus = WiFi.status();
|
int newStatus = WiFi.status();
|
||||||
if (newStatus != oldStatus) {
|
if (newStatus != oldStatus) {
|
||||||
if (newStatus == WL_CONNECTED) {
|
if (newStatus == WL_CONNECTED) {
|
||||||
Serial.println("CONNECTED - Current ip: " + WiFi.localIP().toString());
|
Serial.println("CONNECTED - Current ip: " + WiFi.localIP().toString());
|
||||||
} else {
|
} else {
|
||||||
Serial.print("[Error] - current status: ");
|
Serial.print("[Error] - current status: ");
|
||||||
Serial.println(newStatus);
|
Serial.println(newStatus);
|
||||||
|
}
|
||||||
|
oldStatus = newStatus;
|
||||||
}
|
}
|
||||||
oldStatus = newStatus;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user