About connecting the microcontroller to the ESP8266 module to intercept its echo content

Publisher:星光小狐狸Latest update time:2018-11-21 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. First of all, ESP uses the serial port to communicate with the 51 single-chip microcomputer. The control end can use a mobile phone. However, the 51 single-chip microcomputer and the mobile phone are not at the same level, so it is necessary to analyze the operation on the 51 single-chip microcomputer.


2. When ESP8266 receives or sends data, it will send an echo message to the serial port, which is a prompt message, prompting what has been received or sent. Therefore, it is very important to analyze and intercept the string on the microcontroller, otherwise the communication quality between the mobile phone and the microcontroller will be greatly reduced. When I was writing the WiFi car project in the early stage, this problem bothered me for a long time. Later, the progress was too slow, so I compromised and used the method of analyzing a character to control the car, but this processing method is very poor.


3. I finally finished making the WiFi car a while ago. Although it only has simple movement, LCD display and obstacle avoidance, I can’t continue working on it anymore. I need to learn new things. Before that, I need to perfect the use of ESP so that I can concentrate on learning the next step and pave the way for future projects.


analysis of idea:


1. First of all, the initialization of the UART serial port will not be described in detail. You can initialize it successfully after learning it.


2. Then, in the interrupt service function of the serial port, use temp to receive the echo data in SBUF, and then make judgments and processes immediately in the interrupt service function, saving what should be saved and skipping what should be discarded. In addition, actions with long delays cannot be performed in the interrupt service function, so only the troublesome flag bits can be used.


3. How to tell when a whole sentence is echoed? Because the echo does not echo \0, at most it only echoes \r\n (carriage return and line feed), so how to judge when to start receiving the first character of a sentence? The method I use now is to use \n as the beginning of receiving a sentence echo and \r as the end of receiving a sentence echo. This process is achieved by setting the flag bit, which is relatively simple.


0,CONNECT


+IPD,0.1:y


Corresponding hexadecimal: 30 2C 43 4F 4E 4E 45 43 54 0D 0A 0D 0A 2B 49 50 44 2C 30 2C 31 3A 79


\r \n \r \n


1_copy.png

2_copy.png

3_copy.png


The above is the echo template. Based on the content, we can understand that it is more effective to use \r\n to determine the start and end positions.


4. Secondly, what is more important now is to obtain the data sent by the mobile phone, that is, the echo sentence such as +IPD,0,3:abc (0: customer connection number, 3: string length), which needs to be intercepted and stored in the microcontroller for use by other functions. Then the parsing of this string is done in a dynamic process, so the timeliness needs to be very high. It needs to be analyzed and processed immediately. It cannot be saved first and then judged, because there is no string terminator. The end mark is completely determined by the 3 in front, that is, the string length. Even \r is useless here, and it can only be dynamically judged and analyzed.


5. The following is the serial port interrupt service function 51 program


//Interrupt service function for soft reset


void uart_isr() interrupt 4


{


//loc is used to offset the ret_msg global variable to assemble a string


static unsigned char i = 0;


unsigned char temp;


EN = 0;


temp = SBUF; //temp cannot be changed because soft reset is required


/*ESP8266 intercepts the string part*/


if(temp == '\n')//Start character


{


Rev_status = BEGIN; //Set to start receiving


}


else if(temp == '\r')//end character


{


Rev_status = END; //Set to end reception


}


else // Characters other than \r\n


{


/************************************************/


//Specially used to receive IPD and CIFSR. When the reception ends, set Rev_Str_status to invalid and enter the following loop again to detect the first character


if(Rev_Str_status == BEGIN)


{


if((str_rev_flag == END) &&(temp != ':') && (str_len_flag == BEGIN))//Start receiving string length


{


str_len = str_len * 10 + (temp - '0');


}


//To fully ensure that there is only one situation and it is entered once, use multiple flags


if((str_rev_flag == END) &&(First_dou_flag == OK) && (temp == ',') && (client_num_flag == BEGIN) && (str_len_flag == END))//Received a comma again and started receiving the string length


{


str_len_flag = BEGIN;


client_num_flag = END;


}


//The first comma comes, enter, and no longer enter


if((str_rev_flag == END) &&(First_dou_flag == NO) && (temp == ',') && (client_num_flag == END))//逗号来临


{


client_num_flag = BEGIN;


First_dou_flag = OK; // is the first comma


}


//Start receiving user connection number


if((str_rev_flag == END) && (temp != ',') && (client_num_flag == BEGIN))


{


client_num = client_num * 10 + (temp - '0');


}


//Start receiving string


if(str_rev_flag == BEGIN)


{


//Save the string to a global variable for later output


Get_str[Get_str_loc] = temp;


Get_str_loc ++;


//If the length of the string is the same as the specified string just received, no more reception will be done and finishing work will be done


if(Get_str_loc == str_len)


{


Get_str[Get_str_loc] = '\0';


Str_Ready = OK; //Set the flag to indicate that I have received a complete string and can perform operations.


Rev_Str_status = END; // Clear the received string flag so that the following switch loop can be entered again


client_num_flag = END; // Clear the receiving client_num flag


str_len_flag = END; // Clear the received str_len string length flag


str_rev_flag = END; // Clear the flag bit for receiving the real string


First_dou_flag = NO; // Clear the flag to distinguish the first comma


}


}


if(temp == ':') //If it starts:, then the character length of the string to be received is str_len


{


str_rev_flag = BEGIN;


}


}


/************************************************/


/************************************************/


//This should be done only when the flag bit of the received string is invalid and the receiving status bit is valid


if((Rev_Str_status == END) && (Rev_status == BEGIN))


{


//After detecting the first one, immediately set the receiving flag to invalid and temporarily stop receiving


switch(temp)


{


case '+':// Either +IPD or +CIFSR is received


{


Rev_Str_status = BEGIN; //Start receiving, do not enter this switch loop for now


Rev_status = END;


break;


}


case 'E'://Send failed, ERROR is displayed


{


Send_flag = NO;


Rev_status = END;


break;


}


case 'S'://Send successfully, echo SEND OK


{


Send_flag = OK;


Rev_status = END;


break;


}


default:


{


Rev_status = END;


break;


}


}


}


}


//Used during soft reset


if(0x7f == temp)//special for Doflye


{


i ++;


if(10 == i)


{


i = 0;


ISP_CONTR = 0xe0;


}


}


else


{


i = 0;


}


RI = 0;


EN = 1;


}


6. Since it is done in a dynamic process, judgment and flags are the only options. Here we need to figure out the logic. Although I am also confused about the above program, I wrote it based on my feelings and debugged it bit by bit. Finally, it can be implemented stably. I still need to improve the algorithm.


7. Another thing is to make good use of sprintf, which can convert the number you need to display into the corresponding string. Note: It is best to use int type.


8. Below is the entire module function and usage examples


/********************Usage example**************************************/


// /*Test ESP8266, purpose: get the echo information*/


// #include


// #include "delay.h"


// #include "WifiESP8266.h"


// #include "lcd.h"


// #include "uart.h"


// #include "delay.h"


// #include


// #include


// extern bit Ok_flag;


// extern bit Str_Ready;


// extern bit Rev_Str_status;


// extern bit str_rev_flag;


// extern bit flag;


// extern unsigned char Get_str[40];


// extern int client_num;


// extern int str_len;


// void main()


// {


// unsigned char temp_buf[16] = "Tmp:26 Hum:56";


// int i = 0;


// uart_init();


//


// lcd_init();


// lcd_clean();


// delay_ms(500);


//


// WifiESP8266_Init("ZTLTest","0123456789","8000");


//


// while(1)


// {


// if(OK == SendStrToClint(temp_buf,0,strlen(temp_buf)))


// //Sent to the client with connection number 0, hhh, three bytes in length


// {


// lcd_clean();


// lcd_write_str(1,1,"SEND OK");


// }


// else


// {


// lcd_clean();


// lcd_write_str(1,1,"ERROR");


// }


//


// if(check_revStr() == OK) // can also be changed to while in a function body


// {


// /*************Write the operation on the obtained string**************/


// sprintf(temp_buf,"%d %d %s\0",client_num,str_len,Get_str);


// lcd_write_str(0,0,temp_buf);


// /*****************************************/


//


//


// /*********************After the test is successfully received, reply to the message without ********************/


// // if(OK == SendStrToClint(Get_str,0,strlen(Get_str)))


// // //Sent to the client with connection number 0, hhh, three bytes in length


// // {


// // lcd_clean();


// // lcd_write_str(1,1,"SEND OK");


// // }


// // else


// // {


// // lcd_clean();


// // lcd_write_str(1,1,"ERROR");


// // }


// /******************************************************/


//


//


// /**************************Must add!********************************/


// clean_flag(); //Call the clear function in the wifi module


// /*******************************************************/


// }


//


//


// }


// }


/************************************************************/


/*


Wifi module ESP8266 module test function


Author: Zhang Tianle


Start time: 2016/1/19


Function: Complete basic connection functions


Modified time: 2016/1/28


Function: Ability to distinguish which client sends which data


*/


#include


#include "WifiESP8266.h"


#include "uart.h"


#include "lcd.h"


#include "delay.h"


#include


#include


//The receiving status defaults to end


bit Rev_status = END; //Receive status bit


bit Rev_Str_status = END; //Receive string status bit


bit Send_flag = NO; //Send information to the mobile phone status bit


bit OK_flag = NO; //success status bit


bit Str_Ready = NO; //Data ready status bit


bit First_dou_flag = NO; //Is it the first comma?


//Get the string content


unsigned char Get_str[40];


unsigned char Get_str_loc = 0;


//Customer connection number and string length


int client_num = 0;


int str_len = 0;


bit client_num_flag = END;


bit str_len_flag = END;


bit str_rev_flag = END;


//Check whether data is received for other functions to call. If data is received, then other functions can extract the global variable Get_str


//After other functions have finished receiving, the clear function must be called to clear the flag for next use


bit check_revStr()


{


if(Str_Ready == OK)


{


return OK;


}


return NO;


}


void clean_flag()


{


//Clear operation


memset(Get_str,0,sizeof(Get_str));


client_num = 0;


str_len = 0;


Get_str_loc = 0; // Clear some global variables for the next operation. Get_str should be cleared after receiving it in the external function.


Str_Ready = NO; // Clear the receive data ready flag


}


//Send a string to the client with the connection number num, the content is the parameter str


//str: sent content, str_len: number of bytes sent, client_num: client connection number, note: all parameters are in string form!


bit SendStrToClint(unsigned char *str,int client_num,int str_len) //String parsing is required to determine whether the sending is successful


{


//Buffer for splicing AT commands


unsigned char AT_temp[30] = {0};


//Splice into: "AT+CIPSEND=client_num,str_len\r\n" Set to send, the first parameter after = is the client connection number, i.e. client_num, and the second is the number of bytes to be sent


sprintf(AT_temp,"AT+CIPSEND=%d,%d\r\n",client_num,str_len);


uart_sendstr(AT_temp); //Send the encapsulated AT command


delay_ms(50);


//Send the bytes that need to be sent


uart_sendstr(str);


delay_s(1);


//After one second, check whether there is a successful send flag. If the send is successful, set Send_flag to valid


if(Send_flag == NO)


{


return NO;


}


else


{


//After sending, clear the flag to invalid for next use


Send_flag = NO;


return OK;


}


}


// Initialization function of the wifi module wifi name, wifi password and port name, the IP name is fixed to 192.168.4.1


void WifiESP8266_Init(unsigned char *name,unsigned char *password,unsigned char *port)


{


//Used to splice AT string commands


unsigned char AT_tempBuf[50] = {0};


//Send AT commands, set wifi mode, etc.


uart_sendstr("AT+RST\r\n");//重启


delay_s(1);


uart_sendstr("AT+CWMODE=2\r\n"); //Set to AP mode, wifi module acts as a router


delay_s(1);


//Set the wifi name and password


sprintf(AT_tempBuf,"AT+CWSAP=\"%s\",\"%s\",11,4\r\n",name,password);


uart_sendstr(AT_tempBuf);


memset(AT_tempBuf,0,sizeof(AT_tempBuf));//Clear after use


delay_s(1);


uart_sendstr("AT+RST\r\n");//重启


delay_s(1);


uart_sendstr("AT+CIPMUX=1\r\n");//Set to multi-channel


delay_s(1);


//Start concatenating strings with port numbers


sprintf(AT_tempBuf,"AT+CIPSERVER=1,%s\r\n",port);


uart_sendstr(AT_tempBuf); //Open the service, need to splice


memset(AT_tempBuf,0,sizeof(AT_tempBuf));//Clear after use


delay_s(1);


}


//Interrupt service function for soft reset


void uart_isr() interrupt 4


{


//loc is used to offset the ret_msg global variable to assemble a string


static unsigned char i = 0;


unsigned char temp;


EN = 0;


temp = SBUF; //temp cannot be changed because soft reset is required


/*ESP8266 intercepts the string part*/


if(temp == '\n')//Start character


{


Rev_status = BEGIN; //Set to start receiving


}


else if(temp == '\r')//end character


{


Rev_status = END; //Set to end reception


}


else // Characters other than \r\n


{


/************************************************/


//Specially used to receive IPD and CIFSR. When the reception ends, set Rev_Str_status to invalid and enter the following loop again to detect the first character


if(Rev_Str_status == BEGIN)


{


if((str_rev_flag == END) &&(temp != ':') && (str_len_flag == BEGIN))//Start receiving string length


{


str_len = str_len * 10 + (temp - '0');


}


//To fully ensure that there is only one situation and it is entered once, use multiple flags


if((str_rev_flag == END) &&(First_dou_flag == OK) && (temp == ',') && (client_num_flag == BEGIN) && (str_len_flag == END))//Received a comma again and started receiving the string length


{


str_len_flag = BEGIN;


client_num_flag = END;


}


//The first comma comes, enter, and no longer enter


if((str_rev_flag == END) &&(First_dou_flag == NO) && (temp == ',') && (client_num_flag == END))//逗号来临


{


client_num_flag = BEGIN;


First_dou_flag = OK; // is the first comma


}


//Start receiving user connection number


if((str_rev_flag == END) && (temp != ',') && (client_num_flag == BEGIN))


{


client_num = client_num * 10 + (temp - '0');


}


//Start receiving string


if(str_rev_flag == BEGIN)


{


//Save the string to a global variable for later output


Get_str[Get_str_loc] = temp;


Get_str_loc ++;


//If the length of the string is the same as the specified string just received, no more reception will be done and finishing work will be done


if(Get_str_loc == str_len)


{


Get_str[Get_str_loc] = '\0';


Str_Ready = OK; //Set the flag to indicate that I have received a complete string and can perform operations.


Rev_Str_status = END; // Clear the received string flag so that the following switch loop can be entered again


client_num_flag = END; // Clear the receiving client_num flag


str_len_flag = END; // Clear the received str_len string length flag


str_rev_flag = END; // Clear the flag bit for receiving the real string


First_dou_flag = NO; // Clear the flag to distinguish the first comma


}


}


if(temp == ':') //If it starts:, then the character length of the string to be received is str_len


{


str_rev_flag = BEGIN;


}


}


/************************************************/


/************************************************/


//This should be done only when the flag bit of the received string is invalid and the receiving status bit is valid


if((Rev_Str_status == END) && (Rev_status == BEGIN))


{


//After detecting the first one, immediately set the receiving flag to invalid and temporarily stop receiving


switch(temp)


{


case '+':// Either +IPD or +CIFSR is received


{


Rev_Str_status = BEGIN; //Start receiving, do not enter this switch loop for now


Rev_status = END;


break;


}


case 'E'://Send failed, ERROR is displayed


{


Send_flag = NO;


Rev_status = END;


break;


}


case 'S'://Send successfully, echo SEND OK


{


Send_flag = OK;


Rev_status = END;


break;


}


default:


{


Rev_status = END;


break;


}


}


}


}


//Used during soft reset


if(0x7f == temp)//special for Doflye


{


\i ++;


if(10 == i)


{


i = 0;


ISP_CONTR = 0xe0;


}


}


else


{

i = 0;


}


RI = 0;


EN = 1;


}


Finally, there is still a little flaw. The Android client is not well completed. It can only send strings to the microcontroller, but the data sent by the microcontroller cannot be displayed on the mobile phone using socket. Android is a weak point, but socket communication still needs to be learned well. I will learn network programming later, and I will also try to write the corresponding Android client.


Reference address:About connecting the microcontroller to the ESP8266 module to intercept its echo content

Previous article:Software configuration problem of using the "external counting" TIMx_ETR pulse measurement of the stm8 microcontroller
Next article:Realize the connection between Bluetooth HC-05, 06 and single-chip microcomputer and communication with mobile phone

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号