SEDIMENTARY ROCK - 微控
type: channel
link: https://www.sedirk.cn/index.php/category/micro_controller/
items: Ender-3 V2 奇技淫巧救砖笔记
items: 用Arduino制作一个摇杆式鼠标&温度监视器

Ender-3 V2 奇技淫巧救砖笔记
type: item
date: 2025-10-05T19:05:00+00:00
description: 出于一些原因我搞到了一台 Ender-3 V2 打印机，拧好了螺丝调好了平之后开机发现它读不出自带的 TF 卡里的文件。于是从树莓派里掏张卡出来，装几个 gcode 文件进去，重启打印机⸺然后发现卡在启动界面了。查打印机的说明书才发现它在开机时会自动读取 TF 卡里 .bin 文件。原来用在树莓派上的卡里肯定有不少 .bin 文件，猜测是打印机把其中的一个当打印机固件读取并刷写了，导致不开机。那怎么修复呢？你想看普通的修复教程？不不，那样就和随处可见（存疑）的论坛帖子没有区别了，这是为了博客特制的，明白吗？请阅读下文以感受我修复之路的痛楚⋯⋯尝试“正常”的修复方法去 创想三维的固件发布页 找到了原版固件，阅读说明得知只要把新固件放进 TF 卡里装进机器就可以自动更新固件。听起来非常的简单是不是，我们动手做一下吧。先把树莓派卡格式化成 FAT32，装上固件⸺等一下，这么多固件我选哪个，怎么也没有说明？从主板盖板下面的缝里打光能看到主板版本是 V4.2.2，就选个比较新而且不花里胡哨的 Ender-3 V2_HW_V4.2.2_SW_V1.0.7 吧。装上 TF 卡，重启打印机，然而并没有解决问题，还是卡在启动画面。换了原装 TF 卡装固件，还是没有作用。上网查一下呢？在 一篇红迪帖子 里找到了修复方法：用一张格式化为 FAT32，簇大小 4096B，容量不超过 32GB 的 TF 卡装上固件插进打印机里。按照指示重新格式化了卡然后装上固件，但依旧没有解决问题。打开主板盖板，拔掉常开风扇、挤出头加热棒、挤出头热敏电阻的线。还是没用。拆开挤出头，松一松固定热敏电阻的螺丝。什么也没有发生。那接下来怎么办？开始发癫抱着试一试的想法插了根线到打印机的 USB 口，然后 lsusb 一下，发现了经典 CH340 串口芯片。用串口终端打开一看，还真收到了打印机发送的信息：Update failed, No SD/TF-Card or error。但我明明装了卡啊，而且一开始不就是因为从这卡上错误地读了二进制文件才导致了问题的吗？猜测是误刷的固件把整块主控都搞得乱糟糟的了（实际上这个猜测错得离谱)｡在主板上一通搜索，发现了熟悉的 SWDIO 和 SWCLK SWD 接口。连上 DAPLink 调试器，pyOCD 启动！警告：不要贸然尝试以下的任何代码！SWD 刷写很容易就可以把你的主控送上天！初步尝试 SWD观察主板得知主控芯片是 GD32F303RET6，那就先下载对应的目标文件：pyocd pack install GD32F303RE，成功建立与主控的通信。以防万一先读取备份一下主控的固件：pyocd cmd --target gd32f303re -c reset halt -c savemem 0 0x400000 e3v2_gd32f303_dump.bin（事后发现这个操作救了我）现在我们可以大胆去做了。先 pyocd erase -t gd32f303re -c 清空存储器，然后 pyocd flash --target gd32f303re -v ./GD-Ender-3\ V2Marlin2.0.6.1V1.0.5HW4.2.2 试着刷写原厂固件。然后不出所料地没用。插上 USB 线发现糟了，串口都没输出了。再次上网查资料：神秘的 RepRap 论坛 网友提到 V4.2.2 版本主板的固件应该存在 0x08007000 位置之后，而 0x0800000-0x08006FF 的这一段地址是分配给 bootloader 的。继续查阅 GD32F303 的技术手册，发现 0x00000000-0x002fffff 的这一段地址是映射到位于 0x08000000 - 0x082fffff 的主 FLASH 存储器的，而默认状况下这颗芯片上电后从 0x00000000 开始执行。看来通过 SWD 直写固件不工作的原因是固件需要依赖 bootloader 的存在才能工作，或者是链接时写死的内存位置因为我从 0x0000000 开始直接写入固件也混乱了。那么，原本的 bootloader 似乎不起作用，厂商提供的固件又依赖 bootloader 才能工作，我该怎么办呢？似乎自己编译固件才是唯一的方法了，毕竟这只是个普通的微控制器，也有开源的固件，想整一些非常规的花活应该也不困难。编译固件还好 Ender-3 V2 原装的固件就是基于 Marlin 的，对它的社区支持也相当完善，按照 Marlin 官方指引 很快就改好了一个配置文件。这里要注意创想三维在不改变主板版本号的情况下居然推出了使用两种（甚至更多）主控芯片的主板：有的是 STM32F1 系列，有的是 STM32F3 系列，还有的是 GD32F3 系列，而且（显然的）它们的固件并不通…

用Arduino制作一个摇杆式鼠标&温度监视器
type: item
date: 2020-08-21T08:07:00+00:00
description: 为了把之前挖的说要搭一台UMPC的大坑给填上，必须要有一个足够小的、能当鼠标用的装置，所以就弄出了这么个玩意...首先看看这个项目的原型，Toshiba Libretto系列和Thinkpad 750，都是使用的指点杆然而指点杆太贵了，一个要40多，而且PCB还很大，装不进键盘里，所以实际上和摇杆没什么区别了...那就弄摇杆好了...然后事实证明便宜确实没好货，摇杆转20°左右就满量程了，而且阻尼很大，用起来让人觉得喝了假酒那么要怎么让它用起来稍微好一点呢？因为阻尼大，转起来很难精确控制转动的角度 --> 那就降低光标的移动速度然而这样光标要走过很长的距离时就很痛苦 --> 弄个加速键这样虽然说妥协很大，用起来远远不如小红点顺手，但是...嘿！它能用！再把左键，右键，中键加上之后用一段时间还算顺手，那就这样了吧...既然用了Arduino来当鼠标了，那不加一块屏幕就太浪费了于是就弄了那块128*64，0.96'的OLED屏幕显示下温度，风扇转速和警告信息，看起来相当不错(最终效果见上图)(测试中...)然后是用这玩意解决一些在测试其它系统的时候发现的问题：本来是准备用一个简单的霍尔+MOSFET的独立电路来做到控制主屏幕在开合时的开关的，结果P沟道MOSFET忘买了...再去为了一个MOSFET付十块钱的运费实在是不值，也懒得拿三极管做非门了...那就干脆用Arduino解决算了这里没什么好讲的，就是给栅极10k的下拉电阻似乎太小了，直接上680k下拉解决键盘是买的现成的，拿到手发现虽然质量还行，但是有Z+Shift会和方向左键冲突...本来这不是什么大问题，但是对于东方玩家来说实在致命...于是就弄了个自锁开关，按下会一直按Z，问题解决！最后，还有50%的剩余ROM空间，那就加个非常中二的Boot Screen好了...最后的最后，放下写的稀烂的代码(BootScreen删掉了)#include <Mouse.h> #include <Keyboard.h> #include <U8glib.h> U8GLIB_SSD1306_128X64 u8g(4, 5, 6); const int xPin = A0; const int yPin = A1; const int caliButton = 9; const int caliIndi = 16; const int lButton = 12; const int rButton = 10; const int mainSW = 3; const int scrlSW = 11; const int accSW = 2; const int zButtonSW = 1; const int CPUTempSensor = A5; const int battTempSensor = A4; const int fanPin = 0; const int hallSensor = 7; const int screenMOSFET = 8; //Pin configuration int xCali; int yCali; //Create variables for calibration int xCalied; int yCalied; int xProcessed; int yProcessed; int CPUtemp; int battTemp; int fanSpeed; boolean mouseSwitch; //Declaring variables void setup() { Serial.begin(9600); Mouse.begin(); mouseSwitch = 0; pinMode(accSW, INPUT_PULLUP); u8g.setFont(u8g_font_7x13B); } void loop() { CPUtemp = ((analogRead(CPUTempSensor) - 240) / 11); battTemp = ((analogRead(battTempSensor) - 240) / 11);//Temperature monitoring fanSpeed = (CPUtemp * 6) - 240; if (fanSpeed > 0){ analogWrite(fanPin, fanSpeed); }else{ analogWrite(fanPin, 0); }//Fan control if (digitalRead(hallSensor) == HIGH){ digitalWrite(screenMOSFET, HIGH); }else{ digitalWrite(screenMOSFET, LOW);…