diff --git a/AVR_Miner.py b/AVR_Miner.py
index 8309d694..e242ce3b 100644
--- a/AVR_Miner.py
+++ b/AVR_Miner.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
-Duino-Coin Official AVR Miner 4.1 © MIT licensed
+Duino-Coin Official AVR Miner 4.2 © MIT licensed
https://duinocoin.com
https://github.com/revoxhere/duino-coin
Duino-Coin Team & Community 2019-2024
@@ -109,7 +109,7 @@ def port_num(com):
class Settings:
- VER = '4.1'
+ VER = '4.2'
SOC_TIMEOUT = 15
REPORT_TIME = 120
AVR_TIMEOUT = 10
@@ -266,6 +266,16 @@ def check_updates():
print(e)
sys.exit()
+
+def has_mining_key(username):
+ response = requests.get(
+ "https://server.duinocoin.com/mining_key"
+ + "?u=" + username,
+ timeout=10
+ ).json()
+ return response["has_key"]
+
+
def check_mining_key(user_settings):
user_settings = user_settings["AVR Miner"]
@@ -601,7 +611,7 @@ def title(title: str):
print('\33]0;' + title + '\a', end='')
sys.stdout.flush()
except Exception as e:
- print(e)
+ debug_output("Error setting title: " +str(e))
def handler(signal_received, frame):
@@ -653,13 +663,8 @@ def load_config():
if not correct_username:
print(get_string("incorrect_username"))
- response = requests.get(
- "https://server.duinocoin.com/mining_key"
- + "?u=" + username, timeout=10
- ).json()
-
mining_key = "None"
- if response["has_key"]:
+ if has_mining_key(username):
mining_key = input(Style.RESET_ALL + Fore.YELLOW
+ get_string("ask_mining_key")
+ Fore.RESET + Style.BRIGHT)
diff --git a/Arduino_Code/Arduino_Code.ino b/Arduino_Code/Arduino_Code.ino
index 697b56a0..1b6836ff 100644
--- a/Arduino_Code/Arduino_Code.ino
+++ b/Arduino_Code/Arduino_Code.ino
@@ -4,7 +4,7 @@
( _ \( )( )(_ _)( \( )( _ )___ / __)( _ )(_ _)( \( )
)(_) ))(__)( _)(_ ) ( )(_)((___)( (__ )(_)( _)(_ ) (
(____/(______)(____)(_)\_)(_____) \___)(_____)(____)(_)\_)
- Official code for Arduino boards (and relatives) version 4.1
+ Official code for Arduino boards (and relatives) version 4.2
Duino-Coin Team & Community 2019-2024 © MIT Licensed
https://duinocoin.com
diff --git a/ESP_Code/Dashboard.h b/ESP_Code/Dashboard.h
index f2349858..1e737174 100644
--- a/ESP_Code/Dashboard.h
+++ b/ESP_Code/Dashboard.h
@@ -131,6 +131,7 @@ const char WEBSITE[] PROGMEM = R"=====(
github.com/revoxhere/duino-coin
+ @@RESET_SETTINGS@@
diff --git a/ESP_Code/DisplayHal.h b/ESP_Code/DisplayHal.h
new file mode 100644
index 00000000..dfde2490
--- /dev/null
+++ b/ESP_Code/DisplayHal.h
@@ -0,0 +1,296 @@
+// Abstraction layer for handling various types of screens
+// See Settings.h for enabling the screen of your choice
+#ifndef DISPLAY_HAL_H
+#define DISPLAY_HAL_H
+
+// Abstraction layer: custom fonts, images, etc.
+#if defined(DISPLAY_SSD1306)
+ static const unsigned char image_check_contour_bits[] U8X8_PROGMEM = {0x00,0x04,0x00,0x0a,0x04,0x11,0x8a,0x08,0x51,0x04,0x22,0x02,0x04,0x01,0x88,0x00,0x50,0x00,0x20,0x00};
+ static const unsigned char image_network_1_bar_bits[] U8X8_PROGMEM = {0x00,0x70,0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x57,0x00,0x55,0x00,0x55,0x00,0x55,0x70,0x55,0x50,0x55,0x50,0x55,0x50,0x55,0x57,0x55,0x57,0x55,0x77,0x77,0x00,0x00};
+ static const unsigned char image_network_2_bars_bits[] U8X8_PROGMEM = {0x00,0x70,0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x57,0x00,0x55,0x00,0x55,0x00,0x55,0x70,0x55,0x70,0x55,0x70,0x55,0x70,0x55,0x77,0x55,0x77,0x55,0x77,0x77,0x00,0x00};
+ static const unsigned char image_network_3_bars_bits[] U8X8_PROGMEM = {0x00,0x70,0x00,0x50,0x00,0x50,0x00,0x50,0x00,0x57,0x00,0x57,0x00,0x57,0x00,0x57,0x70,0x57,0x70,0x57,0x70,0x57,0x70,0x57,0x77,0x57,0x77,0x57,0x77,0x77,0x00,0x00};
+ static const unsigned char image_network_4_bars_bits[] U8X8_PROGMEM = {0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x77,0x00,0x77,0x00,0x77,0x00,0x77,0x70,0x77,0x70,0x77,0x70,0x77,0x70,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x00,0x00};
+ static const unsigned char image_duco_logo_bits[] U8X8_PROGMEM = {0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0xff,0x00,0xc0,0x01,0x9f,0x01,0x20,0x01,0x20,0x01,0x20,0x01,0x9f,0x01,0xc0,0x01,0xff,0x00,0x7f,0x00};
+ static const unsigned char image_duco_logo_big_bits[] U8X8_PROGMEM = {0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0x01,0x00,0x00,0xfc,0xff,0xff,0x0f,0x00,0x00,0xfc,0xff,0xff,0x3f,0x00,0x00,0xfc,0xff,0xff,0x7f,0x00,0x00,0xfc,0xff,0xff,0xff,0x00,0x00,0xfc,0xff,0xff,0xff,0x01,0x00,0xfc,0xff,0xff,0xff,0x03,0x00,0xf8,0xff,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0xfe,0x0f,0x00,0xfc,0xff,0x03,0xf8,0x0f,0x00,0xfc,0xff,0x0f,0xf0,0x1f,0x00,0xfc,0xff,0x1f,0xe0,0x1f,0x00,0xfc,0xff,0x3f,0xe0,0x3f,0x00,0xfc,0xff,0x7f,0xc0,0x3f,0x00,0xfc,0xff,0xff,0xc0,0x7f,0x00,0xf8,0xff,0xff,0x80,0x7f,0x00,0x00,0x00,0xfe,0x80,0x7f,0x00,0x00,0x00,0xfc,0x81,0x7f,0x00,0x00,0x00,0xfc,0x01,0x7f,0x00,0x00,0x00,0xfc,0x01,0xff,0x00,0x00,0x00,0xfc,0x01,0xff,0x00,0x00,0x00,0xfc,0x01,0xff,0x00,0x00,0x00,0xfc,0x01,0xff,0x00,0x00,0x00,0xfc,0x01,0xff,0x00,0x00,0x00,0xfc,0x81,0x7f,0x00,0x00,0x00,0xfe,0x81,0x7f,0x00,0x00,0x80,0xff,0x80,0x7f,0x00,0xfc,0xff,0xff,0xc0,0x7f,0x00,0xfc,0xff,0xff,0xc0,0x7f,0x00,0xfc,0xff,0x7f,0xe0,0x3f,0x00,0xfc,0xff,0x3f,0xf0,0x3f,0x00,0xfc,0xff,0x1f,0xf8,0x1f,0x00,0xfc,0xff,0x0f,0xfc,0x1f,0x00,0xf8,0xff,0x01,0xfe,0x0f,0x00,0x00,0x00,0xc0,0xff,0x0f,0x00,0xfc,0xff,0xff,0xff,0x07,0x00,0xfc,0xff,0xff,0xff,0x03,0x00,0xfc,0xff,0xff,0xff,0x01,0x00,0xfc,0xff,0xff,0xff,0x00,0x00,0xfc,0xff,0xff,0x7f,0x00,0x00,0xfc,0xff,0xff,0x1f,0x00,0x00,0xfc,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+#endif
+
+#if defined(DISPLAY_16X2)
+ static byte duco_logo[] = {0x1E, 0x01, 0x1D, 0x05, 0x1D, 0x01, 0x1E, 0x00};
+ static byte check_mark[] = {0x00, 0x00, 0x00, 0x01, 0x02,0x14, 0x08, 0x00};
+ static byte kh[] = {0x08, 0x0A, 0x0C, 0x0A, 0x00, 0x0A, 0x0E, 0x0A};
+ static byte msec[] = {0x0A, 0x15, 0x11, 0x06, 0x08, 0x04, 0x02, 0x0C};
+#endif
+
+ #if defined(DISPLAY_SSD1306)
+ void drawStrMultiline(const char *msg, int xloc, int yloc) {
+ //https://github.com/olikraus/u8g2/discussions/1479
+ int dspwidth = u8g2.getDisplayWidth();
+ int strwidth = 0;
+ char glyph[2]; glyph[1] = 0;
+
+ for (const char *ptr = msg, *lastblank = NULL; *ptr; ++ptr) {
+ while (xloc == 0 && *msg == ' ')
+ if (ptr == msg++) ++ptr;
+
+ glyph[0] = *ptr;
+ strwidth += u8g2.getStrWidth(glyph);
+ if (*ptr == ' ') lastblank = ptr;
+ else ++strwidth;
+
+ if (xloc + strwidth > dspwidth) {
+ int starting_xloc = xloc;
+ while (msg < (lastblank ? lastblank : ptr)) {
+ glyph[0] = *msg++;
+ xloc += u8g2.drawStr(xloc, yloc, glyph);
+ }
+
+ strwidth -= xloc - starting_xloc;
+ yloc += u8g2.getMaxCharHeight();
+ xloc = 0; lastblank = NULL;
+ }
+ }
+ while (*msg) {
+ glyph[0] = *msg++;
+ xloc += u8g2.drawStr(xloc, yloc, glyph);
+ }
+ }
+#endif
+
+#if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ void screen_setup() {
+ // Ran during setup()
+ // Abstraction layer: screen initialization
+
+ #if defined(DISPLAY_SSD1306)
+ u8g2.begin();
+ u8g2.clearBuffer();
+ u8g2.setFontMode(1);
+ u8g2.setBitmapMode(1);
+ u8g2.sendBuffer();
+ #endif
+
+ #if defined(DISPLAY_16X2)
+ lcd.begin(16, 2);
+ lcd.createChar(0, duco_logo);
+ lcd.createChar(1, check_mark);
+ lcd.createChar(2, kh);
+ lcd.createChar(3, msec);
+ lcd.home();
+ lcd.clear();
+ #endif
+ }
+
+
+ void display_boot() {
+ // Abstraction layer: compilation time, features, etc.
+
+ #if defined(DISPLAY_16X2)
+ lcd.clear();
+ #if defined(ESP8266)
+ lcd.print("ESP8266 ");
+ #elif defined(CONFIG_FREERTOS_UNICORE)
+ lcd.print("ESP32S2 ");
+ #else
+ lcd.print("ESP32 ");
+ #endif
+ #if defined(ESP8266)
+ lcd.print(String(ESP.getCpuFreqMHz()).c_str());
+ #else
+ lcd.print(String(getCpuFrequencyMhz()).c_str());
+ #endif
+ lcd.print(" MHz");
+
+ lcd.setCursor(0, 1);
+ lcd.print(__DATE__);
+ #endif
+
+ #if defined(DISPLAY_SSD1306)
+ u8g2.clearBuffer();
+
+ u8g2.setFont(u8g2_font_profont15_tr);
+ u8g2.setCursor(2, 13);
+ #if defined(ESP8266)
+ u8g2.print("ESP8266 ");
+ #elif defined(CONFIG_FREERTOS_UNICORE)
+ u8g2.print("ESP32S2/C3 ");
+ #else
+ u8g2.print("ESP32 ");
+ #endif
+
+ #if defined(ESP8266)
+ u8g2.print(String(ESP.getCpuFreqMHz()).c_str());
+ #else
+ u8g2.print(String(getCpuFrequencyMhz()).c_str());
+ #endif
+ u8g2.print(" MHz");
+
+ u8g2.setFont(u8g2_font_profont10_tr);
+ u8g2.drawLine(1, 27, 126, 27);
+ u8g2.setCursor(2, 24);
+ u8g2.print("Compiled ");
+ u8g2.print(__DATE__);
+
+
+ u8g2.drawStr(2, 37, "Features:");
+ u8g2.setCursor(2, 46);
+ String features_str = "OTA ";
+ #if defined(USE_LAN)
+ features_str += "LAN ";
+ #endif
+ #if defined(LED_BLINKING)
+ features_str += "Blink ";
+ #endif
+ #if defined(SERIAL_PRINTING)
+ features_str += "Serial ";
+ #endif
+ #if defined(WEB_DASHBOARD)
+ features_str += "Webserver ";
+ #endif
+ #if defined(DISPLAY_16X2)
+ features_str += "LCD16X2 ";
+ #endif
+ #if defined(DISPLAY_SSD1306)
+ features_str += "SSD1306 ";
+ #endif
+ #if defined(USE_INTERNAL_SENSOR)
+ features_str += "Int. sensor ";
+ #endif
+ #if defined(USE_DS18B20)
+ features_str += "DS18B20 ";
+ #endif
+ #if defined(USE_DHT)
+ features_str += "DHT ";
+ #endif
+ #if defined(USE_HSU07M)
+ features_str += "HSU07M ";
+ #endif
+ drawStrMultiline(features_str.c_str(), 2, 46);
+ u8g2.sendBuffer();
+ #endif
+ }
+
+ void display_info(String message) {
+ // Abstraction layer: info screens (setups)
+
+ #if defined(DISPLAY_SSD1306)
+ u8g2.clearBuffer();
+ u8g2.drawXBMP(-1, 3, 41, 45, image_duco_logo_big_bits);
+ u8g2.setFont(u8g2_font_t0_16b_tr);
+ #if defined(ESP8266)
+ u8g2.drawStr(42, 27, "ESP8266");
+ #elif defined(CONFIG_FREERTOS_UNICORE)
+ u8g2.drawStr(42, 27, "ESP32S2/C3");
+ #else
+ u8g2.drawStr(42, 27, "ESP32");
+ #endif
+ u8g2.setFont(u8g2_font_t0_13b_tr);
+ u8g2.drawStr(41, 14, "Duino-Coin");
+ u8g2.setFont(u8g2_font_6x10_tr);
+ u8g2.drawStr(98, 36, "MINER");
+ u8g2.setFont(u8g2_font_6x13_tr);
+ u8g2.drawStr(1, 60, message.c_str());
+ u8g2.setFont(u8g2_font_5x8_tr);
+ u8g2.drawStr(42, 46, "www.duinocoin.com");
+ u8g2.setFont(u8g2_font_4x6_tr);
+ u8g2.drawStr(116, 14, String(SOFTWARE_VERSION).c_str());
+ u8g2.sendBuffer();
+ #endif
+
+ #if defined(DISPLAY_16X2)
+ lcd.clear();
+ lcd.setCursor(0, 0);
+ lcd.write(0);
+ lcd.print(" Duino-Coin ");
+ lcd.print(SOFTWARE_VERSION);
+ lcd.setCursor(0, 1);
+ lcd.print(message);
+ #endif
+ }
+
+
+ void display_mining_results(String hashrate, String accepted_shares, String total_shares, String uptime, String node,
+ String difficulty, String sharerate, String ping, String accept_rate) {
+ // Ran after each found share
+ // Abstraction layer: displaying mining results
+ Serial.println("Displaying mining results");
+
+ #if defined(DISPLAY_SSD1306)
+ u8g2.clearBuffer();
+ u8g2.setFont(u8g2_font_profont10_tr);
+ u8g2.drawStr(67, 26, "kH");
+ if (hashrate.toFloat() < 100.0) {
+ u8g2.setFont(u8g2_font_profont29_tr);
+ u8g2.drawStr(2, 36, hashrate.c_str());
+ } else {
+ u8g2.setFont(u8g2_font_profont22_tr);
+ u8g2.drawStr(3, 35, hashrate.c_str());
+ }
+
+ u8g2.setFont(u8g2_font_haxrcorp4089_tr);
+ u8g2.drawStr(52, 12, node.c_str());
+
+ u8g2.setFont(u8g2_font_t0_11_tr);
+ u8g2.drawStr(17, 47, (accepted_shares + "/" + total_shares).c_str());
+ u8g2.setFont(u8g2_font_5x7_tr);
+ u8g2.drawStr(88, 47, ("(" + accept_rate + "%)").c_str());
+
+ u8g2.setFont(u8g2_font_profont12_tr);
+ u8g2.drawStr(20, 12, (ping + "ms").c_str());
+ u8g2.drawStr(69, 36, "s");
+
+ u8g2.setFont(u8g2_font_6x13_tr);
+ u8g2.drawStr(125-u8g2.getStrWidth(uptime.c_str()), 61, uptime.c_str());
+
+ u8g2.drawStr(85, 38, sharerate.c_str());
+ u8g2.drawStr(85, 27, difficulty.c_str());
+ u8g2.drawLine(67, 28, 75, 28);
+
+ u8g2.drawXBMP(2, 38, 13, 10, image_check_contour_bits);
+
+ if (WiFi.RSSI() > -40) {
+ u8g2.drawXBMP(1, 0, 15, 16, image_network_4_bars_bits);
+ } else if (WiFi.RSSI() > -60) {
+ u8g2.drawXBMP(1, 0, 15, 16, image_network_3_bars_bits);
+ } else if (WiFi.RSSI() > -75) {
+ u8g2.drawXBMP(1, 0, 15, 16, image_network_2_bars_bits);
+ } else {
+ u8g2.drawXBMP(1, 0, 15, 16, image_network_1_bar_bits);
+ }
+
+ u8g2.setFont(u8g2_font_4x6_tr);
+ u8g2.drawStr(14, 61, String(WiFi.localIP().toString()).c_str());
+ u8g2.drawStr(14, 55, ("Duino-Coin " + String(SOFTWARE_VERSION)).c_str());
+ u8g2.drawXBMP(2, 11, 9, 50, image_duco_logo_bits);
+ u8g2.drawStr(111, 27, "diff");
+ u8g2.drawStr(107, 38, "shr/s");
+
+ u8g2.sendBuffer();
+ #endif
+
+ #if defined(DISPLAY_16X2)
+ lcd.clear();
+ lcd.setCursor(0,0);
+ lcd.print(hashrate);
+ lcd.setCursor(4,0);
+ lcd.write(2); // kh
+
+ lcd.setCursor(7, 0);
+ lcd.print(difficulty);
+ lcd.print(" diff");
+
+ lcd.setCursor(0, 1);
+ lcd.write(1); // checkmark
+ lcd.print(accepted_shares);
+
+ lcd.setCursor(7, 1);
+ lcd.print(ping);
+ lcd.write(3); // ms
+
+ lcd.setCursor(12, 1);
+ lcd.print(sharerate);
+ lcd.print("s");
+ #endif
+ }
+#endif
+
+#endif
diff --git a/ESP_Code/ESP_Code.ino b/ESP_Code/ESP_Code.ino
index 64ba34d1..690f01f6 100644
--- a/ESP_Code/ESP_Code.ino
+++ b/ESP_Code/ESP_Code.ino
@@ -3,7 +3,7 @@
( _ \( )( )(_ _)( \( )( _ )___ / __)( _ )(_ _)( \( )
)(_) ))(__)( _)(_ ) ( )(_)((___)( (__ )(_)( _)(_ ) (
(____/(______)(____)(_)\_)(_____) \___)(_____)(____)(_)\_)
- Official code for all ESP8266/32 boards version 4.1
+ Official code for all ESP8266/32 boards version 4.2
Main .ino file
The Duino-Coin Team & Community 2019-2024 © MIT Licensed
@@ -34,10 +34,10 @@
#include
#else
#include
- #include
#include
#include
#include
+ #include
#endif
#include
@@ -59,6 +59,15 @@
#include "Dashboard.h"
#endif
+#if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ #include "DisplayHal.h"
+#endif
+
+#if !defined(ESP8266) && defined(DISABLE_BROWNOUT)
+ #include "soc/soc.h"
+ #include "soc/rtc_cntl_reg.h"
+#endif
+
// Auto adjust physical core count
// (ESP32-S2/C3 have 1 core, ESP32 has 2 cores, ESP8266 has 1 core)
#if defined(ESP8266)
@@ -70,10 +79,100 @@
#define CORE 2
// Install TridentTD_EasyFreeRTOS32 if you get an error
#include
+
+ void Task1Code( void * parameter );
+ void Task2Code( void * parameter );
+ TaskHandle_t Task1;
+ TaskHandle_t Task2;
#endif
#if defined(WEB_DASHBOARD)
WebServer server(80);
+#endif
+
+#if defined(CAPTIVE_PORTAL)
+ #include // This needs to be first, or it all crashes and burns...
+ #include
+ #include
+ char duco_username[40];
+ char duco_password[40];
+ char duco_rigid[24];
+ WiFiManager wifiManager;
+ Preferences preferences;
+ WiFiManagerParameter custom_duco_username("duco_usr", "Duino-Coin username", duco_username, 40);
+ WiFiManagerParameter custom_duco_password("duco_pwd", "Duino-Coin mining key (if enabled in the wallet)", duco_password, 40);
+ WiFiManagerParameter custom_duco_rigid("duco_rig", "Custom miner identifier (optional)", duco_rigid, 24);
+
+ void saveConfigCallback() {
+ preferences.begin("duino_config", false);
+ preferences.putString("duco_username", custom_duco_username.getValue());
+ preferences.putString("duco_password", custom_duco_password.getValue());
+ preferences.putString("duco_rigid", custom_duco_rigid.getValue());
+ preferences.end();
+ RestartESP("Settings saved");
+ }
+
+ void reset_settings() {
+ server.send(200, "text/html", "Settings have been erased. Please redo the configuration by connecting to the WiFi network that will be created");
+ delay(500);
+ wifiManager.resetSettings();
+ RestartESP("Manual settings reset");
+ }
+
+ void saveParamCallback(){
+ Serial.println("[CALLBACK] saveParamCallback fired");
+ Serial.println("PARAM customfieldid = " + getParam("customfieldid"));
+ }
+
+ String getParam(String name){
+ //read parameter from server, for customhmtl input
+ String value;
+ if(wifiManager.server->hasArg(name)) {
+ value = wifiManager.server->arg(name);
+ }
+ return value;
+ }
+#endif
+
+void RestartESP(String msg) {
+ #if defined(SERIAL_PRINTING)
+ Serial.println(msg);
+ Serial.println("Restarting ESP...");
+ #endif
+
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ display_info("Restarting ESP...");
+ #endif
+
+ #if defined(ESP8266)
+ ESP.reset();
+ #else
+ ESP.restart();
+ abort();
+ #endif
+}
+
+#if defined(ESP8266)
+ // WDT Loop
+ // See lwdtcb() and lwdtFeed() below
+ Ticker lwdTimer;
+
+ unsigned long lwdCurrentMillis = 0;
+ unsigned long lwdTimeOutMillis = LWD_TIMEOUT;
+
+ void ICACHE_RAM_ATTR lwdtcb(void) {
+ if ((millis() - lwdCurrentMillis > LWD_TIMEOUT) || (lwdTimeOutMillis - lwdCurrentMillis != LWD_TIMEOUT))
+ RestartESP("Loop WDT Failed!");
+ }
+
+ void lwdtFeed(void) {
+ lwdCurrentMillis = millis();
+ lwdTimeOutMillis = lwdCurrentMillis + LWD_TIMEOUT;
+ }
+#else
+ void lwdtFeed(void) {
+ Serial.println("lwdtFeed()");
+ }
#endif
namespace {
@@ -104,26 +203,36 @@ namespace {
#if defined(SERIAL_PRINTING)
Serial.println("Poolpicker selected the best mining node: " + node_id);
#endif
+
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ display_info(node_id);
+ #endif
}
String httpGetString(String URL) {
String payload = "";
- WiFiClientSecure client;
- client.setInsecure();
+ WiFiClientSecure *client = new WiFiClientSecure;
+ client->setInsecure();
+ client->setTimeout(10000);
HTTPClient http;
+ http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
- if (http.begin(client, URL)) {
+ if (http.begin(*client, URL)) {
int httpCode = http.GET();
- if (httpCode == HTTP_CODE_OK)
+ if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY)
payload = http.getString();
else
#if defined(SERIAL_PRINTING)
Serial.printf("Error fetching node from poolpicker: %s\n", http.errorToString(httpCode).c_str());
#endif
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ display_info(http.errorToString(httpCode));
+ #endif
http.end();
}
+ delete client;
return payload;
}
@@ -142,60 +251,58 @@ namespace {
// Increase wait time till a maximum of 32 seconds
// (addresses: Limit connection requests on failure in ESP boards #1041)
waitTime *= 2;
- if (waitTime > 32)
- waitTime = 32;
+ if (waitTime > 32)
+ RestartESP("Node fetch unavailable");
}
UpdateHostPort(input);
}
#ifdef USE_LAN
- void WiFiEvent(WiFiEvent_t event)
- {
- switch (event) {
- case ARDUINO_EVENT_ETH_START:
- #if defined(SERIAL_PRINTING)
- Serial.println("ETH Started");
- #endif
- // The hostname must be set after the interface is started, but needs
- // to be set before DHCP, so set it from the event handler thread.
- ETH.setHostname("esp32-ethernet");
- break;
- case ARDUINO_EVENT_ETH_CONNECTED:
- #if defined(SERIAL_PRINTING)
- Serial.println("ETH Connected");
- #endif
- break;
- case ARDUINO_EVENT_ETH_GOT_IP:
- #if defined(SERIAL_PRINTING)
- Serial.println("ETH Got IP");
- #endif
- eth_connected = true;
- break;
-
- case ARDUINO_EVENT_ETH_DISCONNECTED:
- #if defined(SERIAL_PRINTING)
- Serial.println("ETH Disconnected");
- #endif
- eth_connected = false;
- break;
- case ARDUINO_EVENT_ETH_STOP:
- #if defined(SERIAL_PRINTING)
- Serial.println("ETH Stopped");
- #endif
- eth_connected = false;
- break;
- default:
- break;
- }
- }
+ void WiFiEvent(WiFiEvent_t event) {
+ switch (event) {
+ case ARDUINO_EVENT_ETH_START:
+ #if defined(SERIAL_PRINTING)
+ Serial.println("ETH Started");
+ #endif
+ // The hostname must be set after the interface is started, but needs
+ // to be set before DHCP, so set it from the event handler thread.
+ ETH.setHostname("esp32-ethernet");
+ break;
+ case ARDUINO_EVENT_ETH_CONNECTED:
+ #if defined(SERIAL_PRINTING)
+ Serial.println("ETH Connected");
+ #endif
+ break;
+ case ARDUINO_EVENT_ETH_GOT_IP:
+ #if defined(SERIAL_PRINTING)
+ Serial.println("ETH Got IP");
+ #endif
+ eth_connected = true;
+ break;
+ case ARDUINO_EVENT_ETH_DISCONNECTED:
+ #if defined(SERIAL_PRINTING)
+ Serial.println("ETH Disconnected");
+ #endif
+ eth_connected = false;
+ break;
+ case ARDUINO_EVENT_ETH_STOP:
+ #if defined(SERIAL_PRINTING)
+ Serial.println("ETH Stopped");
+ #endif
+ eth_connected = false;
+ break;
+ default:
+ break;
+ }
+ }
#endif
void SetupWifi() {
#ifdef USE_LAN
#if defined(SERIAL_PRINTING)
- Serial.println("Connecting to Ethernet...");
+ Serial.println("Connecting to Ethernet...");
#endif
WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread.
ETH.begin();
@@ -209,16 +316,17 @@ namespace {
}
#if defined(SERIAL_PRINTING)
- Serial.println("\n\nSuccessfully connected to Ethernet");
- Serial.println("Local IP address: " + ETH.localIP().toString());
- Serial.println("Rig name: " + String(RIG_IDENTIFIER));
- Serial.println();
+ Serial.println("\n\nSuccessfully connected to Ethernet");
+ Serial.println("Local IP address: " + ETH.localIP().toString());
+ Serial.println("Rig name: " + String(RIG_IDENTIFIER));
+ Serial.println();
#endif
#else
#if defined(SERIAL_PRINTING)
- Serial.println("Connecting to: " + String(SSID));
+ Serial.println("Connecting to: " + String(SSID));
#endif
+
WiFi.mode(WIFI_STA); // Setup ESP in client mode
#if defined(ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
@@ -226,29 +334,37 @@ namespace {
WiFi.setSleep(false);
#endif
WiFi.begin(SSID, PASSWORD);
-
+
int wait_passes = 0;
- while (WiFi.waitForConnectResult() != WL_CONNECTED) {
+ while (WiFi.waitForConnectResult() != WL_CONNECTED || WiFi.localIP() == IPAddress(192, 168, 4, 2)) {
delay(500);
#if defined(SERIAL_PRINTING)
- Serial.print(".");
+ Serial.print(".");
#endif
if (++wait_passes >= 10) {
+ WiFi.disconnect();
WiFi.begin(SSID, PASSWORD);
wait_passes = 0;
}
}
+ #ifndef(ESP8266)
+ WiFi.config(WiFi.localIP(), WiFi.gatewayIP(), WiFi.subnetMask(), DNS_SERVER);
+ #endif
#if defined(SERIAL_PRINTING)
- Serial.println("\n\nSuccessfully connected to WiFi");
- Serial.println("Local IP address: " + WiFi.localIP().toString());
- Serial.println("Rig name: " + String(RIG_IDENTIFIER));
- Serial.println();
+ Serial.println("\n\nSuccessfully connected to WiFi");
+ Serial.println("Local IP address: " + WiFi.localIP().toString());
+ Serial.println("Rig name: " + String(RIG_IDENTIFIER));
+ Serial.println("DNS: " + WiFi.dnsIP().toString());
+ Serial.println();
#endif
#endif
- SelectNode();
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ display_info("Waiting for node...");
+ #endif
+ SelectNode();
}
void SetupOTA() {
@@ -301,12 +417,6 @@ namespace {
#endif
}
- void handleSystemEvents(void) {
- VerifyWifi();
- ArduinoOTA.handle();
- yield();
- }
-
#if defined(WEB_DASHBOARD)
void dashboard() {
#if defined(SERIAL_PRINTING)
@@ -319,7 +429,7 @@ namespace {
s.replace("@@IP_ADDR@@", WiFi.localIP().toString());
#endif
- s.replace("@@HASHRATE@@", String(hashrate / 1000));
+ s.replace("@@HASHRATE@@", String((hashrate+hashrate_core_two) / 1000));
s.replace("@@DIFF@@", String(difficulty / 100));
s.replace("@@SHARES@@", String(share_count));
s.replace("@@NODE@@", String(node_id));
@@ -335,6 +445,12 @@ namespace {
s.replace("@@ID@@", String(RIG_IDENTIFIER));
s.replace("@@MEMORY@@", String(ESP.getFreeHeap()));
s.replace("@@VERSION@@", String(SOFTWARE_VERSION));
+
+ #if defined(CAPTIVE_PORTAL)
+ s.replace("@@RESET_SETTINGS@@", "• Reset settings");
+ #else
+ s.replace("@@RESET_SETTINGS@@", "");
+ #endif
server.send(200, "text/html", s);
}
#endif
@@ -353,6 +469,23 @@ void task1_func(void *) {
VOID LOOP() {
job[0]->mine();
+
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ float hashrate_float = (hashrate+hashrate_core_two) / 1000.0;
+ float accept_rate = (accepted_share_count / 0.01 / share_count);
+
+ long millisecs = millis();
+ int uptime_secs = int((millisecs / 1000) % 60);
+ int uptime_mins = int((millisecs / (1000 * 60)) % 60);
+ int uptime_hours = int((millisecs / (1000 * 60 * 60)) % 24);
+ String uptime = String(uptime_hours) + "h" + String(uptime_mins) + "m" + String(uptime_secs) + "s";
+
+ float sharerate = share_count / (millisecs / 1000.0);
+
+ display_mining_results(String(hashrate_float, 1), String(accepted_share_count), String(share_count), String(uptime),
+ String(node_id), String(difficulty / 100), String(sharerate, 1),
+ String(ping), String(accept_rate, 1));
+ #endif
}
#endif
}
@@ -365,19 +498,63 @@ void task2_func(void *) {
VOID LOOP() {
job[1]->mine();
+
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ float hashrate_float = (hashrate+hashrate_core_two) / 1000.0;
+ float accept_rate = (accepted_share_count / 0.01 / share_count);
+
+ long millisecs = millis();
+ int uptime_secs = int((millisecs / 1000) % 60);
+ int uptime_mins = int((millisecs / (1000 * 60)) % 60);
+ int uptime_hours = int((millisecs / (1000 * 60 * 60)) % 24);
+ String uptime = String(uptime_hours) + "h" + String(uptime_mins) + "m" + String(uptime_secs) + "s";
+
+ float sharerate = share_count / (millisecs / 1000.0);
+
+ display_mining_results(String(hashrate_float, 1), String(accepted_share_count), String(share_count), String(uptime),
+ String(node_id), String(difficulty / 100), String(sharerate, 1),
+ String(ping), String(accept_rate, 1));
+ #endif
}
#endif
}
void setup() {
- delay(500);
+ #if !defined(ESP8266) && defined(DISABLE_BROWNOUT)
+ WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
+ #endif
#if defined(SERIAL_PRINTING)
- Serial.begin(500000);
- Serial.println("\n\nDuino-Coin " + String(configuration->MINER_VER));
+ Serial.begin(SERIAL_BAUDRATE);
+ Serial.println("\n\nDuino-Coin " + String(configuration->MINER_VER));
#endif
pinMode(LED_BUILTIN, OUTPUT);
+ #if defined(BLUSHYBOX)
+ analogWrite(LED_BUILTIN, 255);
+ for (int i = 255; i > 0; i--) {
+ analogWrite(LED_BUILTIN, i);
+ delay(1);
+ }
+ pinMode(GAUGE_PIN, OUTPUT);
+
+ // Gauge up and down effect on startup
+ for (int i = GAUGE_MIN; i < GAUGE_MAX; i++) {
+ analogWrite(GAUGE_PIN, i);
+ delay(10);
+ }
+ for (int i = GAUGE_MAX; i > GAUGE_MIN; i--) {
+ analogWrite(GAUGE_PIN, i);
+ delay(10);
+ }
+ #endif
+
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ screen_setup();
+ display_boot();
+ delay(2500);
+ #endif
+
assert(CORE == 1 || CORE == 2);
WALLET_ID = String(random(0, 2811)); // Needed for miner grouping in the wallet
job[0] = new MiningJob(0, configuration);
@@ -404,6 +581,13 @@ void setup() {
#endif
#endif
+ #if defined(USE_HSU07M)
+ #if defined(SERIAL_PRINTING)
+ Serial.println("Initializing HSU07M sensor (Duino IoT)");
+ Serial.println("Test reading: " + String(read_hsu07m()) + "°C");
+ #endif
+ #endif
+
#if defined(USE_INTERNAL_SENSOR)
#if defined(SERIAL_PRINTING)
Serial.println("Initializing internal ESP32 temperature sensor (Duino IoT)");
@@ -419,7 +603,68 @@ void setup() {
#endif
#endif
- SetupWifi();
+ #if defined(CAPTIVE_PORTAL)
+ preferences.begin("duino_config", false);
+ strcpy(duco_username, preferences.getString("duco_username", "username").c_str());
+ strcpy(duco_password, preferences.getString("duco_password", "None").c_str());
+ strcpy(duco_rigid, preferences.getString("duco_rigid", "None").c_str());
+ preferences.end();
+ configuration->DUCO_USER = duco_username;
+ configuration->RIG_IDENTIFIER = duco_rigid;
+ configuration->MINER_KEY = duco_password;
+
+ String captivePortalHTML = R"(
+ Duino BlushyBox
+
+ )";
+
+ wifiManager.setCustomHeadElement(captivePortalHTML.c_str());
+
+ wifiManager.setSaveConfigCallback(saveConfigCallback);
+ wifiManager.addParameter(&custom_duco_username);
+ wifiManager.addParameter(&custom_duco_password);
+ wifiManager.addParameter(&custom_duco_rigid);
+
+ //blinker.attach_ms(200, changeState);
+ wifiManager.autoConnect("Duino-Coin");
+ //blinker.detach();
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ display_info("Waiting for node...");
+ #endif
+ SelectNode();
+ #else
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ display_info("Waiting for WiFi...");
+ #endif
+ SetupWifi();
+ #endif
SetupOTA();
#if defined(WEB_DASHBOARD)
@@ -440,28 +685,73 @@ void setup() {
#endif
server.on("/", dashboard);
+ #if defined(CAPTIVE_PORTAL)
+ server.on("/reset", reset_settings);
+ #endif
server.begin();
#endif
- job[0]->blink(BLINK_SETUP_COMPLETE);
-
- #if CORE == 2 && defined(ESP32)
- task1.start(task1_func);
- task2.start(task2_func);
+ #if defined(ESP8266)
+ // Start the WDT watchdog
+ lwdtFeed();
+ lwdTimer.attach_ms(LWD_TIMEOUT, lwdtcb);
#endif
-}
-
-void loopOneCore() {
- job[0]->mine();
#if defined(ESP8266)
// Fastest clock mode for 8266s
system_update_cpu_freq(160);
+ os_update_cpu_frequency(160);
+ // Feed the watchdog
+ lwdtFeed();
#else
// Fastest clock mode for 32s
setCpuFrequencyMhz(240);
#endif
+
+ job[0]->blink(BLINK_SETUP_COMPLETE);
+
+ #if defined(ESP32) && CORE == 2
+ mutexClientData = xSemaphoreCreateMutex();
+ mutexConnectToServer = xSemaphoreCreateMutex();
+
+ xTaskCreatePinnedToCore(system_events_func, "system_events_func", 10000, NULL, 1, NULL, 0);
+ xTaskCreatePinnedToCore(task1_func, "task1_func", 10000, NULL, 1, &Task1, 0);
+ xTaskCreatePinnedToCore(task2_func, "task2_func", 10000, NULL, 1, &Task2, 1);
+ #endif
+}
+
+void system_events_func(void* parameter) {
+ while (true) {
+ delay(10);
+ #if defined(WEB_DASHBOARD)
+ server.handleClient();
+ #endif
+ ArduinoOTA.handle();
+ }
+}
+
+void single_core_loop() {
+ job[0]->mine();
+
+ lwdtFeed();
+ #if defined(DISPLAY_SSD1306) || defined(DISPLAY_16X2)
+ float hashrate_float = (hashrate+hashrate_core_two) / 1000.0;
+ float accept_rate = (accepted_share_count / 0.01 / share_count);
+
+ long millisecs = millis();
+ int uptime_secs = int((millisecs / 1000) % 60);
+ int uptime_mins = int((millisecs / (1000 * 60)) % 60);
+ int uptime_hours = int((millisecs / (1000 * 60 * 60)) % 24);
+ String uptime = String(uptime_hours) + "h" + String(uptime_mins) + "m" + String(uptime_secs) + "s";
+
+ float sharerate = share_count / (millisecs / 1000.0);
+
+ display_mining_results(String(hashrate_float, 1), String(accepted_share_count), String(share_count), String(uptime),
+ String(node_id), String(difficulty / 100), String(sharerate, 1),
+ String(ping), String(accept_rate, 1));
+ #endif
+
VerifyWifi();
ArduinoOTA.handle();
#if defined(WEB_DASHBOARD)
@@ -470,7 +760,8 @@ void loopOneCore() {
}
void loop() {
- #if CORE == 1
- loopOneCore();
- #endif
+ #if defined(ESP8266) || defined(CONFIG_FREERTOS_UNICORE)
+ single_core_loop();
+ #endif
+ delay(10);
}
diff --git a/ESP_Code/MiningJob.h b/ESP_Code/MiningJob.h
index 9d488c7e..7384735c 100644
--- a/ESP_Code/MiningJob.h
+++ b/ESP_Code/MiningJob.h
@@ -90,38 +90,66 @@ class MiningJob {
return false;
}
+ void handleSystemEvents(void) {
+ #if defined(ESP32) && CORE == 2
+ esp_task_wdt_reset();
+ #endif
+ delay(10); // Required vTaskDelay by ESP-IDF
+ yield();
+ ArduinoOTA.handle();
+ }
+
void mine() {
connectToNode();
askForJob();
-
+
dsha1->reset().write((const unsigned char *)getLastBlockHash().c_str(), getLastBlockHash().length());
int start_time = micros();
max_micros_elapsed(start_time, 0);
#if defined(LED_BLINKING)
digitalWrite(LED_BUILTIN, LOW);
- #endif
+ #endif
for (Counter<10> counter; counter < difficulty; ++counter) {
DSHA1 ctx = *dsha1;
ctx.write((const unsigned char *)counter.c_str(), counter.strlen()).finalize(hashArray);
-
- #if CORE == 1
- yield();
- #elif defined(ESP8266)
- ESP.wdtFeed();
+
+ #ifndef CONFIG_FREERTOS_UNICORE
+ #if defined(ESP32)
+ #define SYSTEM_TIMEOUT 100000 // 10ms for esp32 looks like the lowest value without false watchdog triggers
+ #else
+ #define SYSTEM_TIMEOUT 500000 // 50ms for 8266 for same reason as above
+ #endif
+ if (max_micros_elapsed(micros(), SYSTEM_TIMEOUT)) {
+ handleSystemEvents();
+ }
#endif
if (memcmp(getExpectedHash(), hashArray, 20) == 0) {
unsigned long elapsed_time = micros() - start_time;
float elapsed_time_s = elapsed_time * .000001f;
- hashrate = counter / elapsed_time_s;
share_count++;
#if defined(LED_BLINKING)
- digitalWrite(LED_BUILTIN, HIGH);
- #endif
-
- submit(counter, hashrate, elapsed_time_s);
+ #if defined(BLUSHYBOX)
+ analogWrite(LED_BUILTIN, 200);
+ #else
+ digitalWrite(LED_BUILTIN, HIGH);
+ #endif
+ #endif
+
+ if (String(core) == "0") {
+ hashrate = counter / elapsed_time_s;
+ submit(counter, hashrate, elapsed_time_s);
+ } else {
+ hashrate_core_two = counter / elapsed_time_s;
+ submit(counter, hashrate_core_two, elapsed_time_s);
+ }
+
+ #if defined(BLUSHYBOX)
+ gauge_set(hashrate + hashrate_core_two);
+ #endif
+
break;
}
}
@@ -138,11 +166,19 @@ class MiningJob {
String chipID = "";
#if defined(ESP8266)
- String MINER_BANNER = "Official ESP8266 Miner";
+ #if defined(BLUSHYBOX)
+ String MINER_BANNER = "Official BlushyBox Miner (ESP8266)";
+ #else
+ String MINER_BANNER = "Official ESP8266 Miner";
+ #endif
#elif defined(CONFIG_FREERTOS_UNICORE)
String MINER_BANNER = "Official ESP32-S2 Miner";
#else
- String MINER_BANNER = "Official ESP32 Miner";
+ #if defined(BLUSHYBOX)
+ String MINER_BANNER = "Official BlushyBox Miner (ESP32)";
+ #else
+ String MINER_BANNER = "Official ESP32 Miner";
+ #endif
#endif
uint8_t *hexStringToUint8Array(const String &hexString, uint8_t *uint8Array, const uint32_t arrayLength) {
@@ -196,7 +232,10 @@ class MiningJob {
Serial.println("Core [" + String(core) + "] - Connecting to a Duino-Coin node...");
#endif
while (!client.connect(config->host.c_str(), config->port)) {
- if (millis()-stopWatch>100000) ESP.restart();
+ if (max_micros_elapsed(micros(), 100000)) {
+ handleSystemEvents();
+ }
+ if (millis()-stopWatch>100000) ESP.restart();
}
waitForClientData();
@@ -207,6 +246,12 @@ class MiningJob {
blink(BLINK_CLIENT_CONNECT);
+ /* client.print("MOTD" + END_TOKEN);
+ waitForClientData();
+ #if defined(SERIAL_PRINTING)
+ Serial.println("Core [" + String(core) + "] - MOTD: "
+ + client_buffer);
+ #endif */
}
void waitForClientData() {
@@ -231,8 +276,14 @@ class MiningJob {
SEP_TOKEN + "DUCOID" + String(chipID) +
SEP_TOKEN + String(WALLET_ID) +
END_TOKEN);
-
+
+ unsigned long ping_start = millis();
waitForClientData();
+ ping = millis() - ping_start;
+
+ if (client_buffer == "GOOD") {
+ accepted_share_count++;
+ }
#if defined(SERIAL_PRINTING)
Serial.println("Core [" + String(core) + "] - " +
@@ -304,6 +355,18 @@ class MiningJob {
SEP_TOKEN + "Temp:" + String(temp) + "*C" +
IOT_TOKEN + "Hum:" + String(hum) + "%" +
END_TOKEN);
+ #elif defined(USE_HSU07M)
+ float temp = read_hsu07m();
+ #if defined(SERIAL_PRINTING)
+ Serial.println("HSU reading: " + String(temp) + "°C");
+ #endif
+
+ client.print("JOB," +
+ String(config->DUCO_USER) +
+ SEP_TOKEN + config->START_DIFF +
+ SEP_TOKEN + String(config->MINER_KEY) +
+ SEP_TOKEN + "Temp:" + String(temp) + "*C" +
+ END_TOKEN);
#elif defined(USE_INTERNAL_SENSOR)
float temp = 0;
temp_sensor_read_celsius(&temp);
diff --git a/ESP_Code/Settings.h b/ESP_Code/Settings.h
index f58e8d20..13bc34fc 100644
--- a/ESP_Code/Settings.h
+++ b/ESP_Code/Settings.h
@@ -4,30 +4,62 @@
// ---------------------- General settings ---------------------- //
// Change the part in brackets to your Duino-Coin username
-extern const char DUCO_USER[] = "my_cool_username";
+extern char *DUCO_USER = "my_cool_username";
// Change the part in brackets to your mining key (if you have set it in the wallet)
-extern const char MINER_KEY[] = "mySecretPass";
+extern char *MINER_KEY = "mySecretPass";
// Change the part in brackets if you want to set a custom miner name
// Use Auto to autogenerate, None for no custom identifier
-extern const char RIG_IDENTIFIER[] = "None";
+extern char *RIG_IDENTIFIER = "None";
// Change the part in brackets to your WiFi name
extern const char SSID[] = "SSID";
// Change the part in brackets to your WiFi password
extern const char PASSWORD[] = "PASSW0RD";
+// -------------------------------------------------------------- //
-// Uncomment if you want to host the dashboard page (available on ESPs IP address)
+// -------------------- Advanced options ------------------------ //
+// Uncomment if you want to host the dashboard page (available on ESPs IP address and mDNS)
// #define WEB_DASHBOARD
+// Comment out the line below if you wish to disable LED blinking
+#define LED_BLINKING
+
// Uncomment if you want to use LAN8720. WLAN-credentials will be ignored using LAN
// Select correct Board in ArduinoIDE!!! Really!
// #define USE_LAN
-// Comment out the line below if you wish to disable LED blinking
-#define LED_BLINKING
-
// Comment out the line below if you wish to disable Serial printing
#define SERIAL_PRINTING
+// Edit the line below if you wish to change the serial speed (low values may reduce performance but are less prone to interference)
+#define SERIAL_BAUDRATE 500000
+
+// ESP8266 WDT loop watchdog. Do not edit this value, but if you must - do not set it too low or it will falsely trigger during mining!
+#define LWD_TIMEOUT 30000
+
+// Uncomment to disable ESP32 brownout detector if you're suffering from faulty insufficient power detection
+// #define DISABLE_BROWNOUT
+
+// Uncomment to enable WiFiManager captive portal in AP mode
+// The board will create its own network you connect to and change the settings
+// #define CAPTIVE_PORTAL
+// -------------------------------------------------------------- //
+
+// ------------------------ Displays ---------------------------- //
+
+// Uncomment to enable a SSD1306 OLED screen on the I2C bus to display mining info in real time
+// Default connections (can be overriden by using a different u8g2 initializer, see line 140):
+// GND - GND
+// VCC - 5V or 3.3V depending on display
+// SCL - GPIO22 (ESP32) or GPIO5 (D2 on ESP8266) or GPIO35 (ESP32-S2)
+// SDA - GPIO21 (ESP32) or GPIO4 (D1 on ESP8266) or GPIO33 (ESP32-S2)
+// #define DISPLAY_SSD1306
+
+// Uncomment to enable a 16x2 LCD screen on a direct bus to display mining info in real time
+// See line 150 for connections and initializer
+// #define DISPLAY_16X2
+
+// Uncomment if your device is a Duino BlushyBox device
+// #define BLUSHYBOX
// -------------------------------------------------------------- //
// ---------------------- IoT examples -------------------------- //
@@ -44,10 +76,18 @@ extern const char PASSWORD[] = "PASSW0RD";
// #define USE_DS18B20
// Uncomment the line below if you wish to use a DHT11/22 temperature and humidity sensor (Duino IoT example)
-// NOTE: Untested as of right now
+// NOTE: Mining performance should stay the same
// #define USE_DHT
+
+// Uncomment the line below if you wish to use a HSU07M sensor (Duino IoT Example)
+// NOTE: Untested as of right now
+// #define USE_HSU07M
// -------------------------------------------------------------- //
+// ---------------- Variables and definitions ------------------- //
+// You generally do not need to edit stuff below this line
+// unless you're know what you're doing.
+
#if defined(ESP8266)
// ESP8266
#define LED_BUILTIN 2
@@ -62,12 +102,15 @@ extern const char PASSWORD[] = "PASSW0RD";
#define BLINK_SETUP_COMPLETE 2
#define BLINK_CLIENT_CONNECT 5
-#define SOFTWARE_VERSION "4.1"
+#define SOFTWARE_VERSION "4.2"
extern unsigned int hashrate = 0;
+extern unsigned int hashrate_core_two = 0;
extern unsigned int difficulty = 0;
extern unsigned long share_count = 0;
+extern unsigned long accepted_share_count = 0;
extern String node_id = "";
extern String WALLET_ID = "";
+extern unsigned int ping = 0;
#if defined(USE_INTERNAL_SENSOR)
#include "driver/temp_sensor.h"
@@ -95,4 +138,78 @@ extern String WALLET_ID = "";
DHT extern dht(DHTPIN, DHTTYPE);
#endif
+#if defined(DISPLAY_SSD1306)
+ // Install "u8g2" if you get an error
+ #include
+ #include
+ // Display definition from the U8G2 library. Edit if you use a different display
+ // For software I2C, use ..._F_SW_I2C and define the pins in the initializer
+ U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
+#endif
+
+#if defined(DISPLAY_16X2)
+ #include "Wire.h"
+ // Install "Adafruit_LiquidCrystal" if you get an error
+ #include "Adafruit_LiquidCrystal.h"
+
+ // initialize the library with the numbers of the interface pins
+ // RS E D4 D5 D6 D7
+ Adafruit_LiquidCrystal lcd(1, 2, 3, 4, 5, 6);
+#endif
+
+#if defined(USE_HSU07M)
+ #include "Wire.h"
+ #define HSU07M_ADDRESS 0x4B // Change this if your sensor has a different address
+
+ float read_hsu07m() {
+ Wire.beginTransmission(HSU07M_ADDRESS);
+ Wire.write(0x00);
+ Wire.endTransmission();
+ delay(100);
+ Wire.requestFrom(HSU07M_ADDRESS, 2);
+ if(Wire.available() >= 2) {
+ byte tempMSB = Wire.read();
+ byte tempLSB = Wire.read();
+ int tempRaw = (tempMSB << 8) | tempLSB;
+ float tempC = (tempRaw / 16.0) - 40.0;
+ return tempC;
+ }
+ return -1.0;
+ }
+#endif
+
+#if defined(BLUSHYBOX)
+ #define GAUGE_PIN 5
+ #define GAUGE_MAX 190
+ #define GAUGE_MIN 0
+ #if defined(ESP8266)
+ #define GAUGE_MAX_HR 80000
+ #else
+ #define GAUGE_MAX_HR 200000
+ #endif
+ extern float hashrate_old = 0.0;
+
+ void gauge_set(float hashrate) {
+ float old = hashrate_old;
+ float new_val = hashrate;
+
+ if (hashrate_old == 0) {
+ float delta = (new_val - old) / 50;
+ for (int x=0; x < 50; x++) {
+ analogWrite(5, map(old + x*delta, 0, GAUGE_MAX_HR, GAUGE_MIN, GAUGE_MAX) + random(0, 10));
+ delay(20);
+ }
+ } else {
+ float delta = (new_val - old) / 10;
+ for (int x=0; x < 10; x++) {
+ analogWrite(5, map(old + x*delta, 0, GAUGE_MAX_HR, GAUGE_MIN, GAUGE_MAX) + random(0, 10));
+ delay(10);
+ }
+ }
+ hashrate_old = hashrate;
+ }
+#endif
+
+IPAddress DNS_SERVER(1, 1, 1, 1); // Cloudflare DNS server
+
#endif // End of SETTINGS_H
diff --git a/PC_Miner.py b/PC_Miner.py
index c7557fc1..2d728844 100644
--- a/PC_Miner.py
+++ b/PC_Miner.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
-Duino-Coin Official PC Miner 4.1 © MIT licensed
+Duino-Coin Official PC Miner 4.2 © MIT licensed
https://duinocoin.com
https://github.com/revoxhere/duino-coin
Duino-Coin Team & Community 2019-2024
@@ -142,7 +142,7 @@ class Settings:
"""
ENCODING = "UTF8"
SEPARATOR = ","
- VER = 4.1
+ VER = 4.2
DATA_DIR = "Duino-Coin PC Miner " + str(VER)
TRANSLATIONS = ("https://raw.githubusercontent.com/"
+ "revoxhere/"
@@ -198,7 +198,7 @@ def title(title: str):
print('\33]0;' + title + '\a', end='')
sys.stdout.flush()
except Exception as e:
- print(e)
+ debug_output("Error setting title: " +str(e))
def check_updates():
@@ -712,6 +712,15 @@ def get_string(string_name):
return string_name
+def has_mining_key(username):
+ response = requests.get(
+ "https://server.duinocoin.com/mining_key"
+ + "?u=" + username,
+ timeout=10
+ ).json()
+ return response["has_key"]
+
+
def check_mining_key(user_settings):
if user_settings["mining_key"] != "None":
key = '&k=' + urllib.parse.quote(b64.b64decode(user_settings["mining_key"]).decode('utf-8'))
@@ -948,10 +957,11 @@ def load_cfg():
if not correct_username:
print(get_string("incorrect_username"))
- mining_key = input(Style.RESET_ALL + get_string("ask_mining_key") + Style.BRIGHT)
- if not mining_key:
- mining_key = "None"
- else:
+ mining_key = "None"
+ if has_mining_key(username):
+ mining_key = input(Style.RESET_ALL +
+ get_string("ask_mining_key") +
+ Style.BRIGHT)
mining_key = b64.b64encode(mining_key.encode("utf-8")).decode('utf-8')
algorithm = "DUCO-S1"
diff --git a/README.md b/README.md
index ae14846c..a2cf0a5c 100644
--- a/README.md
+++ b/README.md
@@ -137,17 +137,17 @@ Server source code, documentation for API calls and official libraries for devel
## Version 4.0 reward goals
Captured at normal multiplier (no weekend boost)
-| Device | Hashrate | Threads | DUCO/day |
-|-----------------------|---------------------|---------|----------|
-| Arduino | 343 H/s | 1 | 12 |
-| ESP32 | 84 kH/s (2x42 kH/s) | 2 | 10 |
-| ESP32-S2/C3 | 82 kH/s | 1 | 8 |
-| ESP8266 | 66 kH/s | 1 | 6 |
-| Raspberry Pi 4 (LOW) | 1 MH/s (no fasthash)| 4 | 6-7 |
-| Raspberry Pi 4 (MED) | 5.4 MH/s (fasthash) | 4 | 7-8 |
-| Low power PCs | | 4 | 4-6 |
-| Medium | | 4-8 | 6-10 |
-| High end | | 8+ | 10-12 |
+| Device | Hashrate | Threads | DUCO/day | Power usage |
+|-----------------------|---------------------|---------|----------|-------------|
+| Arduino | 343 H/s | 1 | 12 | <0.5 W
+| ESP32 | 170-180 kH/s | 2 | 10 | 1.5-2 W
+| ESP32-S2/C3 | 85-96 kH/s | 1 | 8 | 1-1.5 W
+| ESP8266 | 66 kH/s | 1 | 6 | 1-1.5 W
+| Raspberry Pi 4 (LOW) | 1 MH/s (no fasthash)| 4 | 6-7 | 6.5 W
+| Raspberry Pi 4 (MED) | 5.4 MH/s (fasthash) | 4 | 7-8 | 6.5 W
+| Low power PCs | | 4 | 4-6 | -
+| Medium | | 4-8 | 6-10 | -
+| High end | | 8+ | 10-12 | -
Other tested devices and their benchmarks
@@ -184,11 +184,11 @@ Please note the DUCO/day column has been removed since version 4.0 changed the r
## Community-made softwares
-### Please note that these softwares are not developed by us and we do not give any guarantees that use of them will not result in an account getting banned. Treat them as a curiosity.
+### Please note that these softwares are not developed by us and we do not give any guarantees that use of them will not result in an account getting banned if they get changed in the future.
- ### Other miners known to work with Duino-Coin:
- * [Dockerized Duino-Coin Miner](https://github.com/simeononsecurity/docker-duino-coin) - A Dockerized version of the Duino-Coin Miner
- * :point_right: [**RP2040-HAT-MINING-C**](https://github.com/Wiznet/RP2040-HAT-MINING-C) - **WIZnet RP2040** mining stack
+ ### Miners made by the Duino-Coin community:
+ * [Dockerized Duino-Coin Miner](https://github.com/simeononsecurity/docker-duino-coin) - A Dockerized version of the Duino-Coin Miner by simeononsecurity
+ * :point_right: [**RP2040-HAT-MINING-C**](https://github.com/Wiznet/RP2040-HAT-MINING-C) - **WIZnet RP2040 mining stack**
* [DuinoCoinEthernetMiner](https://github.com/Pumafron/DuinoCoinEthernetMiner) - Arduino Ethernet shield Miner by Pumafron
* [STM8 DUCO Miner](https://github.com/BBS215/STM8_DUCO_miner) - STM8S firmware for mining DUCO by BBS215
* [DuinoCoinbyLabVIEW](https://github.com/ericddm/DuinoCoinbyLabVIEW) - miner for LabVIEW family by ericddm
@@ -213,6 +213,7 @@ Please note the DUCO/day column has been removed since version 4.0 changed the r
* [Teensy 4.1 code for Arduino IDE](https://github.com/revoxhere/duino-coin/blob/master/Unofficial%20miners/Teensy_code/Teensy_code.ino) by joaquinbvw
### Other tools:
+ * [**Duinogotchi**](https://github.com/OSRdesign/duinogotchi) - Duino-Coin virtual pet project by OSRdesign
* [Duino Miner](https://github.com/g7ltt/Duino-Miner) - Arduino Nano based DUCO miner files and documentation by g7ltt
* [DUINO Mining Rig](https://repalmakershop.com/pages/duino-mining-rig) - 3D files, PCB designs and instructions for creating your own Duino rig by ReP_AL
* [DuinoCoin-balance-Home-Assistant](https://github.com/NL647/DuinoCoin-balance-Home-Assistant) - addon for home assistant displaying your balance by NL647
@@ -227,6 +228,8 @@ Please note the DUCO/day column has been removed since version 4.0 changed the r
* [DuCoWallet](https://github.com/viktor02/DuCoWallet) GUI Wallet by viktor02
* [Duco-widget-ios](https://github.com/naphob/duco-widget-ios) - a Duino-Coin iOS widget by Naphob
* [Duino Lookup](https://axorax.github.io/duino-lookup/) by axorax
+ * [Duino Miner Hassio Add-on](https://github.com/mavotronik/hassio-addons/tree/main/duino_miner_hassio_addon) by mavotronik
+ * [Home Assistant sensors package](https://github.com/mavotronik/Duinocoin_homeassistant) by mavotronik
You may also view a similar list on the [website](https://duinocoin.com/apps).
diff --git a/Resources/AVR_Miner_langs.json b/Resources/AVR_Miner_langs.json
index 6b9103a1..c7fd5c43 100644
--- a/Resources/AVR_Miner_langs.json
+++ b/Resources/AVR_Miner_langs.json
@@ -83,7 +83,7 @@
"connecting_node": " Retrieved mining node: ",
"new_version": "A new version is available, do you want to update the miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!",
"incorrect_username": "The username you provided doesn't exist!",
@@ -267,7 +267,7 @@
"connecting_node": " Získaný těžební uzel: ",
"new_version": "Je dostupná nová verze programu. Chceš ho hned teď aktualizovat [Y/n] ? ",
"updating": "Těžící program je zastaralý. Instaluji aktualizaci....",
- "ask_mining_key": "Zadej svůj těžební klíč (jen pokud sis ho dříve nastavil ve webové peněžence - stiskni enter k přeskočení): ",
+ "ask_mining_key": "Zadej svůj těžební klíč: ",
"mining_key_required": "Těžební klíč je nutný pro těžbu na tomto účtě",
"invalid_mining_key": "Zadaný těžební klíč není správný",
"incorrect_username": "Zadané uživatelské jméno neexistuje",
@@ -443,7 +443,7 @@
"total_mining_time": "\n\t\t‖ Koparka działa przez: ",
"new_version": "Znalezino nową wersję, chcesz zaktualizować koparkę? [Y/n] ? ",
"updating": "Koparka jest nieaktualna, aktualizacja w trakcie....",
- "ask_mining_key": "Wprowadź swoje hasło do kopania (mining key) (tylko jeżeli ustawiłeś je w portfelu internetowym - w przeciwnym razie wciśnij enter aby pominąć): ",
+ "ask_mining_key": "Wprowadź swoje hasło do kopania (mining key): ",
"mining_key_required": "Hasło do kopania jest wymagane do kopania na tym koncie",
"invalid_mining_key": "Podane hasło do kopania jest nieprawidłowe!",
"incorrect_username": "Podana nazwa użytkownika nie istnieje!",
@@ -672,7 +672,7 @@
"connecting_node": " Abgerufener Mining Knoten: ",
"new_version": "Eine neue Version ist verfügbar. Möchtest du den Miner aktualisieren [Y/n]? ",
"updating": "Der Miner ist veraltet. Aktualisiere....",
- "ask_mining_key": "Gib deinen Miningschlüssel an (nur nötig, wenn du diese Option im Webwallet aktiviert hast - Drück die Eingabetaste um zu überspringen): ",
+ "ask_mining_key": "Gib deinen Miningschlüssel an: ",
"mining_key_required": "Ein Miningschlüssel ist erforderlich um auf diesem Konto zu schürfen",
"invalid_mining_key": "Der angegebene Miningschlüssel ist inkorrekt!",
"incorrect_username": "Der angegebene Nutzername existiert nicht!",
@@ -1428,7 +1428,7 @@
"connecting_node": " 取得したマイニングノード: ",
"new_version": "新しいバージョンが利用可能です、マイナーをアップデートしますか[Y/n]? ",
"updating": "マイナーが古くなっています。アップデート中....",
- "ask_mining_key": "マイニングキーを入力してください(ウェブウォレットでこのオプションを有効にした場合のみ必要です - Enterを押すとスキップします): ",
+ "ask_mining_key": "マイニングキーを入力してください: ",
"mining_key_required": "このアカウントでマイニングを行うには、マイニングキーが必要です",
"invalid_mining_key": "入力されたマイニングキーは無効です!",
"incorrect_username": "入力されたユーザーネームは存在しません!",
@@ -1522,7 +1522,7 @@
"connecting_node": " Haettu louhintanode: ",
"new_version": "Uusi versio on saatavilla, haluatko päivittää louhijan [Y/n] ? ",
"updating": "Louhija on vanhentunut. Päivitetään....",
- "ask_mining_key": "Anna louhintatunnus (vain tarvittaessa, jos olet aktivoinut tämän vaihtoehdon verkkolompakossa - paina Enter ohittaaksesi): ",
+ "ask_mining_key": "Anna louhintatunnus: ",
"mining_key_required": "Louhintatunnus vaaditaan tälle tilille louhimiseen",
"invalid_mining_key": "Annettu louhintatunnus on virheellinen!",
"incorrect_username": "Annettu käyttäjätunnus ei ole olemassa!",
diff --git a/Resources/PC_Miner_langs.json b/Resources/PC_Miner_langs.json
index da89d32e..63e225f1 100644
--- a/Resources/PC_Miner_langs.json
+++ b/Resources/PC_Miner_langs.json
@@ -92,7 +92,7 @@
"connecting_node": " Retrieved mining node: ",
"new_version": "A new version is available, do you want to update the miner (Y/n) ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!",
"running_on_rpi": "The miner seems to be running on a Raspberry Pi.",
@@ -203,7 +203,7 @@
"connecting_node": " mining node yang dipakai: ",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -294,7 +294,7 @@
"total_mining_time": "\n\t\t‖ 총 채굴 기간: ",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -385,7 +385,7 @@
"total_mining_time": "\n\t\t‖ تمام وقت کارکرد: ",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -476,7 +476,7 @@
"total_mining_time": "\n\t\t‖ Celková doba prevádzky: ",
"new_version": "K dispozícii je nová verzia, chcete aktualizovať miner [A/n] ? ",
"updating": "Miner je zastaraný. Aktualizujem....",
- "ask_mining_key": "Zadajte svoj ťažobný kľúč (povinné iba vtedy, ak ste túto možnosť aktivovali vo webovej peňaženke - preskočíte stlačením Enter): ",
+ "ask_mining_key": "Zadajte svoj ťažobný kľúč: ",
"mining_key_required": "Na ťažbu na tomto účte je potrebný ťažobný kľúč",
"invalid_mining_key": "Zadaný ťažobný kľúč je neplatný!"
},
@@ -550,7 +550,7 @@
"recommended": "raccomandato",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -647,7 +647,7 @@
"connecting_node": " Wybrano najszybszy serwer: ",
"new_version": "Znalezino nową wersję, chcesz zaktualizować koparkę? [Y/n] ? ",
"updating": "Koparka jest nieaktualna, aktualizacja w trakcie....",
- "ask_mining_key": "Wprowadź swoje hasło do kopania (mining key) (tylko jeżeli ustawiłeś je w portfelu internetowym - w przeciwnym razie wciśnij enter aby pominąć): ",
+ "ask_mining_key": "Wprowadź swoje hasło do kopania (mining key): ",
"mining_key_required": "Hasło do kopania jest wymagane do kopania na tym koncie",
"invalid_mining_key": "Podane hasło do kopania jest nieprawidłowe!",
"incorrect_username": "Podana nazwa użytkownika nie istnieje!",
@@ -727,7 +727,7 @@
"mining_not_exist_warning": " Asegurate de haber ingresado el nombre de usuario correcto. Revisa el archivo de configuraciones. Reintentando en 10s",
"new_version": "Hay una nueva version del minero, Quieres actualizarlo? [Y/n] ? ",
"updating": "El minero esta desactualizado. Actualizando....",
- "ask_mining_key": "Ingresa tu llave de minado (Solo es necesario si lo activaste en la web-wallet - presiona enter para saltar): ",
+ "ask_mining_key": "Ingresa tu llave de minado: ",
"mining_key_required": "Una llave de minado es necesaria para minar con esta cuenta",
"invalid_mining_key": "La llave de minado ingresada no es válida!"
},
@@ -820,7 +820,7 @@
"connecting_node": " Node de minage récupéré : ",
"new_version": "Une nouvelle version est disponible, voulez vous faire la mise à jour [Y/n] ? ",
"updating": "Le mineur est obsolète. Mise a jour...",
- "ask_mining_key": "Entrez votre clé de minage (mining key) - (Cela est seulement nécessaire si vous avez activé cette option dans le webwallet) : ",
+ "ask_mining_key": "Entrez votre clé de minage: ",
"mining_key_required": "Une clé de minage (mining key) est nécessaire pour miner sur ce compte",
"invalid_mining_key": "La clé de minage fournie est invalide !"
},
@@ -890,7 +890,7 @@
"mining_not_exist_warning": " Убедитесь в том, что вы правильно ввели имя пользователя. Пожалуйста, проверьте ваш файл настроек. Пробуем еще раз через 10с",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -986,7 +986,7 @@
"connecting_node": " Отриманий вузол майнінгу: ",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -1083,7 +1083,7 @@
"connection_search": "Suche nach der schnellsten Verbindung zu dem Server",
"new_version": "Eine neue Version ist verfügbar, möchtest du den Miner updaten [Y/n] ?",
"updating": "Der Miner ist nicht aktuell. Aktualisierung....",
- "ask_mining_key": "Mining-Key eingeben (nur notwendig, wenn du diese Option in deinem Webwallet aktiviert hast - drücke Enter zum überspringen): ",
+ "ask_mining_key": "Mining-Key eingeben: ",
"mining_key_required": "Es wird ein Mining-Key benötigt, um an diesem Account zu minen",
"invalid_mining_key": "Der eingegebene Mining-Key ist ungültig!",
"running_on_rpi": "Der Schürfklient scheint auf einem Raspberry Pi zu laufen.",
@@ -1163,7 +1163,7 @@
"mining_not_exist_warning": " 确保您正确输入了用户名。请检查您的配置文件。 将在10秒内重试",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -1234,7 +1234,7 @@
"mining_not_exist_warning": " 請確認您正確輸入了帳號名稱。請檢查您的設定檔。將在10秒後重試。",
"new_version": "線上有新版本可更新,您想更新挖礦程式嗎? [Y/n] ? ",
"updating": "挖礦軟體過舊。正在更新中.....",
- "ask_mining_key": "請輸入您的挖礦密碼 (只有在您的網絡錢包中啟用此選項時才需要設定 - 按 Enter 鍵跳過): ",
+ "ask_mining_key": "請輸入您的挖礦密碼: ",
"mining_key_required": "此帳號挖礦需要挖礦密碼",
"invalid_mining_key": "您提供的挖礦密碼無效!"
},
@@ -1306,7 +1306,7 @@
"connection_search": "Sunuculara bağlanmak için en hızlı bağlantı aranıyor",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -1396,7 +1396,7 @@
"total_mining_time": "\n\t\t‖ Tempo de atividade total do minerador: ",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -1462,7 +1462,7 @@
"load_config_error_warning": "/Miner_config.cfg). Ipprova neħħih u erġa 'ibda l-iskavatur. Agħlaq f'10 sekondi",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -1553,7 +1553,7 @@
"total_mining_time": "\n\t\t‖ เวลาที่ตัวขุดทำงานทั้งหมด: ",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -1649,7 +1649,7 @@
"connecting_node": " पुनर्प्राप्त खनन नोड: ",
"new_version": "A new version is available, you want to update miner [Y/n] ? ",
"updating": "The miner is outdated. Updating....",
- "ask_mining_key": "Enter your mining key (only required if you activated this option in the webwallet - press enter to skip): ",
+ "ask_mining_key": "Enter your mining key: ",
"mining_key_required": "Mining key is required to mine on this account",
"invalid_mining_key": "The mining key you provided is invalid!"
},
@@ -1745,7 +1745,7 @@
"connecting_node": " Získaný těžební uzel: ",
"new_version": "Je dostupná nová verze. Chceš aktualizovat těžební program [Y/n] ? ",
"updating": "Těžební program je zastaralý. Aktualizuji....",
- "ask_mining_key": "Zadej svůj těžební klíč (požadováno v případech, kdy tato možnost byla nastavena ve webové peněžence - stiskni enter pro přeskočení): ",
+ "ask_mining_key": "Zadej svůj těžební klíč: ",
"mining_key_required": "Těžební klíč je nutný pro těžbu na tomto účtu",
"invalid_mining_key": "Zadaný těžební klíč je neplatný!",
"running_on_rpi": "Vypadá to, že tento těžební program jede na Raspberry Pi.",
@@ -1856,7 +1856,7 @@
"connecting_node": " 取得したマイニングノード: ",
"new_version": "新しいバージョンが利用可能です、マイナーをアップデートしますか(Y/n) ? ",
"updating": "マイナーが古くなっています。アップデート中....",
- "ask_mining_key": "マイニングキーを入力してください(webwalletでこのオプションを有効にした場合のみ必要です - Enterを押すとスキップします): ",
+ "ask_mining_key": "マイニングキーを入力してください: ",
"mining_key_required": "このアカウントでマイニングを行うには、マイニングキーが必要です",
"invalid_mining_key": "入力されたマイニングキーは無効です!",
"running_on_rpi": "マイナーはRaspberry Piで動作しているようです。",
@@ -1961,7 +1961,7 @@
"connecting_node": " Haettu louhintanode: ",
"new_version": "Uusi versio on saatavilla, haluatko päivittää louhijan (Y/n) ? ",
"updating": "Louhija on vanhentunut. Päivitetään....",
- "ask_mining_key": "Syötä louhintatunnuksesi (vain tarpeen, jos aktivoit tämän vaihtoehdon web-lompakossa - paina enter ohittaaksesi): ",
+ "ask_mining_key": "Syötä louhintatunnuksesi: ",
"mining_key_required": "Louhintatunnus vaaditaan tälle tilille louhimiseen",
"invalid_mining_key": "Antamasi louhintatunnus on virheellinen!",
"running_on_rpi": "Louhija näyttää toimivan Raspberry Pi:llä.",
diff --git a/Tools/duco-install-rpi.sh b/Tools/duco-install-rpi.sh
index 55c81548..3763cbf5 100755
--- a/Tools/duco-install-rpi.sh
+++ b/Tools/duco-install-rpi.sh
@@ -19,7 +19,7 @@ if [ ! -d ~/duino-coin/ ];then
fi
cd ~/duino-coin
-echo "Installing python packages"
+echo "Installing Python packages"
python3 -m pip install -r requirements.txt # Install pip dependencies
#Check if the app exists
@@ -32,7 +32,7 @@ fi
mkdir -p ~/.local/share/applications
echo "[Desktop Entry]
Name=Duino Coin PC Miner
-Comment=Duino Coin miner for the raspberry pi
+Comment=Duino Coin miner for the Raspberry Pi
Exec=python3 /home/$u/duino-coin/PC_Miner.py
Icon=/home/$u/duino-coin/Resources/PCMiner.png
Terminal=true
@@ -56,7 +56,7 @@ Type=Application
Categories=Utility;
StartupNotify=true" > ~/.local/share/applications/duino-coin-avr.desktop
cd ~/
-if [ -f ~/duco-install-rpi.sh]; then
+if [ -f ~/duco-install-rpi.sh ]; then
rm duco-install-rpi.sh
fi
-echo "Installed"
\ No newline at end of file
+echo "Installed"