起因 前段时间把我的小主机连带路由器硬盘等设备带回了老家,老家也有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 // 板载的绿色LED指示灯是PC13 #define ledPin PC13 Servo myServo; void setup() { pinMode(ledPin, OUTPUT); // 默认关闭LED指示灯 digitalWrite(ledPin, HIGH); Serial.begin(); // MG90s的脉冲范围是500ms~2500ms myServo.attach(servoPin, 500, 2500); // 初始设置为20度 myServo.write(20); } void loop() { if(Serial.available()) { String c = Serial.readString(); int deg; bool shouldExec = true; if (c == "1") { // 如果收到了字符串"1",则正向旋转到40度,打开硬盘盒开关 deg = 40; } else if (c == "2"){ // 如果收到了字符串"2",则反向旋转到0度,用作测试 deg = 0; } else { shouldExec = false; } if (shouldExec) { // 打开LED指示灯 digitalWrite(ledPin, LOW); // 执行舵机旋转 myServo.write(deg); // 1秒后关闭LED指示灯 delay(1000); digitalWrite(ledPin, HIGH); } } // 复原舵机 myServo.write(20); } 写完后,点击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 后面遇到停电了,可以直接命令行远程启动硬盘盒。但是如果断网了,那估计神仙也救不了。 实际效果
使用USB接口连接STM32F103C并控制舵机
起因
前段时间把我的小主机连带路由器硬盘等设备带回了老家,老家也有ipv6,所以无缝衔接,随后安心出去游玩。某天我一如既往地打开nextcloud准备上传图片,发现服务挂了,然后发现是家里停过几小时的电。虽然路由器和小主机都有来电自启,但硬盘盒通电后需要手动按一下开关才能启动,我人不在家,所以这段时间和NAS相关的服务全都无法启动。 遂琢磨着弄个东西远程启动硬盘盒。
调研
这个功能如果用树莓派做应该很简单,但我没有带回来,而且用树莓派专门操作一个舵机也太杀鸡用牛刀了。第一个想到的当然是单片机,一顿搜索,目标定位到了ESP32和STM32,都是非常便宜的单片机,两者的资料也都非常多。 但,不是ESP32买不起,而是STM32更有性价比,6.1元买一个单片机,只能感叹现代的工业化太发达了。然后再搜索相关资料,以及问ChatGPT,发现STM32到手后不能直接通过USB操作,必须要装一个bootloader,而装bootloader需要另一个单片机,CH340,也非常便宜。 所以需要购买的东西如下:
STM32F103C8T6
大概6元CH340土豪金
大概3元MG90s舵机(金属齿)
大概6元上手
工作几年,我本就贫乏的硬件知识几乎全部忘了,好在互联网上啥都有,又一顿搜索,找到这个神奇的视频:
硬件安装
连线非常简单,就三根线,把舵机的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 // 板载的绿色LED指示灯是PC13 #define ledPin PC13 Servo myServo; void setup() { pinMode(ledPin, OUTPUT); // 默认关闭LED指示灯 digitalWrite(ledPin, HIGH); Serial.begin(); // MG90s的脉冲范围是500ms~2500ms myServo.attach(servoPin, 500, 2500); // 初始设置为20度 myServo.write(20); } void loop() { if(Serial.available()) { String c = Serial.readString(); int deg; bool shouldExec = true; if (c == "1") { // 如果收到了字符串"1",则正向旋转到40度,打开硬盘盒开关 deg = 40; } else if (c == "2"){ // 如果收到了字符串"2",则反向旋转到0度,用作测试 deg = 0; } else { shouldExec = false; } if (shouldExec) { // 打开LED指示灯 digitalWrite(ledPin, LOW); // 执行舵机旋转 myServo.write(deg); // 1秒后关闭LED指示灯 delay(1000); digitalWrite(ledPin, HIGH); } } // 复原舵机 myServo.write(20); }
写完后,点击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
后面遇到停电了,可以直接命令行远程启动硬盘盒。但是如果断网了,那估计神仙也救不了。