起因

前段时间把我的小主机连带路由器硬盘等设备带回了老家,老家也有ipv6,所以无缝衔接,随后安心出去游玩。某天我一如既往地打开nextcloud准备上传图片,发现服务挂了,然后发现是家里停过几小时的电。虽然路由器和小主机都有来电自启,但硬盘盒通电后需要手动按一下开关才能启动,我人不在家,所以这段时间和NAS相关的服务全都无法启动。 遂琢磨着弄个东西远程启动硬盘盒。

调研

这个功能如果用树莓派做应该很简单,但我没有带回来,而且用树莓派专门操作一个舵机也太杀鸡用牛刀了。第一个想到的当然是单片机,一顿搜索,目标定位到了ESP32和STM32,都是非常便宜的单片机,两者的资料也都非常多。 但,不是ESP32买不起,而是STM32更有性价比,6.1元买一个单片机,只能感叹现代的工业化太发达了。然后再搜索相关资料,以及问ChatGPT,发现STM32到手后不能直接通过USB操作,必须要装一个bootloader,而装bootloader需要另一个单片机,CH340,也非常便宜。 所以需要购买的东西如下:

  • STM32F103C8T6大概6元
  • CH340土豪金大概3元
  • MG90s舵机(金属齿)大概6元

上手

工作几年,我本就贫乏的硬件知识几乎全部忘了,好在互联网上啥都有,又一顿搜索,找到这个神奇的视频:

保姆级教程
上面的视频讲解了(Windows环境)如何刷bootloader,如何安装驱动,如何通过USB上传代码到STM32。成功实现视频结尾的示例,就算成功了。

硬件安装

连线非常简单,就三根线,把舵机的5V和GND接在STM32的5V和GND上,信号线接在STM32的A1针。 需要把舵机固定在硬盘盒的合适位置: 安装前 安装后

编码

又到了喜闻乐见的show me the code环节,代码是c写的,也非常简单:

#include <Servo.h> #include "Arduino.h" #include <usb_serial.h> #include <HardwareSerial.h> #include <libmaple/usart.h> #include <libmaple/usb_cdcacm.h> // 把舵机的信号线接到STM32的A1口 #define servoPin PA1 Servo myServo; void setup() { Serial.begin(); // MG90s的脉冲范围是500ms~2500ms myServo.attach(servoPin, 500, 2500); // 初始设置为0度 myServo.write(0); } void loop() { if(Serial.available()) { String c = Serial.readString(); // 如果收到了信息1,则旋转20度,打开硬盘盒开关 if (c == "1") { myServo.write(20); delay(1000); } } // 1秒后复原舵机 myServo.write(0); delay(1000); }

写完后,点击Arduino IDE左上方的上传按钮,编译并上传代码到STM32,这时在Serial Monitor上输入1并回车,舵机会旋转20度,1秒后复原。 测试完成,把STM32转移到linux小主机的USB接口,linux一般自带驱动,什么都不用做,就能发现/dev/下多了一个设备,我的是/dev/ttyACM0,操作方法如下:

# 修改权限 sudo chmod o+rw /dev/ttyACM0 # 发送命令 echo -ne '1' > /dev/ttyACM0

后面遇到停电了,可以直接命令行远程启动硬盘盒。但是如果断网了,那估计神仙也救不了

实际效果