WatchDog для фермы купить или сделать? Автоматический перезапуск майнинг ферм на Arduino.
Сегодня будем определяться с выбором: купить вотчдог на алиэкспресс или сделать самому из подручных материалов. Если раньше WatchDog’и для фермы стоили очень дорого в виду их не распространенности, то сейчас на рынке представлено огромное количество таких устройств.
Как всегда, у вас есть несколько вариантов, (2) :)
Содержание:
Вообще, если ферма настроена правильно, то она не должна зависать. Но бывают разные ситуации, например, вы настраивали ферму посредством Team Viewer и ошиблись в указании частот, а случайным стечением обстоятельств ферма находится далеко, далеко. В таком случае, вам и пригодится вотчдог.
Купить WatchDog — I Вариант
Давайте зайдем на алиэкспресс и посмотрим какой ассортимент сторожевых песиков предлагает данная площадка…
Действительно, представлен достаточно широкий выбор WatchDog для покупки, стоимость начинается от 226 рублей с бесплатной доставкой:
Изображение 1. Стоимость и ассортимент watchdog на aliexpress
Большинство устройств предлагают подключение не только к разъему Reset на материнской плате, но и к разъему питания (Power). Так как в некоторых случаях, компьютер перестает реагировать на сигналы перезагрузки, в таких случаях, необходимо выполнять «жесткую перезагрузку», удерживая кнопку питания определенный промежуток времени, и затем, повторно запуская устройство.
Помимо самого устройства в комплекте поставляется два провода для подключения watchdog к майнинг ферме. Дополнительно придется установить программное обеспечение, которое можно скачать с сайта производителя: https://vk.com/usbwatchdog.
Собрать самому — II Вариант
Шаловливые ручонки? Ну что ж, поехали…
Мы будем собирать нашу поделку на базе Arduino Nano, но подойдет и любая другая модель.
Так же нам потребуется:
Кнопка и коннектор (можно купить в любом компьютерном магазине)
Самый дешевый оптрон (продаются в радиомагазинах, стоимость около 15-30 рублей)
Схема подключения:
К Arduino GND:
- контакт от кнопки перезагрузки
- катод оптрона
- контакт от спикера (по желанию)
К цифровым выходам Arduino:
- D3 — контакт от кнопки перезагрузки
- D2 — анод оптрона
- D9 — контакт от спикера (по желанию)
«Выходы оптрона» — эмиттер и коллектор на разъем питания (Power SW) материнской платы.
Скетч для Arduino:
int speakerOut = 9;
int resetOut = 2;
int resetIn = 3;
int incomingByte = 0;
int iter = 0;
int sub_iter = 0;
bool b = false;
void setup() {
pinMode(speakerOut, OUTPUT);
pinMode(resetOut, OUTPUT);
pinMode(resetIn, INPUT);
digitalWrite(resetIn, HIGH);
Serial.begin(9600);
}
void loop() {
delay(100);
sub_iter++;
if(b && sub_iter > 10) {
tickTimer();
}
if(sub_iter > 10) {
sub_iter = 0;
}
if (Serial.available() > 0) {
incomingByte = Serial.read();
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
if(incomingByte == 49) {
startTimer();
} else if(incomingByte == 50) {
resetTimer();
} else if(incomingByte == 51) {
stopTimer();
} else if(incomingByte == 52) {
optoPWReset();
}
}
/*
Reset Btn
*/
if(digitalRead(resetIn) == LOW) {
digitalWrite(resetOut, HIGH);
Serial.println("Signal on resetIn");
} else {
digitalWrite(resetOut, LOW);
}
}
void startTimer() {
resetTimer();
b = true;
tone(speakerOut, 8000, 500);
}
void resetTimer() {
Serial.println("resetTimer");
iter = 0;
tone(speakerOut, 8000, 200);
}
void stopTimer() {
Serial.println("stopTimer");
b = false;
tone(speakerOut, 8000, 1000);
}
void tickTimer() {
Serial.print("tickTimer: ");
Serial.println(iter);
if(iter > 15) {
optoPWReset();
stopTimer();
}
iter++;
}
void optoPWReset() {
Serial.println("optoReset HIGH");
digitalWrite(resetOut, HIGH);
delay(6000);
Serial.println("optoReset LOW");
digitalWrite(resetOut, LOW);
delay(3000);
Serial.println("optoReset START");
digitalWrite(resetOut, HIGH);
delay(400);
digitalWrite(resetOut, LOW);
}
Программа на C#:
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleObs
{
class Program
{
internal delegate void SignalHandler(ConsoleSignal consoleSignal);
internal enum ConsoleSignal
{
CtrlC = 0,
CtrlBreak = 1,
Close = 2,
LogOff = 5,
Shutdown = 6
}
internal static class ConsoleHelper
{
[DllImport("Kernel32", EntryPoint = "SetConsoleCtrlHandler")]
public static extern bool SetSignalHandler(SignalHandler handler, bool add);
}
static SignalHandler signalHandler;
static SerialPort port;
static void Main(string[] args)
{
signalHandler += HandleConsoleSignal;
ConsoleHelper.SetSignalHandler(signalHandler, true);
Thread myThread = new Thread(SerialPortProgram);
myThread.Start();
Console.ReadKey();
}
static void SerialPortProgram()
{
string text = System.IO.File.ReadAllText(@"config.txt");
int com = int.Parse(text);
// получаем список доступных портов
string[] ports = SerialPort.GetPortNames();
Console.WriteLine("Выберите порт:");
// выводим список портов
for (int i = 0; i < ports.Length; i++)
{
Console.WriteLine("[" + i.ToString() + "] " + ports[i].ToString());
}
Console.WriteLine();
port = new SerialPort();
try
{
// настройки порта
port.PortName = ports[com];
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = System.IO.Ports.Parity.None;
port.StopBits = System.IO.Ports.StopBits.One;
port.ReadTimeout = 1000;
port.WriteTimeout = 1000;
port.DataReceived += DataReceivedHandler;
port.Open();
Console.WriteLine(ports[com] + " выбран");
Console.WriteLine();
Thread.Sleep(5000);
port.Write("1");
ConsoleKeyInfo k = new ConsoleKeyInfo();
do {
Thread.Sleep(10000);
port.Write("2");
} while (true);
}
catch (Exception ex)
{
Console.WriteLine("Exception" + ex.ToString());
return;
}
}
private static void HandleConsoleSignal(ConsoleSignal consoleSignal)
{
port.Write("3");
port.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.Write(indata);
}
}
}








