Linux系统下串口AT指令控制EC20连接华为云物联网平台

一、前言

在当今万物互联的时代背景下,物联网技术的快速发展极大地推动了智能化社会的构建。作为其中的关键一环,设备与云端平台之间的通信变得尤为重要。本文介绍如何在Linux操作系统环境下,利用串口通信来实现EC20模块与华为云物联网平台的有效连接。使用Linux下的/dev/ttyUSB0设备文件通过AT指令来配置EC20模块,采用C语言和Python这两种编程语言实现这一过程。

EC20 是Quectel 生产的 4G LTE 模块。是一个多功能的通信模块,广泛应用于各种 IoT(物联网)设备中,提供了可靠的无线通信能力。EC20 支持 LTE FDD、LTE TDD、WCDMA 和 GSM 网络,能够实现高速的数据传输和稳定的语音通信。

EC20 模块支持全球主要的频段,使其能够在多个国家和地区的网络环境中正常工作。它能够提供最高达 150 Mbps 的下行速率和 50 Mbps 的上行速率,这使得它非常适合需要高带宽的应用场景,如视频流、远程监控和数据传输。

该模块具有强大的数据通信能力,包括支持 TCP/IP 和 UDP 协议的网络连接。EC20 还支持各种 AT 命令,通过这些命令用户可以控制模块的操作,配置网络设置,发送和接收数据。其内置的网络协议栈使得模块可以直接进行 MQTT、HTTP、FTP 等网络协议的通信,为开发者提供了极大的便利。

除了数据通信功能,EC20 模块还支持语音通话和短信功能。这使得它不仅可以用于数据传输,还可以作为语音通信解决方案。通过 AT 命令,用户可以方便地进行拨打和接听电话,发送和接收短信,满足不同应用场景的需求。

在电源管理方面,EC20 模块具有低功耗模式,能够有效地延长设备的电池寿命。它支持多种电源管理功能,包括睡眠模式和省电模式,使得它在不使用的时候能够降低功耗,减少能量消耗。

模块的物理接口包括多个 UART 串口、USB 接口和 GPIO 引脚,这些接口允许模块与其他硬件进行连接。通过这些接口,用户可以实现串口通信、USB 数据传输以及各种数字信号的输入输出,提供了高度的灵活性和可扩展性。

在设计和生产方面,EC20 模块遵循了工业标准,确保其在各种恶劣环境下的可靠性。它的设计小巧且坚固,适合嵌入到各种嵌入式系统和终端设备中。Quectel 提供了详细的技术文档和开发工具,帮助开发者快速集成和部署模块。

image-20240913101144215

二、实例代码

2.1 服务器信息

下面是我的华为云物联网服务器设备信息。

关于创建过程,可以看视频:https://www.bilibili.com/video/BV1mr421c75S

IP地址:117.78.5.125
端口号:1883
ClientId      64000697352830580e48df07_dev1_0_0_2023030206
Username      64000697352830580e48df07_dev1
Password      a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449
订阅主题:$oc/devices/64000697352830580e48df07_dev1/sys/messages/down
发布主题:$oc/devices/64000697352830580e48df07_dev1/sys/properties/report
发布的消息:{"services": [{"service_id": "stm32","properties":{"DHT11_T":18,"DHT11_H":80,"MQ2":1,"water":1,"flame":1,"light":0,"LED1":0,"LED2":0,"LED3":0}}]}

2.2 Python代码

本小节介绍 通过串口 /dev/ttyUSB0 发送 AT 指令以控制 EC20 模块连接华为云物联网平台,并完成 MQTT 通信,使用 Python 脚本实现。

AT 指令:

  • AT+RST: 重启模块
  • AT+CSIM=1: 设置工作模式为数据模式(请根据实际模块手册确认是否需要此指令)
  • AT+QMTOPEN=0,"IP地址",端口号: 连接到 MQTT 服务器
  • AT+QMTCONN=0,"ClientId","Username","Password": 使用提供的 ID、用户名和密码连接到 MQTT 服务器
  • AT+QMTSUB=0,0,"主题",1: 订阅指定主题
  • AT+QMTPUB=0,0,0,0,"主题",消息内容: 发布消息到指定主题

下面是实现代码,展示了如何用 Python 通过串口发送 AT 指令来配置 EC20 模块并连接到华为云物联网平台:

# -*- coding: utf-8 -*-

import serial
import time

# 串口配置
SERIAL_PORT = '/dev/ttyUSB0'
BAUDRATE = 115200
TIMEOUT = 1

# MQTT 服务器信息
MQTT_SERVER_IP = '117.78.5.125'
MQTT_SERVER_PORT = '1883'
MQTT_CLIENT_ID = '64000697352830580e48df07_dev1_0_0_2023030206'
MQTT_USERNAME = '64000697352830580e48df07_dev1'
MQTT_PASSWORD = 'a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449'

# 发布的消息
PUBLISH_MESSAGE = '{"services": [{"service_id": "stm32","properties":{"DHT11_T":18,"DHT11_H":80,"MQ2":1,"water":1,"flame":1,"light":0,"LED1":0,"LED2":0,"LED3":0}}]}'

# 发送 AT 指令并获取响应
def send_at_command(serial_conn, command, response_termination='OK', delay=1):
    print(f"Sending command: {command}")
    serial_conn.write((command + '\r\n').encode())
    time.sleep(delay)
    response = serial_conn.read(serial_conn.inWaiting()).decode()
    print(f"Response: {response}")
    if response_termination and response_termination not in response:
        raise Exception(f"Unexpected response: {response}")
    return response

def main():
    # 打开串口连接
    with serial.Serial(SERIAL_PORT, BAUDRATE, timeout=TIMEOUT) as ser:
        try:
            # 重启模块
            send_at_command(ser, 'AT+RST')

            # 设置工作模式为数据模式
            send_at_command(ser, 'AT+CSIM=1')

            # 连接到 MQTT 服务器
            send_at_command(ser, f'AT+QMTOPEN=0,"{MQTT_SERVER_IP}",{MQTT_SERVER_PORT}')
            send_at_command(ser, 'AT+QMTCONN=0,"{MQTT_CLIENT_ID}","{MQTT_USERNAME}","{MQTT_PASSWORD}"')
            time.sleep(5)  # 等待连接

            # 订阅主题
            send_at_command(ser, 'AT+QMTSUB=0,0,"$oc/devices/64000697352830580e48df07_dev1/sys/messages/down",1')

            # 发布消息
            send_at_command(ser, f'AT+QMTPUB=0,0,0,0,"$oc/devices/64000697352830580e48df07_dev1/sys/properties/report",{PUBLISH_MESSAGE}')

        except Exception as e:
            print(f"An error occurred: {e}")

if __name__ == "__main__":
    main()

运行命令:

root@flexusx-1a58:~# python3 mqtt_connect.py 

2.3 C语言代码

本小节介绍 用 C 语言实现通过串口发送 AT 指令来控制 EC20 模块并完成 MQTT 通信。

下面是实现代码,通过串口配置 EC20 模块并连接到 MQTT 服务器:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>

#define SERIAL_PORT "/dev/ttyUSB0"
#define BAUDRATE B115200

int setup_serial_port(const char *port) {
    int fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    struct termios options;
    tcgetattr(fd, &options);
    cfsetispeed(&options, BAUDRATE);
    cfsetospeed(&options, BAUDRATE);

    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    tcsetattr(fd, TCSANOW, &options);

    return fd;
}

void send_at_command(int fd, const char *command) {
    write(fd, command, strlen(command));
    write(fd, "\r\n", 2);
    usleep(100000);  // Wait for 100ms for the module to respond

    char response[256];
    int n = read(fd, response, sizeof(response) - 1);
    if (n > 0) {
        response[n] = '\0';
        printf("Response: %s\n", response);
    } else {
        printf("No response or read error.\n");
    }
}

int main() {
    int fd = setup_serial_port(SERIAL_PORT);

    // 1. Reset the module
    send_at_command(fd, "AT+RST");

    // 2. Connect to MQTT server
    char command[300];
    snprintf(command, sizeof(command), "AT+QMTOPEN=0,\"%s\",%d", "117.78.5.125", 1883);
    send_at_command(fd, command);

    snprintf(command, sizeof(command), "AT+QMTCONN=0,\"%s\",\"%s\",\"%s\"", 
             "64000697352830580e48df07_dev1_0_0_2023030206", 
             "64000697352830580e48df07_dev1", 
             "a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449");
    send_at_command(fd, command);

    usleep(5000000);  // Wait 5 seconds for connection to establish

    // 3. Subscribe to a topic
    send_at_command(fd, "AT+QMTSUB=0,0,\"$oc/devices/64000697352830580e48df07_dev1/sys/messages/down\",1");

    // 4. Publish a message
    sprintf(command,  "AT+QMTPUB=0,0,0,0,\"$oc/devices/64000697352830580e48df07_dev1/sys/properties/report\",\"{\\\"services\\\": [{\\\"service_id\\\": \\\"stm32\\\",\\\"properties\\\":{\\\"DHT11_T\\\":18,\\\"DHT11_H\\\":80,\\\"MQ2\\\":1,\\\"water\\\":1,\\\"flame\\\":1,\\\"light\\\":0,\\\"LED1\\\":0,\\\"LED2\\\":0,\\\"LED3\\\":0}}]}\"");
    send_at_command(fd, command);

    close(fd);
    return 0;
}

编译运行:

root@flexusx-1a58:~# gcc mqtt_connect.c 
root@flexusx-1a58:~# ./a.out 

2.4 创建虚拟串口方便测试

在与硬件通信之前,可以先建立一个虚拟串口测试一下。

创建一个虚拟的串口设备 /dev/ttyUSB0 主要有两种方式:使用 socat 工具创建虚拟串口对(虚拟串口设备),或者使用 tty0tty 驱动来创建虚拟串口对。

方法 1: 使用 socat 创建虚拟串口

socat 是一个强大的网络工具,可以创建虚拟串口设备。下面是如何使用 socat 创建两个虚拟串口对:

  1. 安装 socat: 在大多数 Linux 发行版上,可以使用包管理工具安装 socat。例如,在 Debian 或 Ubuntu 上运行:

    sudo apt-get install socat
    
  2. 创建虚拟串口对: 运行以下命令来创建两个虚拟串口设备 /dev/ttyV0/dev/ttyV1

    socat -d -d PTY,link=/dev/ttyV0,raw,echo=0 PTY,link=/dev/ttyV1,raw,echo=0
    

    这将创建两个虚拟串口设备 /dev/ttyV0/dev/ttyV1,它们会像物理串口一样工作,可以在程序中使用它们进行测试。

  3. 使用虚拟串口设备

    • 可以将一个设备用于发送数据,另一个设备用于接收数据进行测试。例如,可以将一个串口设备配置为连接到模拟的设备,另一个设备配置为模拟的串口设备的接收端。

方法 2: 使用 tty0tty 驱动

tty0tty 是一个内核模块,用于创建虚拟串口对。

以下是如何安装和使用 tty0tty

  1. 安装 tty0tty: 需要从源代码编译和安装 tty0tty。按照以下步骤进行:

    sudo apt-get install build-essential linux-headers-$(uname -r)
    git clone https://github.com/ntop/tty0tty.git
    cd tty0tty
    make
    sudo make install
    sudo depmod -a
    
  2. 加载内核模块: 运行以下命令加载 tty0tty 内核模块:

    sudo modprobe tty0tty
    

    这将创建虚拟串口设备 /dev/ttyt0/dev/ttyt1

  3. 使用虚拟串口设备

    • /dev/ttyt0/dev/ttyt1 现在可以作为虚拟串口设备使用。可以在程序中将它们作为串口设备来进行测试。

示例代码

假设已经创建了 /dev/ttyV0/dev/ttyV1(使用 socat),可以在 Python 中使用这些虚拟串口设备进行测试。例如:

import serial

# 打开虚拟串口
ser1 = serial.Serial('/dev/ttyV0', 115200, timeout=1)
ser2 = serial.Serial('/dev/ttyV1', 115200, timeout=1)

# 发送数据
ser1.write(b'Hello, world!\n')

# 读取数据
response = ser2.readline()
print('Received:', response.decode('utf-8'))

# 关闭串口
ser1.close()
ser2.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/902493.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Word中Normal.dotm样式模板文件

Normal.dotm文档 首先将自己电脑中C:\Users\自己电脑用户名\AppData\Roaming\Microsoft\Templates路径下的Normal.dotm文件做备份&#xff0c;在下载本文中的Normal.dotm文件&#xff0c;进行替换&#xff0c;重新打开word即可使用。 字体样式如下&#xff08;可自行修改&#…

基于opencv答题卡识别判卷

项目源码获取方式见文章末尾&#xff01; 回复暗号&#xff1a;13&#xff0c;免费获取600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 **《------往期经典推荐------》**项目名称 1.【基于DDPG算法的股票量化交易】 2.【卫星图像道路检测DeepLabV3Plus模型】 3…

蓝桥杯 单片机 DS1302和DS18B20

DS1302 时钟 时钟试题 常作为实验室考核内容 控制三个引脚 P17 时钟 P23输入 P13复位 其他已经配置好 寄存器原理 定位地址 0x80地址 固定格式 0x57 5*107*1 57 小时写入格式 不同 首位区分 A上午 P下午 0为24小时制 1为12小时制 写入8小时 0x87 //1000 7 十二小时制 7…

H5的Canvas绘图——使用fabricjs绘制一个可多选的随机9宫格

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;新的征程&#xff0c;最近一直被测试…

Django+Vue全栈开发旅游网项目首页

一、前端项目搭建 1、使用脚手架工具搭建项目 2、准备静态资源&#xff08;图片资源&#xff09; 将准备好的静态资源拖至public目录下 3、调整生产项目结构 公共的样式 公共js 首页拆解步骤 ①分析页面结构 标题、轮播图、本周推荐、精选景点、底部导航 ②新建页面组…

VAE中的“变分”什么

写在前面 VAE&#xff08;Variational Autoencoder&#xff09;&#xff0c;中文译为变分自编码器。其中AE&#xff08;Autoencoder&#xff09;很好理解。那“变分”指的是什么呢?—其实是“变分推断”。变分推断主要用在VAE的损失函数中&#xff0c;那变分推断是什么&#x…

第十二部分 Java Stream、File

第十二部分 Java Stream、File 12.1 Java Stream流 12.1.1体验Stream流 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合&#xff0c;存储多个字符串元素把集合中所有以"张"开头的元素存储到一个新的集合把"张"开头的集合中的长度为3的元素存…

OpenTelemetry 实际应用

介绍 OpenTelemetry“动手”指南适用于想要开始使用 OpenTelemetry 的人。 如果您是 OpenTelemetry 的新手&#xff0c;那么我建议您从OpenTelemetry 启动和运行帖子开始&#xff0c;我在其中详细介绍了 OpenTelemetry。 OpenTelemetry开始改变可观察性格局&#xff0c;它提供…

开挖 Domain - 前奏

WPF App 主机配置 Microsot.Extension.Hosting 一键启动&#xff08;配置文件、依赖注入&#xff0c;日志&#xff09; // App.xaml.cs 中定义 IHost private readonly IHost _host Host.CreateDefaultBuilder().ConfigureAppConfiguration(c > {_ c.SetBasePath(Envi…

JVM(HotSpot):GC之G1垃圾回收器

文章目录 一、简介二、工作原理三、Young Collection 跨代引用四、大对象问题 一、简介 1、适用场景 同时注重吞吐量&#xff08;Throughput&#xff09;和低延迟&#xff08;Low latency&#xff09;&#xff0c;默认的暂停目标是 200 ms超大堆内存&#xff0c;会将堆划分为…

CentOS 7 上安装 MySQL 8.0 教程

&#x1f31f; 你好 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

C#使用log4net结合sqlite数据库记录日志

0 前言 为什么要把日志存到数据库里&#xff1f; 因为结构化的数据库存储的日志信息&#xff0c;可以写专门的软件读取历史日志信息&#xff0c;通过各种条件筛选&#xff0c;可操作性极大增强&#xff0c;有这方面需求的开发人员可以考虑。 为什么选择SQLite&#xff1f; …

node和npm

背景&#xff08;js&#xff09; 1、为什么js能操作DOM和BOM? 原因&#xff1a;每个浏览器都内置了DOM、BOM这样的API函数 2、浏览器中的js运行环境&#xff1f; v8引擎&#xff1a;负责解析和执行js代码 内置API&#xff1a;由运行环境提供的特殊接口&#xff0c;只能在所…

Java面向对象编程高阶(一)

Java面向对象编程高阶&#xff08;一&#xff09; 一、关键字static1、static修饰属性2、静态变量与实例变量的对比3、static修饰方法4、什么时候将属性声明为静态的&#xff1f;5、什么时候将属性声明为静态的&#xff1f;6、代码演示 一、关键字static static用来修饰的结构…

从0到1学习node.js(npm)

文章目录 一、NPM的生产环境与开发环境二、全局安装三、npm安装指定版本的包四、删除包 五、用npm发布一个包六、修改和删除npm包1、修改2、删除 一、NPM的生产环境与开发环境 类型命令补充生产依赖npm i -S uniq-S 等效于 --save -S是默认选项npm i -save uniq包的信息保存在…

首席数据官和首席数据分析官

根据分析人士的预测&#xff0c;首席数据官&#xff08;CDO&#xff09;和首席数据分析官&#xff08;CDAO&#xff09;必须更有效地展示他们对企业和AI项目的价值&#xff0c;以保障其在高管层的地位。Gartner的最新报告指出&#xff0c;CDO和CDAO在AI时代需要重新塑造自身定位…

HDFS异常org.apache.hadoop.hdfs.protocol.NSQuotaExceededException

HDFS异常org.apache.hadoop.hdfs.protocol.NSQuotaExceededException 异常信息&#xff1a; Hive:org.apache.hadoop.hdfs.protocol.NSQuotaExceededException: The NameSpace quota (directories and files) of directory /xxxdir is exceeded: quota10000 file count15001N…

【Python】为Pandas加速(适合Pandas中级开发者)

非常好的一篇文章&#xff0c;解决问题的方式和思路层层递进&#xff0c;透彻深刻。 Pandas是个好工具&#xff0c;好工具要用正确高效的方式使用&#xff0c;才能发挥出万钧之力。 英文水平较高可直接阅读原文。Fast, Flexible, Easy and Intuitive: How to Speed Up Your p…

linux创建自定义服务部署项目

1.进入linux单元服务文件夹 cd /etc/systemd/system/ 2.创建一个文件以.service结尾的文件 C#(.Net Core)、 Java、Python等语言&#xff0c;都可以通过linux自定义服务来部署项目&#xff0c;实现守护进程、实现开机自启 2.1例如创建my.service文件 这里以部署python项目为…