如何为Flutter应用实现蓝牙文件网关?ESP32传JSON方案咨询
问题:ESP32蓝牙传输SD卡JSON文件到Flutter应用的方案选型
我需要把连接SD卡的ESP32中存储的JSON文件发送到Flutter开发的应用里。文件最大约500KB,不适合蓝牙直接传输,所以拆成128字节的数据包。我知道蓝牙不是最快的传输方式,哪怕耗时10分钟也能接受。
传输原理
蓝牙客户端可以给ESP32发指令,比如downloadfile:/name_of_the_file.json,流程如下:
- ESP32返回文件名、文件大小和数据包总数
- 客户端返回确认(Acknowledgement)
- 开始传输:先发送包含数据包编号和数据包大小的头部,再发数据包;ESP32等待客户端对该数据包的确认(含编号和大小)
- 文件接收完成后,客户端发确认,ESP32确认传输完成
疑问
- 不确定当前方案是不是向Flutter应用传输数据的最佳方案,希望保留蓝牙,考虑BLE是否更适配Flutter;
- 作为Flutter新手,不确定串口蓝牙是不是最简单的开发方案。
目前已经通过「Serial Bluetooth Terminal」应用完成ESP32的大部分测试,指令download:/gps_data_1.json的测试结果已验证。
下载函数
void downloadFile(String filename) { if (!fileRead(filename)) { // 检查文件是否可读 SerialBT.println("ERROR_NO_FILE"); // 文件不存在则发送错误信息 return; } getFileDetails(filename); // 获取文件详情并通过蓝牙发送 // 等待手机端响应:"ACK" waitForACK(); // 直到收到"ACK"才继续 SerialBT.println("START_TRANSFER"); // 通知开始文件传输 SerialBT.println(); // 空行用于格式化 Serial.println("START_TRANSFER"); // 打印到串口监视器 // 将文件拆分成数据包逐个发送 size_t packetNumber = 0; // 初始化数据包编号 uint8_t buffer[CHUNK_SIZE]; // 存储数据块的缓冲区 size_t totalPackets = numberPacket(filename); // 获取总数据包数 while (file.available()) { // 循环直到文件结束 // 从文件读取一块数据 size_t bytesRead = file.read(buffer, CHUNK_SIZE); // 发送数据包编号和大小 // 数据包发送校验帧格式:SEND;PN:*当前数据包编号*/*总数据包数*;PS:*数据包大小* SerialBT.print("SEND;"); SerialBT.print("PN:"); SerialBT.print(++packetNumber); SerialBT.print("/"); SerialBT.print(totalPackets); SerialBT.print(";"); SerialBT.print("PS:"); SerialBT.println(bytesRead); // 发送数据包 SerialBT.println(); // 空行用于格式化 SerialBT.write(buffer, bytesRead); // 发送数据 SerialBT.println(); // 空行用于格式化 // 等待客户端对该数据包的确认 // 数据包接收校验帧格式:ACK;PNR:*当前数据包编号*/*总数据包数*;PSR:*数据包大小* waitForPacketACK(packetNumber, totalPackets, bytesRead); } SerialBT.println("TRANSFER_COMPLETE"); // 通知传输完成 SerialBT.println(); // 空行用于格式化 Serial.println("TRANSFER_COMPLETE"); // 打印到串口监视器 file.close(); // 关闭文件 }
数据包拆分函数
size_t numberPacket(String filename) { if (!fileRead(filename)) { // 添加调用fileRead()的条件 return 0; // 文件未找到则返回0 } // 获取文件大小 size_t fileSize = file.size(); // 计算数据包数量 size_t numChunks = fileSize / CHUNK_SIZE; if (fileSize % CHUNK_SIZE != 0) { numChunks++; // 剩余字节额外添加一个数据包 } return numChunks; }
内容的提问来源于stack exchange,提问作者Gamma
相关产品推荐
相关产品推荐

