手机APP,esp8266,单片机之间究竟是如何连接的呢?
esp8266与单片机是串口连接,esp8266仅作为网络模块使用,不需要写代码。 单片机通过串口发送AT指令,esp8266执行AT指令,设置为STA模式,AP模式或混合模式,生成WIFI和服务器IP,完成组网。手机APP可以连接esp8266在AP模式下的热点。也可以连接在STA模式下esp8266连接的那个WiFi。
如何组成一个局域网?
连接同一个局域网的设备是如何通讯的呢?这和esp8266的透传功能有什么联系?
在一个局域网内,一个设备连接另一个设备的IP,那么信息就可以发到另一个设备上。这个IP是在设备接入这个局域网代表了设备地址。APP端向ESP发送字符1,ESP会在串口输出+IPD:0,3,:1。ESP串口速率需要和单片机的串口速率相同。指令为AT+UART_DEF=9600,8,1,0,0,表示8位数据,1位停止位,无校验位,不使能流控。单片机通过串口,用AT指令将数据发送到ESP,同时手机APP也开始采集数据。
不同模式适合咋样的应用场景?
在使用esp8266之前,需要调试一下。将esp8266的发送和接收串口连接到转串口上之后,连接电脑,电脑打开串口调试助手。使用串口调试助手发送AT指令到esp8266,设置它的工作模式。发送AT,返回OK,表示连接正常。然后发送AT+CWMODE=1,设置为STA模式。在这个模式下,esp8266作为一个终端,需要连接WiFi或者热点。然后发送AT+RST,重启之后设置的模式才会生效。设置好模式之后,esp8266需要连接WiFi或者热点。发送AT+CWLAP,查询当前WIFI列表。发送AT+CWJAP="WIFI名",""WIFI密码。连接到此WIFI后,会显示WIFI CONNECTED,GOT IP。断电重启后,ESP8266会自动连接到这个WIFI,获取IP。发送AT+CIFSR,获取当前局域网内,esp8266的ip。这个ip需要记住,因为待会手机APP需要根据这个ip来连接esp8266。发送AT+CIPMUX=1,建立多连接。发送AT+CIPSERVER=1,8080,建立服务器,端口号是8080。esp8266配网完成。手机APP里的服务器地址改为之前记下的esp的IP地址,端口号为8080.点击连接,显示连接成功,串口助手会返回connect。
发送AT+CWMODE=2,设置为AP模式。在AP模式下,esp作为一个热点,手机可以连接。AT+RST重启生效。那么,下一步不需要像STA模式那样,查询WIFI列表并连接。下一步就是查询esp的IP地址,AT+CIFSR。然后就是建立多连接和建立服务器。AP模式配置完成。手机连接ESP生成的WIFI,连接ESP的IP。
无论是STA模式,还是AP模式,手机APP都可以与单片机通讯,ESP扮演了中转站的角色。由于ESP本身不需要编程,主要是单片机需要完成ESP初始化,UART设置,UART_SEND封装各种AT命令,以及UART_RECE接收手机发送的命令。
ESP8266 WIFI模块有TX,RX,VCC,VSS引脚,还有4个分别为CH_PD,GPIO0,GPIO1,RST。GPIO0在需要升级固件时,需要拉低;CH_PD是EN引脚,使用时需要拉高。
#include "stm32f10x.h"
#include "esp8266.h"
void main(void)
{
ESP8266_USART_Config();
esp8266_init();
while(1);
}
//----------------------------------------------------------------------------
#include"esp8266.h"
#include"stm32f10x.h"
void esp8266_init(void)
{
usart_sendcmd("AT");
usart_sendcmd("AT+CWMODE=2");
usart_sendcmd("AT+RST");
usart_sendbuild(void);
usart_sendcmd("AT+RST");
usart_sendcmd("AT+CIPAP");
usart_sendcmd("AT+CIPMUX=1");
usart_sendservicer("AT+CIPSERVICER=1,8080");
}
//---------------------------------------------------------------------------
#include"stm32f10x.h"
#include "usart.h"
void ESP8266_USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_Configuration();
USART_ITConfig( USART2, USART_IT_RXNE, ENABLE);
USART_ITConfig (USART2, USART_IT_IDLE, ENABLE ); //使能串口总线空闲中断
USART_Cmd(USART2, ENABLE);
}
//---------------------------------------------------------------------------------------
void usart_sendcmd(char*p)
{
for(int i=0;*p!='\0';i++)
{
USART_SendData(*p);
Delay(50);
p++;
}
Delay(50);
USART_SendData('\r');
Delay(50);
USART_SendData('\n');
Delay(100);
}
void usart_senddata(uint8_t *p)
{
usart_sendcmd("AT+CIPSEND=0,7");
for(int i=0;*p!='\0';i++)
{
USART_SendData(*p);
Delay(50);
p++;
}
Delay(50);
USART_SendData('\r');
Delay(50);
USART_SendData('\n');
Delay(100);
}
void usart_sendbuild(void)
{
char ccmd[100]={0};
ccmd[100]="AT+CWSAP=\"ESP8266\",\"12345678\",1,0"
usart_sendcmd(ccmd);
Delay(50);
USART_SendData('\r');
Delay(50);
USART_SendData('\n');
Delay(100);
}
//-------------------------------------------------------------------------------------
void USART2_IRQHandler(void)
{
char ch[100]={0};
if(USART_GetITStatus( USART2, USART_IT_RXNE)!=RESET)
{
ch=USART_ReceiveData( USART2 );
}
USART_ClearITPendingBit(USART2, USART_IT_RXNE );
if((ch[0]=='+')&&(ch[1]=='I')&&(ch[2]=='P')&&(ch[3]=='D')&&(ch[4]==',')&&(ch[5]=='0')&&(ch[6]==',')&&(ch[7]=='1')&&(ch[8]==':'))
{ if(ch[9]==1)
{
ON();
}
else OFF();
}
}
//---------------------------------------------------------------------------------------
void Delay(uint32_t nCount)
{
uint32_t i;
SysTick_Config(SystemCoreClock/1000000);
for (i=0; i<nCount; i++) {
while ( !((SysTick->CTRL)&(1<<16)) );
}
SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
}
在OneNet云平台显示数据。使用ESP8266来上传数据。
HTTP协议。