当前位置: 代码迷 >> 综合 >> 【Luat-esp32c3】4.3 文件系统——加载jpeg图片并拆包
  详细解决方案

【Luat-esp32c3】4.3 文件系统——加载jpeg图片并拆包

热度:78   发布时间:2023-12-05 20:24:19.0

文章目录

  • 1 前言
  • 2 硬件
  • 3 串口屏配置
  • 4 测试数据包
  • 5 代码
    • 5.1 拆分jpeg
    • 5.2 串口
  • 6 结果

1 前言

由于串口屏显示图片需要将jpeg文件进行拆包,每个包240字节,尝试结合esp32的sdmmc加载并拆包。

2 硬件

esp32c3+串口屏

在这里插入图片描述
红字标的是串口屏的tx和rx

在这里插入图片描述

3 串口屏配置

选择图标页面平移显示,尺寸设为64、64。(注意和传入的图片尺寸一致),地址设为7FFE
在这里插入图片描述

4 测试数据包

数据帧
5AA5F3828000FFD8FFE000104A46494600010101009000900000FFE100224578696600004D4D002A00000008000101120003000000010001000000000000FFDB0043000201010201010202020202020202030503030303030604040305070607070706070708090B0908080A0807070A0D0A0A0B0C0C0C0C07090E0F0D0C0E0B0C0C0CFFDB004301020202030303060303060C0807080C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0CFFC00011080040004003012200021101031101FFC4001F00000105010101010101000000000000000001020304055AA5F3828078060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B511000201020404030407050404005AA5F38280f0010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00FDFCA28A2800A28A2800A28A2800A28A2800AFC72FF83AD7F66DF16DD7C0DB5F8A579F17BC69FF0008859EBFE1FD174DF87965B6D343599EE646B8BCBC5AA5F3828168DA49BC918AC3E56F0BE4946C16DF81FB1B5F34FF00C156FF00E09DFF00F0F3BFD96A1F86BFF0987FC20FE4F882C35DFED1FECAFED2CFD95D9BCAF2BCE87EF671BB7F1E86A63755A8D45F66A425E894D733F3F76FE7DB5B1574E9D483FB5092F9B8BB7FE4D6FD74B9F48587FC78C3FF005CD7F954D4DB78BC88123CE76285CFAE29D572DCC69C5A824FB05145148D028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A00FFFD90000显示命令
5AA507827FFE5AA58000

先用串口工具传输,注意串口波特率115200
在这里插入图片描述

5 代码

5.1 拆分jpeg

table_jpg = {
    }
table_jpg_num = 0       -- 记录多少个包
function open_jpg(path)-- if io.exists(path) == false then-- log.info("sdio","error path")-- return -1-- endprint(path)f_jpg = io.open(path,"rb")local jpg_size = io.fileSize(path)local jpg_pkg_num = math.ceil(jpg_size/240) --向上取整table_jpg_num = jpg_pkg_numlog.info("sdio", "fileSize", jpg_size,jpg_pkg_num)jpg_add_num = 0x8000for i = 1, jpg_pkg_num, 1 do-- 从文件中获取数据,240个字节为一组包(迪文定义)local temp_jpg_value_hex = f_jpg:read(240)-- pack.pack( b, temp_jpg_value)-- 报头jpg_head_char = "5AA5F382"-- 地址jpg_add_char = string.format("%x",jpg_add_num)jpg_add_hex = string.fromHex(jpg_add_char)print(jpg_add_char)jpg_add_num = jpg_add_num+0x78-- 数据包-- 最后一个报附加0000if i == jpg_pkg_num thenprint("end pakage")temp_jpg_value_hex = string.fromHex(string.toHex(temp_jpg_value_hex).."0000")endtemp_jpg_value_char = string.toHex(temp_jpg_value_hex)-- print(temp_jpg_value_char)-- 拼接报头,地址,数据包,并转为16进制用于发送uart2dwin_char = jpg_head_char..jpg_add_char..temp_jpg_value_charuart2dwin_hex = string.fromHex(uart2dwin_char)print(uart2dwin_char)-- 存储当前的几个包table_jpg[i]=uart2dwin_hexendf_jpg:close()
end

这样可以将jpeg数据拆分为一包240数据,然后加上报头以及最后附加0000

5.2 串口

tag_uart = "t5_uart"uart_id = 1
uart_speed = 115200
len = 1024function init_uart()-- uart.on(1, "recv", function(uart_id, len)-- local data = uart.read(1, 1024)-- log.info("uart2", data)-- -- libgnss.parse(data)-- end)log.info(tag_uart,"test5_init_uart")uart.setup(uart_id, uart_speed)-- 接收数据uart.on(uart_id, "receive",uart_receive)-- uart.on(uart_id, "sent",uart_send)-- 定时发送数??-- timex = sys.timerLoopStart(uart_send,3000)-- log.info(tag_uart,"time:",timex)
endfunction uart_send()log.info("uart_send")-- if temp_send_hex ~= nil then-- log.info("uart_send",temp_send_hex)uart.write(uart_id, 'a')-- endendfunction uart_receive()log.info("uart_receive")local s = ""s = uart.read(uart_id, len)if #s > 0 then -- #s 是取字符串的长度-- 如果传输二进??/十六进制数据, 部分字符不可??, 不代表没收到-- 关于收发hex??,请查?? https://doc.openluat.com/article/583-- log.info("uart", "receive", uart_id, #s, s)-- log.info("uart", "receive", uart_id, #s, string.toHex(s))dwin_uart2 = string.toHex(s)print(dwin_uart2,type(dwin_uart2))if dwin_uart2 == "5AA503824F4B" thenflag_ok = trueend-- 判断传来的地址judge_dwin_tx(dwin_uart2)end
endfunction judge_dwin_tx(str)-- 0x1502是发送书名if string.find(str,'831502') ~= nil thensys.publish("SEND_BOOKNAME", false)end-- 0x122F是书名if string.find(str,'83122F') ~= nil thensys.publish("SAVE_BOOKNAME", str)end-- 0x1300是发送按钮,暂时用于显示jpgif string.find(str,'831300') ~= nil thensys.publish("DISPLAY_JPG", str)endendfunction send_bookname(state)log.info("SEND_BOOKNAME", state)flag_search = true
end
sys.subscribe("SEND_BOOKNAME", send_bookname)function save_bookname(str)log.info("SAVE_BOOKNAME", str)-- local v_start = string.find(str,'83122F')-- local value = string.sub(str,v_start+7)local dwin_adr_input_ta='83122F'dwin_uart2_adr = string.find(str,dwin_adr_input_ta)dwin_uart2_start = dwin_uart2_adr + #dwin_adr_input_ta + 4   -- 03 5A(标识??)dwin_uart2_len = string.sub(str, dwin_uart2_start, dwin_uart2_start+1)dwin_uart2_end = string.find(str,'FFFF')local dwin_uart2_gbk_char = nildwin_uart2_gbk_char = string.sub(str, dwin_uart2_start+2, dwin_uart2_end-1)dwin_uart2_gbk_hex = string.fromHex(dwin_uart2_gbk_char)print("dwin_uart2_gbk_hex",dwin_uart2_gbk_hex,#dwin_uart2_gbk_hex)temp_bookname = dwin_uart2_gbk_hex
end
sys.subscribe("SAVE_BOOKNAME", save_bookname)function recv_jpg_pkg(state)log.info("RECV_JPG_PKG", state)-- flag_search = true
end
sys.subscribe("RECV_JPG_PKG", recv_jpg_pkg)dwin_tx_jpg_display = "5AA507827FFE5AA58000"
function display_jpg(state)log.info("DISPLAY_JPG", state)-- send_table_jpg()flag_display_jpg = trueend
sys.subscribe("DISPLAY_JPG", display_jpg)function send_table_jpg()for i=1,table_jpg_num doflag_ok = falsewhile true doif flag_ok == false thenprint("send pkg:",i)uart.write(uart_id, table_jpg[i])-- print(table_jpg[i])print("send ok")sys.wait(200)elsebreakendendendprint("start display")flag_ok = falsewhile true doif flag_ok == false then-- 发送显示命令uart.write(uart_id, string.fromHex(dwin_tx_jpg_display))sys.wait(100)elsebreakendendprint("end display")
end

我在串口这里加了死循环,只有接收到ok才能停止传输,这样是为了确保串口屏收到了数据。后期可以在uart接收的时候加一个时间判定,如果超过一定时间就直接停止发送。

6 结果

在这里插入图片描述