使用 Arduino 打造一个硬件的Watchdog

我的台式机使用梅捷 SY-D2700-U3M 的主板,固化了Intel D2700 Atom CPU。具有零噪音(无风扇),节能环保,扩展丰富等等特点。唯一的问题是:经常硬盘丢失。具体是在使用中忽然BSOD,然后自动重启之后在Setup中无法找到硬盘,重启无效,必须关机一次再开机。从我的经验来看这绝非BIOS问题,并且实验确定不是硬盘问题。有人看守的情况下遇到这样的最多只是郁闷一些,但是作为下载机的时候,上述的问题就变得令人难以忍受。于是,考虑做一个硬件的 WatchDog,当出现问题的时候自动完成关闭开关,再次重启的动作。

BOM 如下:

1. Arduino UNO
2. WCH341 USB转串口
3. 面包板
4. 杜邦线+大头针
5. 继电器

说说上面这些东西,最重要的是继电器,就是下面这个东西。

1

这是两路的继电器,可以控制2组电路。性能指标是“交流电压最大250V,交流电流最大10A,直流电压最大30V,直流电流最大10A”。有4个输入针脚,分别是VCC GND,1IN 和2IN可以直连Arduino IO口。上电之后,1IN和2IN可以直接接入到VCC和GND上,应该能听到继电器“啪”的吸合的声音,此时测量受控端的电阻可以得知当前是断开还是链接。

2

再说一下喂狗的WCH341。 一般来说,Arduino的USB口可以用来取电和串口通讯。实际使用中我关闭台式机后,USB口供电也会随之切断,因此Arduino必须使用外部供电。既然使用了外部供电,串口也只能使用外部输入。刚开始选择的是FDTI 的USB转串口,一直无法正常通讯,最后测量发现它转出来的电压在 6.2v左右(TX/RX)远超过了.预期的5V。WCH341是之前玩单片机的剩下的,测量之后发现它的输出电压能够满足要求,于是就选用之。还有需要注意的是,完整的串口通讯实际上需要3跟线:TX RX和GND.

引出PowerButton的2个Pin.

3

继电器直接控制PowerButton Pin。

4

绿线接到继电器上进行控制

5

Arduino代码:

#include //引用库
/*
Simple LED sketch
*/

int led = 13; // Pin 13 当连接(相当于按下PowerButton)时点亮,断开时关闭
int cnt = 10; // Pin 10 控制继电器,高时断开,低时连接

unsigned long int elsp=0; //计算时间

void setup()
{
pinMode(led, OUTPUT); // Set pin 13 as digital out
pinMode(cnt, OUTPUT); // Set pin 10 as digital out
digitalWrite(led, LOW); // off
digitalWrite(cnt,HIGH); //Cut OFF

// Start up serial connection
Serial.begin(9600); //baud rate
Serial.flush();
elsp=millis();

wdt_enable(WDTO_8S); //这是Arduino的看门狗可以更换其他时间值
//注意,这里是8s,后面的延时不可以直接超过8s
}

void loop()
{

// Read any serial input
while (Serial.available() > 0)
{
if ((char) Serial.read() == ‘P’) {elsp=millis(); }
//当收到”P”时,重置计时器。换句话,我们用字符 “P” 来喂狗
}

if (abs(millis()-elsp)>300*1000UL) //300s = minutes
{
digitalWrite(led, HIGH); // on
//关机动作
digitalWrite(cnt,LOW); //继电器短路,相当于按下PowerButton
wdt_reset(); //重置Arduino内部看门狗
delay(6000); //这里相当于长按PowerButton 6s
wdt_reset(); //重置Arduino内部看门狗
digitalWrite(cnt,HIGH); //继电器断路,相当于松开PowerButton
//松开PowerButton 5s
delay(5000);
wdt_reset(); //重置Arduino内部看门狗
//开机上电
digitalWrite(cnt,LOW); //继电器短路,相当于按下PowerButton
delay(500); //按下500ms
digitalWrite(cnt,HIGH); //继电器断路,相当于松开PowerButton
elsp=millis();

digitalWrite(led, LOW); // off
wdt_reset(); //重置Arduino内部看门狗
}
delay(1000);
Serial.println(millis()-elsp);
wdt_reset(); //重置Arduino内部看门狗如果loop时间超过时限,系统会重启
}

6

除了Arduino的Firmware,PC端喂狗也需要一个程序。选择Delphi编写程序,实现两个功能:1.扫描COM Port找到进行通讯的端口 2.每隔一段时间就进行一次喂狗

(此处Delphi代码,Console模式)
HWDog

7

参考:

1. http://biosren.com/thread-6794-1-1.html 《改动代码提取器》

发表评论

电子邮件地址不会被公开。 必填项已用*标注