当前位置: 首页 > news >正文

移远EC20二次开发实战:AT指令与Socket双模式图像传输解析

1. 移远EC20模块与图像传输开发概述

第一次拿到移远EC20开发板时,我盯着这个巴掌大的模块看了半天——它真的能稳定传输图像?作为一款全网通4G LTE Cat.4模块,EC20在工业物联网领域早已名声在外,但实际用AT指令和Socket传图时,还是踩了不少坑。比如用AT传JPEG图片时遇到二进制截断,Socket模式下拨号失败等问题。本文将分享两种传输模式的完整开发流程,包含环境搭建、代码修改、编译运行等关键细节。

EC20模块支持两种工作模式:标准AT指令模式和OpenCPU二次开发模式。我们重点讨论前者,因为90%的嵌入式场景只需要通过串口发送AT指令就能满足需求。实测在Linux环境下,通过虚拟串口/dev/smd8发送AT指令,配合UDP协议传输640x480的JPEG图像,平均耗时约3秒(取决于网络信号)。而直接使用Socket传输相同图片仅需1.5秒,但需要额外处理PPP拨号等底层连接。

2. AT指令模式图像传输实战

2.1 开发环境搭建

在Ubuntu 20.04上配置环境时,需要特别注意移远SDK对环境变量的依赖。每次打开新终端都要执行:

export PATH=$PATH:/opt/ql-sdk/arm-oe-linux-gnueabi/bin source /opt/ql-sdk/environment-setup

我建议把这两行加入~/.bashrc,避免重复操作。SDK安装包解压后包含交叉编译工具链、库文件和示例代码。关键目录结构如下:

ql-ol-sdk/ ├── arm-oe-linux-gnueabi # 工具链 ├── examples # AT与Socket示例 └── ql-ol-extsdk # 扩展功能库

2.2 AT指令核心代码解析

原始示例中的example_at.c需要三个关键修改点:

  1. 虚拟串口配置:EC20通过/dev/smd8提供AT通道,必须以非阻塞模式打开:
smd_fd = open(QUEC_AT_PORT, O_RDWR | O_NONBLOCK | O_NOCTTY);
  1. 二进制数据传输:AT+QISEND指令需要特殊处理二进制数据。我封装了改进版的发送函数:
int Ql_SendAT(char* atCmd, char* finalRsp, long timeout_ms, int should_Add) { // 添加二进制模式处理逻辑 if(should_Add != 0) { write(smd_fd, atCmd, should_Add); // 直接发送二进制数据 } else { // 常规AT指令处理 } }
  1. 分块传输机制:单次传输限制1024字节,需要循环读取文件并分块发送:
while((read_len = read(from_file, buf, MAXLINE)) > 0) { sprintf(str,"%d",read_len); sprintf(receive_buf, "AT+QISEND=2,%s,\"148.70.42.237\",3333", str); Ql_SendAT(receive_buf, "OK", 1000, 0); Ql_SendAT(buf, "SEND OK", 5000, read_len); // 关键:最后参数传数据长度 }

2.3 常见问题解决方案

  • 乱码问题:如果传输的图片出现错位,检查串口属性是否关闭了流控:
struct termios options; tcgetattr(smd_fd, &options); options.c_iflag &= ~(IXON | IXOFF | IXANY); // 关闭软件流控 tcsetattr(smd_fd, TCSANOW, &options);
  • 传输中断:遇到"SEND FAIL"错误时,在每次QISEND前添加延迟:
usleep(100000); // 100ms间隔

完整编译命令如下:

arm-oe-linux-gnueabi-gcc example_at.c -o example_at -I./include -L./lib -lql_oe

3. Socket模式高效传输方案

3.1 网络连接建立

Socket模式需要先完成PPP拨号。移远提供了ql_wwan_v2.h头文件简化操作:

ql_data_call_s data_call = { .profile_idx = 1, .ip_family = QL_DATA_CALL_TYPE_IPV4, .reconnect = true }; QL_Data_Call_Start(&data_call, &err); // 启动数据连接

实测发现必须等待data_call_state_callback返回CONNECTED状态后才能继续操作,否则sendto会失败。建议添加超时检测:

time_t start = time(NULL); while(data_call.state != QL_DATA_CALL_CONNECTED) { if(time(NULL) - start > 30) { printf("Connect timeout!\n"); exit(1); } sleep(1); }

3.2 Socket传输优化技巧

直接使用UDP协议传输时,我推荐以下优化措施:

  1. 双缓冲机制:预读取下一块数据到备用缓冲区,减少I/O等待时间
char buf1[MAXLINE], buf2[MAXLINE]; int fill_buf = 0; while(1) { char *cur_buf = fill_buf ? buf1 : buf2; int len = read(from_file, cur_buf, MAXLINE); if(len <= 0) break; // 启动异步读取下一块 if(!fill_buf) pthread_create(&thread, NULL, async_read, buf2); sendto(sockfd, cur_buf, len, 0, (struct sockaddr*)&cliaddr, sizeof(cliaddr)); fill_buf ^= 1; // 切换缓冲区 }
  1. 动态分块:根据信号强度调整每包大小
int dynamic_size = get_signal_strength() > 20 ? 2048 : 512;

完整Socket示例编译时需要链接移远库:

arm-oe-linux-gnueabi-gcc example_socket.c -o example_socket -I./include -L./lib -lql_wwan_v2

4. 两种模式对比与选型建议

通过实测对比(相同网络环境下传输10次取平均值),得到如下数据:

指标AT指令模式Socket模式
传输耗时(1MB图片)8.2s ±1.3s3.7s ±0.8s
CPU占用率45%-60%15%-25%
内存消耗~35MB~12MB
代码复杂度高(需处理AT响应)低(标准Socket)

选型建议

  • 对实时性要求不高且主控资源有限时,选择AT指令模式
  • 需要高频传输或低延迟的场景,务必使用Socket模式
  • 混合方案:用AT指令查询网络状态,稳定后切换Socket传输

在最近的一个智慧农业项目中,我们最终采用混合方案——设备唤醒时通过AT+COPS?检查网络状态,确认信号强度大于15dbm后自动切换到Socket模式传输作物图像,传输效率提升了40%。

http://www.jsqmd.com/news/556756/

相关文章:

  • 一文掌握Simulink模型加密:从S-Function到受保护模型的实战选择
  • MiroFish终极部署指南:3种简单方法快速搭建群体智能预测引擎
  • WSL2下用QEMU模拟ARM开发板:从uboot到Linux内核的完整启动流程
  • 保姆级教程:在Linux上从源码编译安装IGH EtherCAT主站(含常见编译错误解决)
  • Science Robotics突破 | 20m/s高速避障+2.5mm电线识别的微型无人机技术解析
  • 3步构建个人数字分身:WeClone智能微信机器人全栈实现指南
  • STM32L452 I2C时钟延展功能关闭实战:从异常波形到稳定通信
  • 3种网络环境下Cameradar性能瓶颈与动态优化指南
  • AI-AGENT概念解析 - LLM训练
  • 大模型风口已至!月薪30K+的AI岗正在批量诞生,普通人如何抓住这个风口?
  • 别再只调BERT了!用百度ERNIE 3.0做中文情感分析,实测效果和避坑指南
  • Nginx auth_basic认证实战:半小时搞定敏感数据外网访问控制
  • 别再只用Type-C充电了!手把手教你用16Pin接口给单片机烧录程序(CH340N实战)
  • Docker部署Jaeger链路追踪平台:从入门到生产环境实战
  • 智谱AI GLM-Image企业应用案例:营销团队AI视觉素材日产能提升300%
  • TeslaMate数据管家:从数据黑洞到驾驶洞察的技术突围
  • 别再手动拖预制体了!用Cursor+Unity MCP插件,让AI帮你自动修改游戏资源(保姆级避坑指南)
  • SMUDebugTool:解决AMD Ryzen系统硬件调试难题的专业级工具
  • 如何高效使用gmft:PDF表格提取的完整功能解析与实战指南
  • 突破限制:非苹果硬件运行macOS的开源方案——Unlocker工具全解析
  • S32K144 LPUART中断接收丢字节?手把手教你用模拟空闲中断搞定Modbus RTU
  • Intel RealSense帧管理与元数据架构深度解析:构建高可靠机器视觉系统的核心技术
  • 飞书学AI Agent!3-4个月速成!打破信息差,免费资源包等你拿!
  • 如何在ComfyUI中实现专业级AI视频生成:ComfyUI-WanVideoWrapper完整配置指南
  • 高效管理无线网卡:基于.NET的Windows WPF工具开发实战
  • 用DS1302给51单片机做个电子钟,蓝桥杯选手的实战避坑指南(附完整代码)
  • Cesium实战:基于Entity API封装动态告警闪烁标记
  • AtlasOS系统Xbox控制器驱动问题解决手册
  • DICOM RT Structure深度解析——从文件结构到靶区可视化
  • 别再折腾无障碍服务了!用Android蓝牙HID实现投屏反控的保姆级避坑指南