侧边栏壁纸
  • 累计撰写 69 篇文章
  • 累计收到 2 条评论

用易语言写ESP8266串口上位机的几个高频问题解答

2026-10-22 / 0 评论 / 2 阅读

用易语言写ESP8266串口上位机的几个高频问题解答

最近在易语言开发者论坛刷到好几个同类型求助帖,都是拿易语言写个小上位机接ESP8266传的传感器数据,卡半天跑不通,把问得最多的几个问题整理下,都是我自己实际调过验证过的解法。

先把大家问得最集中的三个问题列出来:

  1. 接收到的ESP8266串口数据全是乱码,换了好几个波特率都没用
  2. 程序运行时第一次开串口正常,关掉重开就直接报错闪退
  3. 收到的数据总是碎成好几段,明明设备一次发了完整的温湿度JSON,程序要分两三次才能收全

关于接收乱码的问题

这个问题基本是两个原因,要么串口参数没匹配对,要么编码没转对,按下面的步骤走基本都能解决:

  • 先别着急写代码,拿现成的串口调试助手接你的ESP8266设备,记下来实际的波特率、数据位、停止位、校验位,绝大多数模块默认是9600波特率、8数据位、1停止位、无校验,但别上来就硬选,个别刷了第三方固件的模块参数可能不一样。
  • 在易语言串口组件的“数据到达”事件里,别直接调用读入文本()命令,默认读入文本是按GBK编码转的,而ESP8266的Arduino核心默认发的是UTF-8编码,十有八九会乱。正确的写法是先读字节集,再手动转编码,参考代码:
    .子程序 _串口1_数据到达
    .局部变量 recv_data, 字节集
    recv_data = 串口1.读字节集 ()
    .如果真 (取字节集长度 (recv_data) > 0)
        编辑框_日志.加入文本 (到文本 (编码转换.Utf8转Ansi (recv_data)))
    .如果真结束
  • 写之前记得先把编码转换相关的支持库勾上,不然写完运行会提示找不到命令。

关闭重开串口闪退的问题

这个问题基本是串口资源没完全释放就被重复调用导致的句柄冲突,按下面的逻辑写关闭流程就不会崩:

  • 不要点了关闭按钮就直接调用串口组件的关闭()方法,先主动清空接收和发送缓冲区,再执行关闭,关完加一个短延时给系统留时间释放串口句柄,参考代码:
    .子程序 _按钮_关闭串口_被单击
    串口1.清空缓冲区 ()
    串口1.关闭 ()
    程序_延时 (50)
    延时的时长不用卡太死,几十毫秒左右就行,看自己设备的响应速度,记得用不阻塞界面的延时命令,别用自带的会卡UI的延时()。
  • 写打开串口的逻辑前,先加个判断,如果串口当前已经是打开状态,先执行一遍上面的关闭流程再调用打开()方法,别硬开。

接收数据分段不完整的问题

说白了串口本身就是字节流传输,根本不存在“设备一次发完、电脑一次收完”的说法,不管你设备端是一次性print还是分批发,电脑端都是按缓冲区状态一点点推送数据的,想拿到完整的数据包不能靠等,得自己做缓存拼包:

  • 先定义一个全局的字节集变量当接收缓存,每次触发数据到达事件,先把新收到的字节拼到缓存后面;
  • 和设备端约定一个包结束标识,比如最常用的换行符(字节值10),每次拼完缓存就循环找里面有没有结束标识,有的话就把标识前面的内容拆出来当完整数据包处理,剩下的内容留在缓存里等下一批数据,参考代码:
    .全局变量 recv_buffer, 字节集
    ' 数据到达事件内追加缓存
    recv_buffer = recv_buffer + recv_data
    .局部变量 split_pos, 整数型
    .局部变量 full_pack, 字节集
    .判断循环首 (寻找字节集 (recv_buffer, {10}, ) ≠ -1)
        split_pos = 寻找字节集 (recv_buffer, {10}, )
        full_pack = 取字节集中间 (recv_buffer, 1, split_pos - 1)
        recv_buffer = 取字节集中间 (recv_buffer, split_pos + 1, 取字节集长度 (recv_buffer) - split_pos)
        ' 这里拿到的full_pack就是完整单包,可直接解析JSON
    .判断循环尾 ()
别靠“延时几百毫秒等数据收完”这种方法凑数,设备发数据的间隔受信号、传感器采样速度影响很大,延时短了还是碎包,延时长了界面会卡,用约定标志拼包是最稳的方案。

反正我当初第一次调通这玩意的时候,对着满屏乱码盯了快俩小时,最后才想起来忘了转UTF-8,你们调的时候要是卡壳了,先对着这几条挨个查就行。

评论一下?

OωO
取消