Code refactoring & upgrades

- Added new button funcion to access config without losing current configuration
- Added code to change screens
- Added socket connection checker to reconnect even if socket is connected but no NOTIFY data is gotten on more than 2 minutes
This commit is contained in:
BitMaker 2023-06-07 10:51:46 +02:00
parent 622bf32ffa
commit 9139fa7a18
5 changed files with 199 additions and 93 deletions

View File

@ -63,7 +63,8 @@ Optional you can select other pool:
### Buttons ### Buttons
With the USB-C port to the right: With the USB-C port to the right:
- The top button allows you to **reset the configurations and reboot** your NerdMiner. Just hold it for 5 seconds. - Hold top right button and power up to enter **configuration mode** and edit current config via Wifi.
- During normal operation hold 5 seconds top right button to **reset the configurations and reboot** your NerdMiner.
- Click the bottom button once to turn the screen off and on again - Click the bottom button once to turn the screen off and on again
- Double click to change the orientation (default is USB-C to the right) - Double click to change the orientation (default is USB-C to the right)
@ -84,7 +85,7 @@ With the USB-C port to the right:
- [x] Bug Reboots when received JSON contains some null values - [x] Bug Reboots when received JSON contains some null values
- [x] Implement midstate sha256 - [x] Implement midstate sha256
- [x] Bug Wificlient DNS unresolved on Wifi.h - [x] Bug Wificlient DNS unresolved on Wifi.h
- [ ] Code refactoring - [x] Code refactoring
- [ ] Add blockHeight to screen - [ ] Add blockHeight to screen
- [ ] Add clock to show current time - [ ] Add clock to show current time
- [ ] Add new screen with global mining stats - [ ] Add new screen with global mining stats

View File

@ -11,16 +11,17 @@
#include "stratum.h" #include "stratum.h"
#include "mining.h" #include "mining.h"
#include "utils.h" #include "utils.h"
#include "monitor.h"
static unsigned long templates = 0; unsigned long templates = 0;
static unsigned long hashes= 0; unsigned long hashes= 0;
static unsigned long Mhashes = 0; unsigned long Mhashes = 0;
static unsigned long totalKHashes = 0; unsigned long totalKHashes = 0;
static String temp; unsigned long elapsedKHs = 0;
static int halfshares; // increase if blockhash has 16 bits of zeroes unsigned long halfshares; // increase if blockhash has 16 bits of zeroes
static int shares; // increase if blockhash has 32 bits of zeroes unsigned int shares; // increase if blockhash has 32 bits of zeroes
static int valids; // increased if blockhash <= target unsigned int valids; // increased if blockhash <= target
// Variables to hold data from custom textboxes // Variables to hold data from custom textboxes
extern char poolString[80]; extern char poolString[80];
@ -35,6 +36,9 @@ static WiFiClient client;
static miner_data mMiner; //Global miner data (Create a miner class TODO) static miner_data mMiner; //Global miner data (Create a miner class TODO)
mining_subscribe mWorker; mining_subscribe mWorker;
mining_job mJob; mining_job mJob;
monitor_data mMonitor;
bool isMinerSuscribed = false;
void checkPoolConnection(bool* isMinerSuscribed) { void checkPoolConnection(bool* isMinerSuscribed) {
@ -54,6 +58,25 @@ void checkPoolConnection(bool* isMinerSuscribed) {
} }
} }
//Checks if pool is not sending any data and reconnects again
//verifies it even connection is alive, because pool could be stopped sending NOTIFY
unsigned long mStart0Hashrate = 0;
bool checkPoolInactivity(unsigned long inactivityTime){
unsigned long currentKHashes = (Mhashes*1000) + hashes/1000;
unsigned long elapsedKHs = currentKHashes - totalKHashes;
if(elapsedKHs == 0){
//Check if hashrate is 0 during inactivityTIme
if(mStart0Hashrate == 0) mStart0Hashrate = millis();
if((millis()-mStart0Hashrate) > inactivityTime) { mStart0Hashrate=0; return true;}
return false;
}
mStart0Hashrate = 0;
return false;
}
void runStratumWorker(void *name) { void runStratumWorker(void *name) {
// TEST: https://bitcoin.stackexchange.com/questions/22929/full-example-data-for-scrypt-stratum-client // TEST: https://bitcoin.stackexchange.com/questions/22929/full-example-data-for-scrypt-stratum-client
@ -69,8 +92,6 @@ void runStratumWorker(void *name) {
float currentPoolDifficulty = atof(DEFAULT_DIFFICULTY); float currentPoolDifficulty = atof(DEFAULT_DIFFICULTY);
bool isMinerSuscribed = false;
while(true) { while(true) {
if(WiFi.status() != WL_CONNECTED){ if(WiFi.status() != WL_CONNECTED){
@ -89,8 +110,8 @@ void runStratumWorker(void *name) {
//portNumber = 3333; //portNumber = 3333;
//strcpy(btcString,"Bitmaker.01"); //strcpy(btcString,"Bitmaker.01");
//CKpool //CKpool
//strcpy(poolString, "solo.ckpool.org"); strcpy(poolString, "solo.ckpool.org");
//portNumber = 3333; portNumber = 3333;
//strcpy(btcString,"test"); //strcpy(btcString,"test");
checkPoolConnection(&isMinerSuscribed); checkPoolConnection(&isMinerSuscribed);
@ -117,6 +138,15 @@ void runStratumWorker(void *name) {
isMinerSuscribed=true; isMinerSuscribed=true;
} }
//Check if pool is down for almost 5minutes and then restart connection with pool (5min=300000ms)
if(checkPoolInactivity(120000)){
//Restart connection
Serial.println(" Detected more than 2 min without data form stratum server. Closing socket and reopening...");
client.stop();
isMinerSuscribed=false;
continue;
}
//Read pending messages from pool //Read pending messages from pool
while(client.connected() && client.available()){ while(client.connected() && client.available()){
@ -249,8 +279,12 @@ void runMiner(void * name){
mbedtls_sha256_free(&ctx); mbedtls_sha256_free(&ctx);
mbedtls_sha256_free(midstate); mbedtls_sha256_free(midstate);
// TODO Pending doub mMiner.inRun = false;
if(hashes>=MAX_NONCE) { Mhashes=Mhashes+MAX_NONCE/1000000; hashes=hashes-MAX_NONCE;}
if(hashes>=MAX_NONCE) {
Mhashes=Mhashes+MAX_NONCE/1000000;
hashes=hashes-MAX_NONCE;
}
uint32_t duration = micros() - startT; uint32_t duration = micros() - startT;
} }
@ -263,87 +297,27 @@ void runMonitor(void *name){
unsigned long mLastCheck = 0; unsigned long mLastCheck = 0;
while(1){ while(1){
background.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen);
unsigned long mElapsed = millis()-mLastCheck; unsigned long mElapsed = millis()-mLastCheck;
mLastCheck = millis(); mLastCheck = millis();
unsigned long currentKHashes = (Mhashes*1000) + hashes/1000; unsigned long currentKHashes = (Mhashes*1000) + hashes/1000;
unsigned long elapsedKHs = currentKHashes - totalKHashes; elapsedKHs = currentKHashes - totalKHashes;
totalKHashes = currentKHashes; totalKHashes = currentKHashes;
//Serial.println("[runMonitor Task] -> Printing results on screen ");
Serial.printf(">>> Completed %d share(s), %d Khashes, avg. hashrate %.3f KH/s\n", switch(mMonitor.screen){
shares, totalKHashes, (1.0*(elapsedKHs*1000))/mElapsed); case SCREEN_MINING: show_MinerScreen(mElapsed); break;
}
//Hashrate
render.setFontSize(70);
render.setCursor(19, 118);
render.setFontColor(TFT_BLACK);
char tmp[10] = {0};
sprintf(tmp, "%.2f", (1.0*(elapsedKHs*1000))/mElapsed);
render.rdrawString(tmp, 118, 114, TFT_BLACK);
//Total hashes
render.setFontSize(36);
render.rdrawString(String(Mhashes).c_str(), 268, 138, TFT_BLACK);
//Block templates
render.setFontSize(36);
render.drawString(String(templates).c_str(), 186, 20, 0xDEDB);
//16Bit shares
render.setFontSize(36);
render.drawString(String(halfshares).c_str(), 186, 48, 0xDEDB);
//32Bit shares
render.setFontSize(36);
render.drawString(String(shares).c_str(), 186, 76, 0xDEDB);
//Hores
unsigned long secElapsed=millis()/1000;
int hr = secElapsed/3600; //Number of seconds in an hour
int mins = (secElapsed-(hr*3600))/60; //Remove the number of hours and calculate the minutes.
int sec = secElapsed-(hr*3600)-(mins*60);
render.setFontSize(36);
render.rdrawString(String(hr).c_str(), 208, 99, 0xDEDB);
//Minutss
render.setFontSize(36);
render.rdrawString(String(mins).c_str(), 253, 99, 0xDEDB);
//Segons
render.setFontSize(36);
render.rdrawString(String(sec).c_str(), 298, 99, 0xDEDB);
//Valid Blocks
render.setFontSize(48);
render.drawString(String(valids).c_str(), 285, 56, 0xDEDB);
//Print Temp
//background.setTextColor(TFT_BLACK);
//background.setFreeFont(FF0);
//background.drawString("30", 230, 4);
//Print Hour
//background.drawString("22:10", 250, 4);
//Print Temp
temp = String(temperatureRead(), 0);
render.setFontSize(20);
render.rdrawString(String(temp).c_str(), 239, 1, TFT_BLACK);
render.setFontSize(7);
render.rdrawString(String(0).c_str(), 244, 3, TFT_BLACK);
//Print Hour
render.setFontSize(20);
render.rdrawString(String(printLocalTime()).c_str(), 286, 1, TFT_BLACK);
//Push prepared background to screen
background.pushSprite(0,0);
//Monitor state when hashrate is 0.0
if(elapsedKHs == 0) {
Serial.printf(">>> [i] Miner: newJob>%s / inRun>%s) - Client: connected>%s / subscribed>%s / wificonnected>%s\n",
mMiner.newJob ? "true" : "false", mMiner.inRun ? "true" : "false",
client.connected() ? "true" : "false", isMinerSuscribed ? "true" : "false", WiFi.status() == WL_CONNECTED ? "true" : "false");
}
// Pause the task for 5000ms // Pause the task for 5000ms
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
} }
} }
String printLocalTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return "00:00";
}
char LocalHour[80];
strftime (LocalHour, 80, "%H:%M", &timeinfo); //4 digit year, 2 digit month
String mystring(LocalHour);
return LocalHour;
}

106
src/monitor.cpp Normal file
View File

@ -0,0 +1,106 @@
#include <Arduino.h>
#include <WiFi.h>
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
#include "media/Free_Fonts.h"
#include "media/images.h"
#include "mbedtls/md.h"
#include "OpenFontRender.h"
#include "mining.h"
#include "utils.h"
#include "monitor.h"
extern unsigned long templates;
extern unsigned long hashes;
extern unsigned long Mhashes;
extern unsigned long totalKHashes;
extern unsigned long elapsedKHs;
extern unsigned long halfshares; // increase if blockhash has 16 bits of zeroes
extern unsigned int shares; // increase if blockhash has 32 bits of zeroes
extern unsigned int valids; // increased if blockhash <= targethalfshares
extern OpenFontRender render;
extern TFT_eSprite background;
extern monitor_data mMonitor;
String printLocalTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return "00:00";
}
char LocalHour[80];
strftime (LocalHour, 80, "%H:%M", &timeinfo); //4 digit year, 2 digit month
String mystring(LocalHour);
return LocalHour;
}
void show_MinerScreen(unsigned long mElapsed){
//Print background screen
background.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen);
char CurrentHashrate[10] = {0};
sprintf(CurrentHashrate, "%.2f", (1.0*(elapsedKHs*1000))/mElapsed);
//Serial.println("[runMonitor Task] -> Printing results on screen ");
Serial.printf(">>> Completed %d share(s), %d Khashes, avg. hashrate %s KH/s\n",
shares, totalKHashes, CurrentHashrate);
//Hashrate
render.setFontSize(70);
render.setCursor(19, 118);
render.setFontColor(TFT_BLACK);
render.rdrawString(CurrentHashrate, 118, 114, TFT_BLACK);
//Total hashes
render.setFontSize(36);
render.rdrawString(String(Mhashes).c_str(), 268, 138, TFT_BLACK);
//Block templates
render.setFontSize(36);
render.drawString(String(templates).c_str(), 186, 20, 0xDEDB);
//16Bit shares
render.setFontSize(36);
render.drawString(String(halfshares).c_str(), 186, 48, 0xDEDB);
//32Bit shares
render.setFontSize(36);
render.drawString(String(shares).c_str(), 186, 76, 0xDEDB);
//Hores
unsigned long secElapsed=millis()/1000;
int hr = secElapsed/3600; //Number of seconds in an hour
int mins = (secElapsed-(hr*3600))/60; //Remove the number of hours and calculate the minutes.
int sec = secElapsed-(hr*3600)-(mins*60);
render.setFontSize(36);
render.rdrawString(String(hr).c_str(), 208, 99, 0xDEDB);
//Minutss
render.setFontSize(36);
render.rdrawString(String(mins).c_str(), 253, 99, 0xDEDB);
//Segons
render.setFontSize(36);
render.rdrawString(String(sec).c_str(), 298, 99, 0xDEDB);
//Valid Blocks
render.setFontSize(48);
render.drawString(String(valids).c_str(), 285, 56, 0xDEDB);
//Print Temp
//background.setTextColor(TFT_BLACK);
//background.setFreeFont(FF0);
//background.drawString("30", 230, 4);
//Print Hour
//background.drawString("22:10", 250, 4);
//Print Temp
String temp = String(temperatureRead(), 0);
render.setFontSize(20);
render.rdrawString(String(temp).c_str(), 239, 1, TFT_BLACK);
render.setFontSize(7);
render.rdrawString(String(0).c_str(), 244, 3, TFT_BLACK);
//Print Hour
render.setFontSize(20);
render.rdrawString(String(printLocalTime()).c_str(), 286, 1, TFT_BLACK);
//Push prepared background to screen
background.pushSprite(0,0);
}

28
src/monitor.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef MONITOR_API_H
#define MONITOR_API_H
#include <Arduino.h>
// Monitor states
#define SCREEN_MINING 0
#define SCREEN_CLOCK 1
#define SCREEN_BLOCK 2
typedef struct{
uint8_t screen;
bool rotation;
//Data gotten from minerWork
/* unsigned long templates;
unsigned long hashes;
unsigned long Mhashes;
unsigned long totalKHashes;
unsigned long halfshares; // increase if blockhash has 16 bits of zeroes
unsigned int shares; // increase if blockhash has 32 bits of zeroes
unsigned int valids; // increased if blockhash <= target
*/
}monitor_data;
void show_MinerScreen(unsigned long mElapsed);
#endif //MONITOR_API_H

View File

@ -18,14 +18,11 @@
uint8_t hex(char ch); uint8_t hex(char ch);
int to_byte_array(const char *in, size_t in_size, uint8_t *out); int to_byte_array(const char *in, size_t in_size, uint8_t *out);
double le256todouble(const void *target); double le256todouble(const void *target);
double diff_from_target(void *target); double diff_from_target(void *target);
miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob); miner_data calculateMiningData(mining_subscribe& mWorker, mining_job mJob);
bool checkValid(unsigned char* hash, unsigned char* target); bool checkValid(unsigned char* hash, unsigned char* target);
#endif // UTILS_API_H #endif // UTILS_API_H