Lua实现Grbl G代码发送:已确认行的字符串删除问题
解决Lua中Grbl G代码缓冲区的行删除问题
核心思路
由于Lua字符串是不可变的,直接修改字符串效率很低,因此我们需要通过维护「待确认行队列」+「对应长度队列」的方式,配合字符串切片来实现已确认行的删除。同时利用Grbl按顺序反馈ok的特性,采用先进先出(FIFO)的队列逻辑处理确认操作。
具体实现步骤
维护关键数据结构
pending_lines:存储已发送至Grbl但未收到ok的G代码行pending_lengths:对应pending_lines中每行的长度(包含结尾的换行符\n)pending_str:当前拼接好的待确认字符串(即你之前的Mystr)pending_total_len:pending_str的总长度,用于快速判断缓冲区剩余空间
收到
ok时的处理逻辑- 从长度队列头部弹出已确认行的长度
- 通过字符串切片直接裁剪掉已确认的行(Lua的
string.sub是高效操作) - 更新总长度,同时尝试将新的G代码行加入缓冲区
完整代码示例
-- 初始化:假设你已经读取好所有G代码行到gc_lines表格 local gc_lines = { "G0 X10 Y10", "G1 X20 Y20 F1000", ... } -- 你的G代码行 local line_lengths = {} local max_buffer = 250 -- Grbl缓冲区上限 -- 预计算每行的长度(包含换行符) for i, line in ipairs(gc_lines) do line_lengths[i] = #(line .. "\n") end -- 缓冲区管理变量 local pending_lines = {} local pending_lengths = {} local pending_str = "" local pending_total_len = 0 local current_line_idx = 1 -- 下一个待加入缓冲区的G代码行索引 -- 填充缓冲区并发送的函数 local function fill_and_send_buffer() -- 尽可能将G代码行加入缓冲区 while current_line_idx <= #gc_lines do local next_len = line_lengths[current_line_idx] if pending_total_len + next_len <= max_buffer then local next_line = gc_lines[current_line_idx] pending_str = pending_str .. next_line .. "\n" pending_total_len = pending_total_len + next_len table.insert(pending_lines, next_line) table.insert(pending_lengths, next_len) current_line_idx = current_line_idx + 1 else break -- 缓冲区已满,停止加入 end end -- 发送当前缓冲区内容(替换成你的串口发送函数) if pending_total_len > 0 then serial.write(pending_str) end end -- 收到Grbl返回"ok"的回调函数(需根据你的串口框架调整触发逻辑) function on_grbl_ok_received() if #pending_lengths == 0 then return end -- 移除已确认的行长度和内容 local removed_len = table.remove(pending_lengths, 1) table.remove(pending_lines, 1) -- 不需要跟踪行内容时可省略 -- 裁剪字符串并更新总长度 pending_str = string.sub(pending_str, removed_len + 1) pending_total_len = pending_total_len - removed_len -- 重新填充缓冲区并发送 fill_and_send_buffer() end -- 启动:首次填充并发送缓冲区 fill_and_send_buffer()
注意事项
- 确保长度计算准确:必须包含换行符,否则裁剪字符串时会出现偏移
- 处理超长行:如果单条G代码行长度超过250字符,需单独拆分(Grbl支持的最大单行长度为256字符)
- 串口回调时序:需保证
on_grbl_ok_received函数能准确捕获Grbl的ok反馈,避免重复处理或遗漏
内容的提问来源于stack exchange,提问作者Ashkan Khajeh
相关产品推荐
相关产品推荐

