nrf51822单片机驱动ESP8266模块中遇到的问题总结

来源:互联网 发布:centos macaddr 编辑:程序博客网 时间:2024/05/22 15:39

作者:李大闯    2017/08/26 18:01

在实际工作中,原本是使用nrf51822作为核心mcu,但是由于大批量数据传输的需要,所以外挂了一个ESP8266的模块,用于批量数据传输。本篇文章总结了在使用nrf51822单片机驱动ESP8266模块时遇到的一些问题及解决方法,在此记录备忘。




2016.5.5
ESP8266模块工作于STA模式还是AP模式?
看一下AP模式和STA模式的定义和区别
AP模式: Access Point,提供无线接入服务,允许其它无线设备接入,提供数据访问,一般的无线路由/网桥工作在该模式下。AP和AP之间允许相互连接
Sta模式: Station, 类似于无线终端,sta本身并不接受无线的接入,它可以连接到AP, 一般无线网卡即工作在该模式。

根据以上的意思,应该让模块工作在AP模式,这样的话手机就可以连接到模块的wifi进而建立连接并传输数据。

手机和模块之间使用TCP连接还是UDP连接?
一下TCP连接和UDP连接的定义和区别
1.TCP基于连接,UDP基于无连接;
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式 ;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
考虑到数据传输准确性和可靠性的问题,使用TCP传输

ESP8266和手机建立TCP连接并通讯的过程(这里主要针对透传)
逐条发送以下指令:
AT+CWMODE=3         //设置ESP8266模块处于AP兼Station模式。这时可以用手机搜索到8266模块的wifi,连接上之后打开手机上安装的有人网络助手
                                    //创建TCP服务器。手机被分配的ip地址为192.168.4.2,选择端口号为8899
AT+CIPMUX=0            //使用单连接。透传模式下只能使用单连接。但是模块处于服务器模式时,必须使用多连接,所以说当模块设置为服务器时,不能使用透                                                                                                                                                
                                    //传。也即是说,如果要使用透传,则ESP8266必须扮演客户端的角色。
AT+CIPSTART="TCP","192.168.4.2",8899         //创建TCP连接,服务器的ip地址为192.168.4.2,端口号为8899
AT+CIPMODE=1         //设置启用透传模式
AT+CIPSEND               //进入透传。该指令后将进入透传模式,此后ESP8266将不能识别串口AT指令,所有串串口串接到的字符都将将透传到手机。

注:在发送这些指令时,一定要在串口调试软件里面选择“发送新行”,或者手动加一个回车。
另外,在实际的使用过程中发现,有些指令的设置结果在ESP8266模块掉电之后仍会保存(AT+CWMODE=3和AT+CIPMUX=0),所以只在51822上电时发这两条指令。而另外三条指令只在用到时才进行配置。

ESP8266的其它常用指令
AT                                            //测试指令,返回OK
AT+RST                                    //ESP8266模块复位
+++                                        //退出透传状态。注意该指令使用时后面不加回车。
AT+CIPCLOSE                        //关闭TCP连接

AT+CIPSTATUS                      //查询当前TCP连接状态。
//如果当前TCP处于连接状态,则返回                                  
   
AT+CIPSTATUS\r\r\nSTATUS:5\r\n+CIPSTATUS:0,"TCP","192.168.4.2",8899,11964,0\r\n\r\nOK\r\n

  //当未建立TCP连接时,则返回
  
AT+CIPSTATUS\r\r\nSTATUS:5\r\n\r\nOK\r\n

AT+CWLIF                                //列出当前接入该AP的设备的ip地址
//当没有手机连接时的回复:

AT+CWLIF\r\r\n\r\nOK\r\n
//当手机连上时的回复:

AT+CWLIF\r\r\n192.168.4.2,14:f6:5a:a1:47:32\r\n\r\nOK\r\n


实际使用过程中建立TCP连接指令AT+CIPSTART的使用技巧
AT+CIPSTART="TCP","192.168.4.2",8899
在实际使用过程中,需要手机端通过蓝牙发送手机端服务器ip地址和端口号信息给51822模块, 51822解析之后再把它加工成对8266模块的配置指令再发送建立tcp连接。
因为ip地址的长度可能不固定,比如说服务器的ip地址可能是192.168.4.2,也可能是192.168.4.100,这样的话对于实际转化成配置指令带来不便。实际测试发现,可以将ip地址转化成固定的位数,即xxx.xxx.xxx.xxx,不够的位置高位补0,如192.168.4.2可以写成192.168.004.002。
同理,把端口号固定成5位,如8899可以写成08899.
测试结果显示AT+CIPSTART="TCP","192.168.004.002",08899和AT+CIPSTART="TCP","192.168.4.2",8899的效果是一样的。

另一个就是关于发起TCP连接之后连接是否建立成功的判断
发送AT+CIPSTART="TCP","192.168.004.002",08899建立连接之后,会有三种返回信息:
1.TCP连接建立成功
AT+CIPSTART="TCP","192.168.004.002",08899
CONNECT

OK
对应逻辑分析仪采集到的字符串为:
AT+CIPSTART="TCP","192.168.004.002",08899\r\r\nCONNECT\r\n\r\nOK\r\n

2.TCP连接之前已经建立
AT+CIPSTART="TCP","192.168.004.002",08899
ALREADY CONNECTED

ERROR
对应逻辑分析仪采集到的字符串为:
AT+CIPSTART="TCP","192.168.004.002",08899\r\r\nALREADY CONNECTED\r\n\r\nERROR\r\n

3.TCP连接建立失败
AT+CIPSTART="TCP","192.168.4.2",8899

ERROR
CLOSED
对应逻辑分析仪采集到的字符串为:
AT+CIPSTART="TCP","192.168.004.002",08899\r\r\n\r\nERROR\r\nCLOSED\r\n

实际测试发现,如果之前TCP连接已经建立,也就是第2种情况,那字符串的返回是连续的,而且是非常快的;但是另外两种情况,都是会先返回AT+CIPSTART="TCP","192.168.004.002",08899尝试去连接,尝试过后会返回连结成功或连接失败,但是很重要的一点是,尝试连结的时间是不固定的,可能很快(如10ms)连接成功并返回,也可能很长时间(大于100ms)才连结成功并返回。所以如果使用串口接收中断来接收返回字符串并判断是否连接成功是非常困难的。我最后的做法是,不判断该条指令的返回字符串,如果要使用透传功能,就在使用之前发送建立TCP连接的指令(不管当前TCP连接是否建立),然后过一段时间(如200ms)再使用查询语句去查询当前TCP连接是否建立。


实际使用过程中查询TCP连接状态指AT+CIPSTATUS的使用方法
在使用AT+CIPSTATUS指令查询当前TCP连接状态时,会有两种返回字符串:
//如果当前TCP处于连接状态,则返回                           
   
AT+CIPSTATUS\r\r\nSTATUS:5\r\n+CIPSTATUS:0,"TCP","192.168.4.2",8899,11964,0\r\n\r\nOK\r\n
  //当未建立TCP连接时,则返回
  
AT+CIPSTATUS\r\r\nSTATUS:5\r\n\r\nOK\r\n

在实际使用过程中,对返回字符串的接收和处理方法是这样的:
先判断是否接收到了AT+前导码,如果接收到了,就开启超时定时器,超时定时器每中断一次,会将一个变量计数值加1,而在串口接收中断函数里面后面每接收到一个字节都会将该计数值清0,如果在规定的时间内该计数值没有清0,在超时定时器的中断函数里检测到计数值大于规定值,则认为本次接收已经完成,超时定时器关闭,触发数据包处理函数。
紧接着就是处理这个数据包,根据CIPSTATUS来判断是不是该指令的返回值,再根据后面的\r或+来判断当前的连接状态。

如何知道一个操作过程从开始到结束所用的精确时间?
初始化一个引脚为低电平,当操作开始的时候将该引脚拉高,当结束的时候再拉低,在操作的时候用逻辑分析仪监控这个引脚,看高电平持续的时间就可以知道这个操作过程持续了多长时间了



下面是在调试过程中遇到的一些现象及分析和解决方法

现象:使用Mini usb给蓝牙开发板供电,使用锂电池给8266模块供电,两者共地,在51822通过串口发送配置指令给8266模块时经常会出现蓝牙断线、51822芯片重启等情况
调试和分析:调试发现,当使用同一个电源(如外部稳压电源3.3V)给8266模块和51822开发板供电时,使用51822发送串口配置指令,会很少出现蓝牙断线或重启的情况。

现象:用外部稳压电源3.3V接51822开发板的一组VCC和GND,开发板不能工作(看不到广播灯闪烁),而用Mini usb供电可以工作
调试和分析:在调试过程中发现,使用外部电源供电开发板不能工作,但当开发板上的RX引脚接上ESP8266模块的TX引脚时,开发板可以工作了。于是可以将这个问题看成跟之前发现的  51822初始化了串口但串口没有接负载时不能正常工作  是同一个问题。

现象:用外部稳压电源3.3V给51822供电,接了8266模块的串口,仍然不能工作
调试和分析:多次尝试发现,用3.3V给51822开发板和8266模块供电,51822开发板和8266模块串口连接,如果51822开发板不能工作,那用Mini usb重新给51822开发板下载一次程序,再拔掉Mini usb供电,51822开发板就可以工作了。
                                           
 ESP8266模块异常工作状态的表现
在8266模块的使用过程中,会出现上电没能正常工作的情况,有时也会出现在工作过程中突然不能正常工作的情况。当8266模块工作异常时,通过其模块的工作电流可以有一个大致的判断,在其正常工作时,供电电流是0.07A,当大于这个值(如0.15A,0.34A)或小于这个值(如0.05A)都不能正常工作,经常会伴随芯片严重发热的情况,且红色工作状态指示LED亮度也会有变暗。


现象:用51822串口连续发两条AT配置指令(AT+CWMODE=3,AT+CIPMUX=0),两条指令之间加20ms的延时,但是使用逻辑分析仪观察发现,接收到的时序是  A  20ms延时   T+CWMODE=3AT+CIPMUX=0,即先接收到了第一个字符串的第一个字符,延时过后,第一个字符串的后面的部分跟第二个字符串一起接收到


调试和分析:尝试了以下方法
1.增加延时时间至1000ms或2000ms。发现结果一样。
2.把发送操作由按键触发改放到蓝牙指令触发。结果一样
3.把ms延时函数(nrf_delay_ms)改用us延时函数(nrf_delay_us)替换。结果一样
4.更改串口初始化函数uart_init()的位置,放在开启广播之后。结果一样。
5.在发送完一个字符串之后,重新调用串口初始化函数,再发下一条字符串。结果是,第一个字符串发出第一个字符A后,系统重启。
6.改发送字符串改成发送十六进制数。结果一样
7.原本把发送语句放在按键中断处理函数和蓝牙接收中断里,改把发送语句放在主循环中。不会出现上述问题
8.使用裸机程序发送字符串。不会出现上述问题
9.在带协议栈的程序中,直接操作寄存器进行串口初始化操作,直接操作寄存器完成发送字符串函数。不会出现上述问题。
10.用软件定时器定时20ms,每次中断发送一个字符串。不会出现上述问题。
问题的根源在于fifo的操作过程,但解决方法未找到。最终还是使用软件定时器来解决上述问题。


现象:手机连上8266模块的热点之后,打开有人网络助手,打开服务器监听,发现ip地址不是预期的192.168.4.2,而是192.168.1.xxx。
调试及分析:这种现象是由于在手机连上8266模块的热点之前就打开了有人网络助手,有人网络助手获取了之前的wifi网络给手机分配的ip地址,并且即使手机切换了wifi网络(改成连接8266模块的热点)后有人网络还是会保持之前获取的ip地址。解决方法是,在连结上8266的wifi之后,关闭有人网络助手,并且结束它后台的进程,重新打开有人网络助手,再打开监听,发现有人网络助手已经获取到手机当前的ip地址。










原创粉丝点击