BC35-G 是一款高性能、低功耗的多频段 NB-IoT 无线通信模块,支持 B1/B3/B8/B5/B20/B28 频段,在设计和AT指令上与BC95兼容。
小熊派开发板右上角的开关拨到AT-PC一端,则模组直接与PC相连,方便调试。
指令:AT
功能:测试AT指令功能是否正常
示例:
指令:AT+CSQ
功能:返回从 UE 接收到的信号强度指示 <rssi> 和信道误码率 <ber>,其中第一个值rssi应当在0-31之间,如果为99则表示信号无法检测,第二个参数ber因为模组当前不支持,所以始终为99。
示例:
指令:AT+CEREG?
功能:查询当前 EPS 网络注册状态,该指令返回的第一个参数为0则表示禁止网络注册URC,第二个参数表示网络注册状态,1表示已注册本地网,5表示已注册漫游网络,其余值则表示注册失败。
示例:
指令:AT+CGATT?
功能:该命令用于查询当前是否将 UE 附着于 PS 域,返回值为1则表示已附着,即网络激活成功。
示例:
指令:AT+CGPADDR
功能:该命令用于查询模组当前的ip地址。
示例:
由于NB-IoT模组可以直接对接IoT平台,所以在单独测试使用UDP连接时,需要 在激活网络成功之后,在获取ip地址之前,关闭IoT平台注册功能 。
使用如下命令禁止该功能:
首先我们需要搭建一个UDP服务器,有两种方式:
因为 NB-IoT 模组直接注册的是公网ip地址,所以这里我们使用第一种方式,在Linux服务器上运行一个Python编写的UDP测试服务器:
这里的Python程序如下:
运行:
效果如下:
使用AT命令连接UDP服务器,首先需要创建一个 UDP 类型的 Socket,创建socket的指令如下:
其中第一个参数是socket类型,DGRAM表示UDP,STREAM表示UDP;第二个参数表示协议类型,UDP 为 17, UDP 为 6,最后一个参数指定socket使用的本地端口,如果为0则表示随机分配。
所以创建UDP socket的示例如下:
指令:
其中第一个参数是由 AT+NSOCR 返回的 Socket 编号,第二个参数是UDP服务器ip地址,也可以使用域名,第三个参数是UDP服务器开启监听的端口,第四个是发送数据的长度,最后一个是要发送的十六进制数据。
示例:
发送之后,在服务器端也可以看到:
模组发送数据到服务器后,服务器会自动发送消息,模组会打印出收到信息的提示:
该信息表示编号为1的socket收到了18字节的数据。
可以使用如下命令查看收到的数据,第一个参数是socket编号,第二个参数是查询的数据长度:
查看刚刚收到的数据:
其中收到的数据为倒数第二个参数,是十六进制格式:
使用 在线工具 将数据转化为字符串即可:
通信完毕之后,可以使用下面的命令关闭最开始创建的socket:
示例:
UDP服务器,就是首发数据,进行数据处理的。与TCP不同的是不用建立连接,直接调用recvfrom来收包。\x0d\x0a开始就是基本的socket初始化地址什么的。\x0d\x0a要求多个线程处理客户端命令,那recvfrom收包后,考虑把客户端的地址信息保存,便于sendto,对接收的数据包,交给线程进行处理,每个线程可以向一块共享内存、队列里写入收到的数据和对应的客户端信息,每次写的时候对这块共享资源加锁,多个线程对共享资源读是加锁,读完解锁,并开始处理数据。\x0d\x0a处理完,用sendto发回去。\x0d\x0a不是什么大项目。小程序而已。UDP是面向无连接的,使用起来比较简单,打开socke之后,指定目标端口,直接进行接收和发送:
socket本身提供了一些接口:
需要注意的是, boost.asio.buffer 是一种接口适配器,通过接口进行发送和接收,必须有对应的数据缓冲区提供数据或者存储空间。
同步接收同步发送的UDP服务器也比较简单,创建一个绑定到本地端口的socket,然后就是接收及发送动作:
同步操作是不需要运行IO服务的,以最常规的方式来进行发送和接收,注意接收时如果接收到全部消息,即EOF也是通过报错形式,错误码为 error::message_size 。
实现异步的UDP服务器就略显复杂,需要保证IO服务运行,发起异步操作时要注意数据缓冲区生命周期:
可以看到 do_recv 方法发起了一个异步接收操作,在操作完成回调中再次发起,构造服务器时率先调用了 do_recv ,从而保证IO服务一直运行。
do_recv 方法在发起异步操作前申请了一块内存,接收的内容被保存在这块内存之中,当 do_send 发起异步发送操作时被借用,直到发送完成才将这段内存释放掉。
在构造函数中启动了一个线程来执行IO服务,并detach掉线程,从而保证服务器不阻塞,在析构函数停止了IO服务。
需要注意到的是 remote_ep_ 在执行 do_send 时被 move 了,由于 remote_ep_ 标识了远程端口,而且被声明为成员变量,在接受操作中会被填充远程端口内容,如果多个远程主机同时发起,单个 remote_ep_ 是无法正常处理的,所以一旦内容被填充后,就会转移出去给发送操作使用[个人理解,没有实际测试和验证]。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)