版本协议

CC BY-NC-SA 3.0

标签
专业版
#第九届立创电赛#VFD USB集线器+电脑性能监控器

创建时间:4个月前

225 0

描述

<h1>VFD电脑性能监控器+USB扩展与TF读卡器</h1> <p><img src="//image.lceda.cn/oshwhub/db6f66b521ab41e497c4e382af98fc63.jpg" alt="IMG_0080.jpg"></p> <h2>1. 项目功能介绍</h2> <p>手里弄到一批Futaba的16x2点阵屏,于是乎物尽其用做个小桌搭,但是现在社区里做VFD时钟的太多。我自己也做了很多钟,在做钟就有点搞笑了.... 那么就加点不一样的功能,我希望他可以具有链接电脑的能力使其进行赋能一些特性</p> <ol> <li>USB HUB扩展集线器</li> <li>SD/TF卡读卡器</li> <li>温湿度传感器</li> <li>可显示日期时间</li> <li>配套上位机,随意传输显示内容 <ol> <li>实时网速上下行</li> <li>CPU/内存使用率</li> <li>自定义文字</li> </ol></li> </ol> <h2>2. 项目属性</h2> <p>项目为首次公开,未参与任何活动、未向任何组织公布</p> <h2>3. 开源协议</h2> <p>CC BY-NC-SA 3.0(创意共享署名-非商业性-相同方式共享 3.0)是一种创意共享许可证,允许用户在特定条件下使用和分享作品。以下是该许可证的主要规定:</p> <p>署名(Attribution):用户在使用作品时必须给予适当的署名,提供许可证的链接,并说明是否对作品进行了修改。这一要求确保原作者得到应有的认可。</p> <p>非商业性(NonCommercial):该许可证禁止将作品用于商业目的。用户只能在非商业的环境中使用和分享作品。</p> <p>相同方式共享(ShareAlike):如果用户对作品进行了改编或衍生创作,必须在相同的许可证下分享这些新作品。这意味着新作品也必须遵循相同的使用条款。</p> <p>无附加限制(No additional restrictions):用户不得施加法律条款或技术措施,限制他人使用该许可证所允许的权利。</p> <h2>3. 硬件设计</h2> <p><img src="//image.lceda.cn/oshwhub/306a47e97fe443469d2da3badf6f335e.png" alt="容器 1.png"></p> <h3>3.1 VFD屏幕驱动</h3> <p>由于屏幕是集成驱动的,所以在设计电路的时候只需要关心:满足灯丝需求、满足SPI通讯的电平要求即可。 屏幕高压输入41V使用LGS6302B5这款升压芯片实现 灯丝实测使用直流供电效果几乎看不出,采用LDO ME6211C33M5G-N 3.3V供电降压</p> <p><img src="//image.lceda.cn/oshwhub/0df1a351f8b84764b0ef72abb3b15a44.png" alt="image.png"></p> <h3>3.2 集成外设</h3> <p>使用了集成ESP32-C3 模组为主控,构建自动下载电路方便调试。 整体中,从Type-C接口进行供电,当连接电脑的时候D+和D-数据线首先接入SL2.1A一款USB扩展IC,从其中扩展出4路HUB接口,其中一路固定连接到CH340C,剩下的3路其中一路给到TF读卡器IC使用,剩下的两路分别是扩展USB-A和Type-C接口。</p> <p><img src="//image.lceda.cn/oshwhub/e3ee9bc3aafe45f39b0cfe50c80a72f7.png" alt="image.png"></p> <p><strong>实时时钟</strong> 实时时钟采用高精度IC:RX8025T-UB,这款IC采用的i2c通讯,后备电池使用可充电电池设计,即上电后则开始充电,掉电后开始放电保持时钟不断走时。 使用两颗二极管构建简易供电选择器</p> <p><img src="//image.lceda.cn/oshwhub/c7588c9363774feeb01f6b22ed07effd.png" alt="image.png"></p> <h2>4.软件开发</h2> <p>软件部分分为两个部分</p> <ol> <li>ESP32 PlatformIO</li> <li>PyQt6 上位机</li> </ol> <h3>目录结构</h3> <p><img src="//image.lceda.cn/oshwhub/0770aeaeeb2d4e73983424b7b3f66ce2.png" alt="image.png"></p> <h3>4.1 ESP32 PlatfromIO</h3> <p><img src="//image.lceda.cn/oshwhub/64cbb66cad194b53bbd6d68a2432bb9e.png" alt="主流程.png"></p> <p><img src="//image.lceda.cn/oshwhub/d3dce4df47154f0295baef8a74e7bfd6.png" alt="消息处理流程.png"></p> <p><strong>部分核心代码:</strong></p> <pre><code class="language-c++">#ifndef __CONTROLLER_H #define __CONTROLLER_H #include "command.h" #define DEFAULT_SEPARATOR ";" typedef enum { CT_VFD_VAL_BRIGHTNESS = 0x00, // VFD亮度调整 CT_VFD_AC_EN = 0x01, // VFD供电使能 CT_VFD_AC_CLEAR = 0x02, // VFD内容清空 CT_VFD_VAL_INPUT_0 = 0x03, // VFD输入0行 CT_VFD_VAL_INPUT_1 = 0x04, // VFD输入1行 CT_DATGETIME_VAL_SET = 0x10, // 日期时间设置 CT_DISPLAY_VAL_TYPE = 0x11, // 显示内容 } control_type; typedef enum { CDIS_DATETIME = 0, // 显示日期时间,温湿度 CDIS_CUSTOM = 1, // 显示自定义内容 } control_display; typedef void (*ControllerReceiveAction)(control_type, cmd_action_t*); typedef void (*ControllerReceiveValue)(control_type, cmd_value_t*); class Controller { public: bool checkHeart() { return util.checkHeartIsSurvive(); } void init(ControllerReceiveValue valueCb, ControllerReceiveAction actionCb) { receiveValue = valueCb; receiveAction = actionCb; // 默认显示时间 current_display_type = CDIS_DATETIME; } void decoder(const char* buf) { util.decode(buf); if (util.getCmdValue() != NULL) { cmd_value_t* val = util.getCmdValue(); int number = (int)strtol(val->key, NULL, 16); // 16进制字符串转换为整数 if (number == CT_VFD_VAL_BRIGHTNESS || number == CT_VFD_VAL_INPUT_0 || number == CT_VFD_VAL_INPUT_1 || number == CT_DATGETIME_VAL_SET || number == CT_DISPLAY_VAL_TYPE) { receiveValue((control_type)number, val); } } else if (util.getCmdAction() != NULL) { cmd_action_t* ac = util.getCmdAction(); int number = (int)strtol(ac->key, NULL, 16); // 16进制字符串转换为整数 if (number == CT_VFD_AC_EN || number == CT_VFD_AC_CLEAR) { receiveAction((control_type)number, ac); } } } /** * 返回当前的显示内容类型 */ control_display getCurrentDispType() { return current_display_type; } void setCurrentDispType(control_display t) { current_display_type = t; } private: control_display current_display_type; CommandUtil util; ControllerReceiveValue receiveValue; ControllerReceiveAction receiveAction; }; #endif</code></pre> <h3>4.2 Python PyQt6 上位机</h3> <p><img src="//image.lceda.cn/oshwhub/273f967b899e454f9f71f1393f400fed.png" alt="image.png"></p> <p><img src="//image.lceda.cn/oshwhub/b53d662a72e5463fb66fb53a180a33a8.png" alt="image.png"></p> <p><strong>部分核心代码</strong></p> <pre><code class="language-python">def task_heart(): """ 定时发送心跳数据 :return: """ while True: time.sleep(4) send_message(f"CMD:HEART") def search_serial_list(): global serial_port_lists serial_port_lists = serial.tools.list_ports.comports() for port in serial_port_lists: print(f"端口: {port.device}, 描述: {port.description}") def connect_serial(port_item: ListPortInfo): global serial_connect_state, serial_connect if serial_connect_state: return try: serial_connect = serial.Serial(port=port_item.name, baudrate=115200, bytesize=8, timeout=2, stopbits=serial.STOPBITS_ONE) except serial.SerialException as e: serial_connect = None print("串口被占用,打开失败") show_dialog_message("错误", "串口被占用,打开失败", QMessageBox.Icon.Critical) return if serial_connect.is_open: print(f"成功连接到 {serial_connect.name}") serial_connect_state = True else: serial_connect_state = False print("连接失败") def disconnect_serial(): global serial_connect, serial_connect_state if serial_connect_state and serial_connect is not None: serial_connect_state = False serial_connect.close() serial_connect = None print("串口关闭成功") def send_message(msg): """ 串口发送字符串数据 :param msg: 字符串数据 :return: """ if serial_connect_state: with lock: serial_connect.write(f"{msg}\n".encode()) def vfd_clear(): """ 清空VFD的内容显示 :return: """ send_message(f"CMD:ACTION:0x02:1") def receive_message(): if serial_connect_state and serial_connect.in_waiting > 0: received_data = serial_connect.readline() if received_data: print(f"接收: {received_data.decode('utf-8')}") </code></pre> <h2>5. 大赛LOGO验证</h2> <p><img src="//image.lceda.cn/oshwhub/1a014317a8e84890aea21fbe167dfa87.jpg" alt="IMG_0075.jpg"></p> <h2>6. 组装</h2> <p><img src="//image.lceda.cn/oshwhub/c52790224f6f445aaaf0638e0f6efc36.jpg" alt="IMG_0077.jpg"></p> <p><img src="//image.lceda.cn/oshwhub/abf9f45891cb4e65b52f8af5ec50f891.jpg" alt="IMG_0078.jpg"></p> <p><img src="//image.lceda.cn/oshwhub/924454e7d3ac4485a3662ff060e9cf90.jpg" alt="IMG_0079.jpg"></p> <p><img src="//image.lceda.cn/oshwhub/0c10b9e7cf3b4c449f4a99694528f309.jpg" alt="IMG_0082.jpg"></p> <h2>7. 视频演示</h2> <p><a href="https://www.bilibili.com/video/BV152xceQEYi/" target="_blank">https://www.bilibili.com/video/BV152xceQEYi/</a></p> <h2>8. 源码</h2> <p><a href="https://github.com/ccy-studio/CCY-VFD-162SD17INK1D28" target="_blank">https://github.com/ccy-studio/CCY-VFD-162SD17INK1D28</a></p> <h2>9. BOOM</h2> <p>具体使用元器件以及数量可在下发BOOM表格内直接购买。 屏幕需要特定采购,请加群联系我咨询购买。 数量不多先到先来</p>

文档

BOM

暂无

附件

附件名 下载
202409272232_x264.mp4
3D打印外壳.7z

成员

评论(3)

  • 表情
    emoji
    小嘉工作篇
    小嘉日常篇
  • 图片
成功
工程所有者当前已关闭评论
立创电赛 回复
<p>还需要上传演示视频哦</p>
Saisaiwa 回复
<p>B站+本页视屏都有了呢</p>
mfdfhkjhkh 回复
<p>有创意的,有没有其他屏幕的方案</p>
goToTop
svg-battery svg-battery-wifi svg-books svg-more svg-paste svg-pencil svg-plant svg-ruler svg-share svg-user svg-logo-cn svg-double-arrow