完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
买正点原子的开发板时送了一块ESP8266wifi模块,一直没使用,最近几天刚好有时间就拿出来玩了一下,现在实现过程分享出来。
用到的模块: 1.STM32F103C8T6最小系统板 2.正点原子ESP8266wifi模块 3.USB转串口模块 整体连接图 ESP8266模块与单片机引脚连接关系 :
ESP8266模块的RST引脚和ID_0引脚悬空,可以不用管。 串口模块与单片机引脚连接关系 :
具体实现的功能是:单片机通过wifi模块连接上原子云,并实时向云端发送数据。通过云端可以向单片机发送 “led on”、“led off”、“led toggle”指令,实现开发板上LED灯的点亮、熄灭、翻转。 串口1监控数据结果 原子云上监控数据 通过原子云上位机测试软件监控 通过手机上原子云客户端监控: 通过网页、上位机软件、手机客户端可以向单片机发送 “led on”、“led off”、“led toggle”指令,实现开发板上LED灯的点亮、熄灭、翻转。基本实现的功能就这些,下面说一下实现思想。 ESP8266模块的驱动代码是在野火【WiFi_ESP8266】模块资料上修改的,具体下载地址:https://ebf-products.readthedocs.io/zh_CN/latest/module/wifi/esp8266.html 正点原子ESP8266wifi模块相关资料下载地址:http://www.openedv.com/thread-308397-1-1.html 通过单片机控制ESP8266模块连接原子云的过程和直接通过串口调试ESP8266模块的过程差不多,实现流程如下: 1.向模块发送测试指令 向模块发生指令: AT 模块回复指令: OK2.设置模块模式为STA模式 向模块发生指令: AT+CWMODE=1 模块回复指令: OK3.设置要连接热点的 ID 和密码 向模块发生指令: AT+CWJAP=“enbiens”,”EB88858804” 模块回复指令: OK4.连接原子云 发送设备编号和密码 向模块发生指令: AT+ATKCLDST,"12345678" 模块回复指令: CLOUD CONNECTED 只需要4步就可以连接到原子云上,ESP8266模块要连接原子云必须要刷原子云的固件,否则最后一步连接原子云的命令是识别不了的。 首先发送测试命令,判断模块与单片机的连接状态是否正常,模块连接正常后就可以发送设置命令了。第二步设置模块为station模式,也就是设置模块为从机。第三步连接路由器,发送wifi名称和密码,连接上wifi后,模块就可以通过路由器连接到互联网上了。最后连接原子云,直接发送原子云上的设备编号和密码接可以了。这个原子云的设备编号是在原子云网站https://cloud.alientek.com/注册的时候会默认分配一个设备编号,密码自己在原子云上可以设置。 要用单片机控制ESP8266模块的关键就是要用代码实现向ESP8266模块发送指令,在野火提供的例子中已经实现了这个函数的封装。 /* * 函数名:ESP8266_Cmd * 描述 :对WF-ESP8266模块发送AT指令 * 输入 :cmd,待发送的指令 * reply1,reply2,期待的响应,为NULL表不需响应,两者为或逻辑关系 * waittime,等待响应的时间 * 返回 : 1,指令发送成功 * 0,指令发送失败 * 调用 :被外部调用 */ bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime ) { strEsp8266_Fram_Record .InfBit .FramLength = 0; //接收缓冲区数据长度清0 macESP8266_Usart ( "%s\r\n", cmd ); //向模块发送命令 if ( ( reply1 == 0 ) && ( reply2 == 0 ) ) //不需要接收数据 return true; Delay_ms ( waittime ); //延时 等待接收模块返回的指令 strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0'; //接收到的字符串末尾加入 结束符 macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF ); //调试口打印接收到模块的指令 if ( ( reply1 != 0 ) && ( reply2 != 0 ) ) return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) || ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) ); else if ( reply1 != 0 ) return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) ); else return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) ); } 这个函数主要实现了向ESP82676模块发送指令,并判断模块返回的指令是否正确。第一个参数cmd中存放要发送的指令,第二个参数存放模块需要返回的字符串,第三个参数也存放模块需要返回的字符串,最后一个参数用来设置向模块发送完指令后需要等待的时间。因为向模块发送指令到模块返回指令还有一段时间的延时。向模块发送完指令后需要等待一段时间,再去判断串口3接收到的数据是否正确。 首先将要发送的命令 通过macESP8266_Usart()函数发送出去。 macESP8266_Usart ( "%s\r\n", cmd ); 这个函数其实就是通过串口3将字符串发送出去。通过串口3向ESP8266模块发送指令后,延时一段时间等待串口接收数据。 Delay_ms ( waittime ); 这行代码实现延时,因为要等待ESP8266模块返回指令,所以代码不能跳出去,必须在这里死等。 strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0'; //接收到的字符串末尾加入 结束符 macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF ); //调试口打印接收到模块的指令 延时一段时间后,就会在串口3的中断函数中接收到ESP8266模块返回的数据。在接收到的数据最后一位添加上字符串结束标志,然后通过调试端口串口1将模块返回的数据打印出来。 最后判断模块返回的字符串是否和参数中提供字符串一样,如果一样说明模块设置正确,否则说明模块设置失败。 要设置不同的命令时,直接调用这个命令设置函数就行,比如第一步向模块发送测试指令 void ESP8266_AT_Test ( void ) { char count = 0; Delay_ms ( 1000 ); while ( count < 10 ) { if( ESP8266_Cmd ( "AT", "OK", NULL, 500 ) ) return; //如果接收到模块返回的OK指令,就直接返回 ESP8266_Rst(); //否则复位模块,重新发送AT测试指令 ++ count; } } 向模块发送“AT”字符串,如果模块返回“OK”则退出,否则循环发送10次。 第二步设置模块为station模式 ESP8266_Net_Mode_Choose ( STA ); /* * 函数名:ESP8266_Net_Mode_Choose * 描述 :选择WF-ESP8266模块的工作模式 * 输入 :enumMode,工作模式 * 返回 : 1,选择成功 * 0,选择失败 * 调用 :被外部调用 */ bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode ) { switch ( enumMode ) { case STA: return ESP8266_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 ); case AP: return ESP8266_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 ); case STA_AP: return ESP8266_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 ); default: return false; } } 第三步连接路由器 ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ); /* * 函数名:ESP8266_JoinAP * 描述 :WF-ESP8266模块连接外部WiFi * 输入 :pSSID,WiFi名称字符串 * :pPassWord,WiFi密码字符串 * 返回 : 1,连接成功 * 0,连接失败 * 调用 :被外部调用 */ bool ESP8266_JoinAP ( char * pSSID, char * pPassWord ) { char cCmd [120]; sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord ); return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 ); } 第四步连接原子云 ESP8266_ConnectYuanziyun ( yuanziyun_DeviceID, yuanziyun_DevicePassWord ); /* * ESP8266_ConnectYuanziyun * 描述 :WF-ESP8266模块连接原子云 * 输入 :pSSID,原子云上设备ID * :pPassWord,原子云上设备密码 * 返回 : 1,连接成功 * 0,连接失败 * 调用 :被外部调用 */ bool ESP8266_ConnectYuanziyun ( char * pSSID, char * pPassWord ) { char cCmd [120]; sprintf ( cCmd, "AT+ATKCLDSTA=\"%s\",\"%s\"", pSSID, pPassWord ); return ESP8266_Cmd ( cCmd, "OK", "CONNECTED", 5000 ); } 这样通过不同的函数,将不同的命令通过命令发送函数发送到串口3上,也就是发送到ESP8266模块上,从而实现ESP8266模块连接到原子云上。 当模块连接到原子云上之后,就可以通过单片机向云端发送数据了。 void ESP8266_Station_Mode_yuanziyun_Test ( void ) { uint8_t value1 = 0, value2 = 0; uint8_t ucStatus; char cStr [ 100 ] = { 0 }; uint8_t ucId; char cStr1 [ 100 ] = { 0 }; char * pCh; printf ( "\r\n正在配置 ESP8266 ......\r\n" ); //1、向模块发送测试指令 AT ESP8266_AT_Test (); //2、设置模块模式为STA模式 AT+CWMODE=1 ESP8266_Net_Mode_Choose ( STA ); //3、设置要连接路由器的 ID 和密码 AT+CWJAP=“enbiens”,”EB88858804” while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) ); //4、连接原子云 发送设备编号和密码 AT+ATKCLDSTA="61212332528032817648","12345678" while ( ! ESP8266_ConnectYuanziyun ( yuanziyun_DeviceID, yuanziyun_DevicePassWord ) ); printf ( "\r\n配置 ESP8266 完毕\r\n" ); while ( 1 ) { value1++; value2++; sprintf ( cStr, "\r\nThe humidity: %d RH ,The temperature: %d C \r\n", value1, value2 ); printf ( "%s", cStr ); //打印数据 ESP8266_SendString ( ENABLE, cStr, 0, Single_ID_0 ); //通过透传模式 发送信息到原子云 Delay_ms ( 1500 ); if ( strEsp8266_Fram_Record .InfBit .FramFinishFlag ) { USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, DISABLE ); //禁用串口接收中断 strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0'; //接收到的数据末尾添加结束符 printf ( "\r\n%s\r\n", strEsp8266_Fram_Record .Data_RX_BUF ); //调试口打印接收到的数据 //strstr是C语言中的函数,作用是返回字符串中首次出现子串的地址。 // 若接收到的字符串中包含字符串 "led on" 就点亮LED灯 if ( ( pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "led on" ) ) != 0 ) { LED1_ON; } // 若接收到的字符串中包含字符串 "led off" 就熄灭LED灯 else if ( ( pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "led off" ) ) != 0 ) { LED1_OFF; } // 若接收到的字符串中包含字符串 "led toggle" 就反转LED灯 else if ( ( pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "led toggle" ) ) != 0 ) { LED1_TOGGLE; } strEsp8266_Fram_Record .InfBit .FramLength = 0; strEsp8266_Fram_Record .InfBit .FramFinishFlag = 0; USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断 } } } 通过两个变量value1和value2模拟单片机采集到的温度和湿度值,向云端发送数据。每发送一次数据后这两个变量加1.当串口3中接收到云端发送的数据后,通过调试口串口1将接收到的内容打印出来。并判断云端接收到数据的内容,如果是"led on"就点亮 LED灯,如果是"led off"就熄灭LED灯,如果是"led toggle"就翻转LED的状态。最后清除串口接收标志。 通过上面的步骤就能实现单片机和手机客户端的通信了,也可以通过手机直接控制单片机。如果将单片机连接上家电后,也可以通过手机直接控制家电。 |
|
|
|
只有小组成员才能发言,加入小组>>
有网友可以分享一款基于51单片机和MCP23017的IO扩展方案吗?谢谢!
1324浏览 4评论嵌入式开发工具Keil 5的安装方法介绍(C51与MDK共存)
3596浏览 4评论小黑屋| 手机版| Archiver| 电子发烧友 ( 粤ICP备14022951号 )
GMT+8, 2022-11-9 07:13 , Processed in 0.475891 second(s), Total 118, Slave 99 queries .
Powered by 电子发烧友网
© 2015 www.ws-dc.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 深圳华秋电子有限公司
电子发烧友 (电路图) 粤公网安备 44030402000349 号 电信与信息服务业务经营许可证:粤 B2-20160233 工商网监 粤ICP备 14022951 号