本帖最后由 我輩樹である 于 2024-11-29 17:38 编辑
人,物,事
做为一名坚定的星巴克背包侠 + 服务器remoting党,游戏只玩3A大作原崩绝,一直以来装一台日常机器好像对我没啥用。
之前都是装了拆拆了装,家里的那几台破烂只是满足尝试新配件或新方案的载体。
故事源于阴差阳错的加入了FormD T1 China官方群。这个群里面可以不活但不能没活的老登比较多,他们时不时发点东西,总能够刺激你对自己的机器做点什么,所以感觉自己也不得不整点啥来满足一下虚荣。
从某种程度来说,我这次装机也算是时髦的社区驱动了。
FormD T1是一款体积控制在9.99升的A4架构纵梁可调整的ITX机箱,它也算ITX装机界的老熟人网红机箱了。
我所用的2.0版本是很稀有的版本了,所以本贴里面分享的东西,包括图纸其实都没有什么参考意义,如果要使用均需要经历调整和验证。
此外,这是我第一次采用数字化的装机方式,首先通过测量机箱部件并在软件中建立起3D CAD模型,基于这个CAD模型完善自己的设计,然后通过3D打印和来自嘉立创的铝合金CNC打样进行反复验证,最后进行装机测试。
我之前从来没有做过CAD建模,但有一定Mesh建模的基础,且软件上选择了面向初学者的Autodesk Fusion360软件,所以这个过程反倒不是很困难。
验证无疑是整个流程中最困难的一步,大量的3D打印件和高昂的铝合金打样,付出了无数的时间和金钱(3D打印200个小时以上,嘉立创CNC打样1W+的费用)。
新手的学费是高昂的,但也不得不感叹蓝星第一的工业实力,就这么一个玩票的坐在家中就能相对廉价的调用加工机器实现自己的想法,可不敢轻易想象。
设计的概念是制作一款“刚体(Rigidbody)”机器。 全身尽量使用金属构成,部件和线束牢牢的固定在机体上,适应运输环境。
1. 设备清单
硬件设备:
机箱 | FormD T1 V2.0
| 中央处理器
| AMD Ryzen 9 7950X3D
| 图形处理器
| NVIDIA GeForce RTX 4090 Founder Edition
| 主板
| ASUS ROG STRIX X670E-I GAMING WIFI
| 内存 | SK Hynix 48GB 5600Mhz OC 6400Mhz x 2
| 固态硬盘
| FANXIANG S790 4TB x 2
| 电源
| ROG Loki 1000W
|
水冷设备:
处理器冷头
| Modultra LOBO AM5 + Emitter Heatsink
| 冷排
| XSPC TX240 Crossflow Ultrathin Radiator
| 风扇
| Noctua A12X25 Black Editon x 2
| 接头
| EKWB、Bitspower、Barrow、Bykski
|
嵌入式设备:
核心算力模组
| M5Stack M5Core2
| AI摄像头模组 | M5Stack UNITV2 USB + UVC Camera | 继电器模组
| M5Stack 4Relay Module
| 指纹识别模组
| M5StickC Plus + M5StickC Fingerprint HAT
|
其他设备:
2. 成品展示
这里展示两款皮肤。 第一套皮肤。 这款皮肤的设计概念是挂件。侧板开窗,均有螺丝孔位可以挂上特别定制的铭牌等。 这款皮肤的设计概念是YOLO。类似目标检测框体的方式将主要部件框出。 本来想做分件彩色的,可惜价格太贵放弃了。 水冷管因为无法CNC的原因,使用304不锈钢打印。 充分利用了公版显卡自带的服务器支架安装位。
水冷总成
包括:冷排,冷头,水冷管。
从这里可以看出,本次安装展示并不是从零开始的。 因为我是装完后再边拆边拍照的,但是水冷一旦装好不排水的话就很难拆卸,就放弃了。
水冷管采用嘉立创的304不锈钢打印,除了可以走复杂造型外,还省去了自己弯管的麻烦。 缺点是外观如果不做处理就只有不锈钢本色可选了。 另外,经测试没有发现和铜水路的电化学反应。
所有三根电源线均为定制长度,ATX24PIN线材还特意建模并定制了不等长线材,以最大限度的节省空间。 水路采用内外循环被动切换的方式。
在不安装显卡的情况下已经可以开机测试了。
取下前置显示屏,安装显卡。
装完显卡后,还需要安装显卡的固定扣具。 显卡的12vhpwr供电线采用中间走线直达电源的方式。 这对机箱的布局有一些小小的要求。要采用“双抬”的方案。 即A4的两侧(主板侧和显卡侧)都需要抬升以远离中间的纵梁。 这样才能腾出空间安装12vhpwr的180度转接头。
最后是安装电源延长线了。 因为电源被抬高,能够使用的电源线屈指可数。 经过寻找,这款来自JLMake的电源线符合要求。 三根黑色镀银线穿过导线器接入AC母口。 借用成品图中的一张来说明。 在机器之外我还安排了一套基于ESP32的嵌入式“带外管理”系统。 采用的方案是M5STACK全家桶。 M5STACK是嵌入式入门非常友好的品牌,模块化的设计提供了很多功能,有利于新手。 AI摄像头模块自带算力和一系列视觉算法,可以无需编程构建一些简单的感知类应用。 设备由USB供电驱动同时进行串口连接。 为了能放入狭小的机体,外壳都进行了重新设计,并使用CNC铝合金制作,加强散热。
包含:核心计算板、AI摄像头、继电器模块和M5STICK指纹模块。 目前能做的事情就是:人脸识别与远程指纹开机。 “带外系统”虽然做之前想了很多,但确实没有精力和时间去实现了。 完成这2个功能只需要2段简短的代码。 因为AI摄像头可以检测人脸然后通过串口以JSON的形式回报结果,那么在核心算力模块上,需要运行一段代码来解析这个结果。 核心算力模块M5Core2可以安装一个继电器模块,将它和主板插针连接,就可以通过核心算力模块控制计算机开关机了。 代码如下(C/C++): - #include <ArduinoJson.h>
- #include <M5Core2.h>
- #include "Module_4RELAY.h"
- #include <WiFi.h>
- #include <WebServer.h>
- MODULE_4RELAY RELAY;
- HardwareSerial SerialPortA(1);
- StaticJsonDocument<512> send;
- StaticJsonDocument<512> receive;
- char jsonBuffer[512];
- int succeededDetectCount = 0;
- int failedDetectCount = 0;
- String detectedName = "liu";
- float matchProbThreshold = 0.5;
- // 自建AP的账号和密码
- const char* ssid = "RYU_M5STACK";
- const char* password = "PASSWORD";
- WebServer server(80);
- void setup() {
- M5.begin();
- M5.Axp.SetBusPowerMode(0);
- delay(100);
- Serial.begin(9600, SERIAL_8N1);
- delay(100);
- SerialPortA.begin(115200, SERIAL_8N1, 33, 32);
- delay(100);
- RELAY.begin(&Wire, MODULE_4RELAY_ADDR, 21, 22, 200000L);
- delay(100);
- send["function"] = "Face Recognition";
- send["args"] = "";
- serializeJson(send, jsonBuffer);
- SerialPortA.println(jsonBuffer);
- delay(100);
- WiFi.softAP(ssid, password);
- delay(100);
- Serial.printf("WiFi AP created. IP address: %s \n", WiFi.softAPIP().toString());
- delay(100);
- //建立一个Web Server,用来响应远程指令
- server.on("/genshinstart", powerOn);
- server.begin();
- }
- void powerOn() {
- RELAY.setAllRelay(true);
- Serial.println("Relay On");
- delay(100);
- RELAY.setAllRelay(false);
- Serial.println("Relay Reset");
- server.send(200, "text/plain", "from m5stack core2.");
- delay(10000);
- succeededDetectCount = 0;
- }
- void loop() {
- server.handleClient();
- String receivedJson = SerialPortA.readStringUntil('\n');
- deserializeJson(receive, receivedJson);
- if (receive["num"].as<int>() == 1) {
- String name = receive["face"][0]["name"].as<String>();
- float matchProb = receive["face"][0]["match_prob"].as<float>();
- Serial.printf("name: %s | prob: %.2f \n", name, matchProb);
- if (name == detectedName && matchProb >= matchProbThreshold) {
- succeededDetectCount++;
- if (succeededDetectCount >= 3) {
- RELAY.setAllRelay(true);
- Serial.println("Relay On");
- delay(100);
- RELAY.setAllRelay(false);
- Serial.println("Relay Reset");
- delay(10000);
- succeededDetectCount = 0;
- }
- } else {
- failedDetectCount++;
- if (failedDetectCount >= 20) {
- succeededDetectCount = 0;
- failedDetectCount = 0;
- Serial.println("Detect Count Reset");
- }
- }
- }
- delay(500);
- }
复制代码代码中还有一段让核心算力模块自建AP并创建一个Web服务器的部分,这一部分主要服务于指纹模块。
指纹模块是由M5StickC Plus和其指纹模块组成。 在检测到正确的指纹后,该模块会向核心算力模块的Web服务器发送指令的方式进行开关机控制。 代码如下(python): - from m5stack import *
- from m5ui import *
- from uiflow import *
- import time
- import hat
- import network
- import urequests
- setScreenColor(0x111111)
- label0 = M5TextBox(71, 4, "Connecting to M5Stack Core2...", lcd.FONT_Default, 0xFFFFFF, rotate=90)
- hat_Finger_0 = hat.get(hat.FINGER)
- wlan = network.WLAN(network.STA_IF)
- ssid = wlan.config('essid')
- def connect_to_m5stack_core2():
- if wlan.isconnected() == True and ssid != 'RYU_M5STACK':
- wlan.disconnect();
- wlan.active(False)
- if wlan.isconnected() == False:
- wlan.active(True)
- wlan.connect('RYU_M5STACK', 'PASSWORD')
- while not wlan.isconnected():
- time.sleep(1)
- print('Network config:', wlan.ifconfig())
- label0.setText('Connected.')
- pass
- connect_to_m5stack_core2()
- def unknown_fingerprint_cb():
- print('fingerprint identification failed.')
- pass
- def known_fingerprint_cb(user_id, access):
- print('fingerprint identification succeeded.')
- print(wlan.ifconfig()[2])
- response = urequests.get('http://<核心算力模块IP地址>/genshinstart')
- if response.status_code == 200:
- print('success.')
- print('response:', response.text)
- else:
- print('failed to fetch data.')
- response.close()
- print('control command delivered.')
- pass
- def add_new_fingerprint():
- print('start adding new fingerprint.')
- hat_Finger_0.addUser(1, 1)
- pass
- def remove_all_fingerprint():
- print('remove all fingerprint.')
- hat_Finger_0.removeAllUser()
- pass
- hat_Finger_0.getUnknownCb(callback=unknown_fingerprint_cb)
- hat_Finger_0.readFingerCb(callback=known_fingerprint_cb)
- btnA.wasPressed(add_new_fingerprint)
- btnB.wasPressed(remove_all_fingerprint)
- while True:
- label0.setText(str(hat_Finger_0.state))
- wait_ms(50)
复制代码这两段代码是非常简陋的,只实现了基本的功能,也没做任何验证,只作为抛砖引玉之用。
6. 出行箱套装
最后还缺一个旅行套装,因为还是想把它带出去逛逛,当然不是带去星巴克喝咖啡。
于是就定制了这款派力肯的1550设备箱,并配置了全套微软设计师套餐。
键鼠也有了,显示屏也有了,您是否是在找 笔记本电脑。
装入3D打印的收纳盒,然后装入定制的EVA海绵中。
整装,出发。
7. 完。
-------------------------------------------------------------------------------------------------------------------------------------------
时间,空间
超过一百张照片,超过一年半的折腾,也算有了一个落幕。
有很多想法、问题、和遗憾,只要还想做可以无尽的迭代下去。
但断舍离也同样的重要,拿得起要放得下。
成为一段我想分享给大家的、一段关于执着一件事情的快乐也未尝不是一件好事。
辛苦大家看到这里,还有很多内容无法言尽,如果有疑问我一定回答。
设计图纸和文档已在FormD T1 China官方群公开(群号:837637024),请谨慎使用。
谢谢。
|