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); } } }