【2024 DigiKey创意大赛】esp32s3 klipper面板提交
<p>ccb04455e9616deb4aa0e2f3662cd4f6<br /><br />
一、作品简介</p>
<p> 米娜大家好啊,这一次eeworld的活动咱也是白嫖上了(雾),这次咱申请的是esp32s3 lcd ev board和一个stm32f401rct6的开发板,stm32f401rct6各位都很熟悉了就不再多说了,esp32s3 lcd这块板子倒是挺好的,这屏幕是真的大啊(舔嘴),这块屏幕尺寸正好可以当86盒子,太适合做点面板了,但是因为作者家里只能家居设备实在是太少了玩homeassitant感觉也没什么太大的意思,正好有台旧的kp3s打印机刚被作者刷了个klipper加个了klicky(押),那么干脆几挫个klipper面板得了(没钱klipper screen……?这块板子似乎比配一个klipper screen还贵????)</p>
<p>二、系统框图<br />
stm32f401被作者拿着测试板子啦(),所有干脆直说esp32这边<br />
一如既往我还是用的espidf开发,实在是用不惯platfromio+arduino这样感觉还是有点怪<br />
框架的话我是直接从局域网接入的打印机moonraker的接口,默认是7125应该是,然后因为作者之前写ws挺多的moonraker也支持ws接口直接写json收发数据,就干脆想写一下ws下json生成和处理的面向对象。页面的话还是一如既往的我做不好设计的lvgl(能用就行,挺难看的(嘘)</p>
<div style="text-align: center;"></div>
<p>三、各部分功能说明</p>
<p>Moonraker API & WebSocket 接口</p>
<p>大家都知道,Moonraker 是 Klipper 提供的远程 API 接口,适合通过局域网控制 3D 打印机。这次项目中我是直接通过 ESP32 连接 Moonraker 的 API 接口,默认端口是 7125,通过它可以使用 HTTP 和 WebSocket 来和打印机交流。 特别是 WebSocket,在 Moonraker 上能保持长连接,能通过 JSON 格式的消息实时收发打印机的状态。同样数据也有广播和请求接受两种大类。案例:</p>
<pre>
<code class="language-xml">
Run a gcode:¶
HTTP request:
POST /printer/gcode/script?script=G28
JSON-RPC request:
{
"jsonrpc": "2.0",
"method": "printer.gcode.script",
"params": {
"script": "G28"
},
"id": 7466}
Returns:
ok when the gcode has completed execution.</code></pre>
<p>ESP-IDF 与 WebSocket 客户端</p>
<p>作为老搭档,ESP-IDF 是开发 ESP32 的标配工具。虽然配置稍显繁琐,但也比前两年的好多了lol。这次项目常规使用esp32 WebSocket 客户端,连接到 Moonraker 获取打印机的实时数据。注意现在ws client的案例需要在The ESP Component Registry去添加Component</p>
<p>WebSocket 在 ESP-IDF 里是基于事件触发的,当连接建立、数据接收或出错时都会触发不同的事件,让开发起来简洁明了。比如,当有数据到来时,会进入 WEBSOCKET_EVENT_DATA 事件。每次收到 JSON 格式的数据,就利用 cJSON 进行解析,轻松提取出温度或位置信息,避免乱码问题,同时在日志里把数据打印出来方便调试。</p>
<p>案例伪程序如下</p>
<pre>
<code class="language-cpp">#include "esp_websocket_client.h"
#include "cJSON.h"
#define TAG "websocket"
#define URI "ws://example.com/socket" // WebSocket URI (replace with actual URI)
// WebSocket事件处理程序,处理连接、数据接收、错误等
static void websocket_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
if (event_id == WEBSOCKET_EVENT_CONNECTED) {
ESP_LOGI(TAG, "WebSocket connected");
} else if (event_id == WEBSOCKET_EVENT_DATA) {
ESP_LOGI(TAG, "Received data: %.*s", data->data_len, (char *)data->data_ptr);
// 尝试解析为 JSON
cJSON *json = cJSON_Parse(data->data_ptr);
if (json) {
// 打印 JSON 内容 (根据实际结构进一步解析)
ESP_LOGI(TAG, "Parsed JSON message");
cJSON_Delete(json); // 清理 JSON 对象
}
}
}
// 初始化 WebSocket 客户端并发送消息
static void websocket_app_start(void) {
esp_websocket_client_config_t ws_cfg = {
.uri = URI,
};
esp_websocket_client_handle_t client = esp_websocket_client_init(&ws_cfg);
esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, websocket_event_handler, NULL);
esp_websocket_client_start(client); // 启动 WebSocket 客户端
vTaskDelay(pdMS_TO_TICKS(1000)); // 1秒延迟
if (esp_websocket_client_is_connected(client)) {
esp_websocket_client_send_text(client, "hello", 5, portMAX_DELAY); // 发送文本消息
}
esp_websocket_client_close(client, portMAX_DELAY); // 关闭连接
esp_websocket_client_destroy(client); // 清理客户端
}
void app_main(void) {
websocket_app_start(); // 启动WebSocket应用
}</code></pre>
<p>讲到图形界面设计,LVGL 作为轻量化 UI 库,这次项目的界面部分我依然选择了它。咱是真的不擅长设计,所以直接用 GUI Guider 工具拖拖拽拽实现基础布局,配合 LVGL 的实时刷新功能将数据展示出来。UI 里主要是显示当前温度、位置信息、打印进度等。</p>
<p>每次解析完 JSON 数据后,只需调用 LVGL 的 lv_chart_set_value 这些方法就能更新显示,比如实时温度曲线、状态文字展示等,效果很不错!这块板子的屏幕不小,图表显示起来效果也很好,不用担心看不清。而且 GUI Guider 工具生成的代码可以直接加进 ESP-IDF 作为组件使用,非常方便,不用手动一行一行写界面代码(真的省心)。</p>
<p>虽然设计水平有限,但 LVGL 整体性能还是非常给力的。界面更新流畅,数据实时同步,体验效果棒棒的!</p>
<div style="text-align: center;"></div>
<div style="text-align: center;"> </div>
<p><br />
(中间过程截图,我真的不会做设计呜呜呜)<br />
代码的话需要添加cmakellist才可以当作espidf的Component类似这样</p>
<pre>
<code class="language-cpp">idf_component_register(SRC_DIRS "custom"
SRC_DIRS "generated"
SRC_DIRS "generated/guider_fonts"
SRC_DIRS "generated/guider_customer_fonts"
SRC_DIRS "generated/images"
INCLUDE_DIRS "custom"
INCLUDE_DIRS "generated"
INCLUDE_DIRS "generated/guider_fonts"
INCLUDE_DIRS "generated/guider_customer_fonts"
INCLUDE_DIRS "generated/images"
REQUIRES lvgl__lvgl)</code></pre>
<p> </p>
<div style="text-align: center;"></div>
<p>四、测试代码见附件<br />
<br />
五、演示视频</p>
<p>0e0da88cb42e431a7afa4ac152c94121<br />
</p>
<p>有演示视频没有呀~</p>
页:
[1]