grove_esp8266
Embed:
(wiki syntax)
Show/hide line numbers
grove_esp8266.cpp
00001 00002 00003 #include "suli2.h" 00004 #include "grove_esp8266.h" 00005 00006 00007 00008 //local functions 00009 static void _uart_rx_callback(void); 00010 static bool esp8266_send_cmd(UART_T *uart, char *command, char *content, unsigned int timeout); 00011 __weak static void esp8266_callback(char *msg, unsigned int len); 00012 00013 00014 //local variables 00015 static char content_buffer[CONTENT_BUF_LEN]; 00016 static char rx_buf[RX_BUF_LEN]; 00017 static unsigned int rx_buf_ptr = 0;//point to the next unused char of rx_buf 00018 static char cmd[70]; 00019 static char cmd_buf[70]; 00020 static char *WaitForAnswer_cmd_Buffer; 00021 static char *WaitForAnswer_ans_Buffer; 00022 static char *WaitForAnswer_data_Buffer; 00023 static ESP8266_RecvStateMachine recv_machine = RECV_DATA; 00024 static bool flag_recved_cmd = false; 00025 static bool flag_recved_end = false; 00026 static bool flag_send_ok = false; 00027 00028 static UART_T *_uart; 00029 static user_cb_fun_ptr user_cb_fun; 00030 EVENT_T event_esp8266; 00031 00032 void grove_esp8266_init(UART_T *uart, int pintx, int pinrx) 00033 { 00034 suli_uart_init(uart, pintx, pinrx, 115200); 00035 } 00036 00037 bool grove_esp8266_write_setup(UART_T *uart) 00038 { 00039 memset((void *)rx_buf, 0, RX_BUF_LEN); 00040 memset((void *)content_buffer, 0, CONTENT_BUF_LEN); 00041 _uart = uart; 00042 suli_uart_rx_event_attach(uart, (cb_fun_ptr)&_uart_rx_callback); 00043 grove_esp8266_write_setcbfun(esp8266_callback); 00044 00045 return true; 00046 } 00047 00048 void grove_esp8266_write_setcbfun(user_cb_fun_ptr fun) 00049 { 00050 user_cb_fun = fun; 00051 } 00052 00053 bool grove_esp8266_attach_event_handler(CALLBACK_T handler) 00054 { 00055 suli_event_init(&event_esp8266, handler); 00056 // pinMode(13, INPUT_PULLUP); 00057 // attachInterrupt(13, _trigger, FALLING); 00058 return true; 00059 } 00060 00061 //////////////////////////////////////////////////////////////////////////////////////////////////////////// 00062 bool grove_esp8266_read_getversion(UART_T *uart) 00063 { 00064 //read version information 00065 while(esp8266_send_cmd(uart, (char*)"AT+GMR", content_buffer, 200) != true) 00066 { 00067 printf("try again\r\n"); 00068 wait(0.5); 00069 } 00070 printf("Version: %s\r\n", content_buffer); 00071 00072 return true; 00073 } 00074 00075 bool grove_esp8266_write_joinwifi(UART_T *uart, char *ssid, char *pwd) 00076 { 00077 //set to station mode 00078 printf("set mode to STATION\r\n"); 00079 wait(0.1); 00080 while(esp8266_send_cmd(uart, (char*)"AT+CWMODE=1", content_buffer, 200) != true) 00081 { 00082 printf("try again\r\n"); 00083 wait(0.5); 00084 } 00085 printf("OK\r\n\r\n"); 00086 00087 //join router 00088 printf("joining specified router\r\n"); 00089 wait(0.1); 00090 while(esp8266_send_cmd(uart, (char*)"AT+CWJAP=\"stu.se.private\",\"depot0510se\"", content_buffer, 5000) != true) 00091 { 00092 printf("try again\r\n"); 00093 wait(0.5); 00094 } 00095 printf("joined\r\n"); 00096 wait(0.1); 00097 while(esp8266_send_cmd(uart, (char*)"AT+CWJAP?", content_buffer, 1000) != true) 00098 { 00099 printf("try again\r\n"); 00100 wait(0.5); 00101 } 00102 printf("joined indeed\r\n\r\n"); 00103 00104 return true; 00105 } 00106 00107 bool grove_esp8266_write_socketasclient(UART_T *uart, char *ip, unsigned int port) 00108 { 00109 //enable mux connection 00110 printf("enable mux connection\r\n"); 00111 wait(0.1); 00112 while(esp8266_send_cmd(uart, (char*)"AT+CIPMUX=1", content_buffer, 200) != true) 00113 { 00114 printf("try again\r\n"); 00115 wait(0.5); 00116 } 00117 printf("OK\r\n\r\n"); 00118 00119 //connect to tcp server 00120 printf("connect to tcp server\r\n"); 00121 wait(0.1); 00122 while(esp8266_send_cmd(uart, (char*)"AT+CIPSTART=4,\"TCP\",\"192.168.21.159\",6320", content_buffer, 2000) != true) 00123 { 00124 printf("try again\r\n"); 00125 wait(0.5); 00126 } 00127 printf("OK\r\n\r\n"); 00128 00129 return true; 00130 } 00131 00132 bool grove_esp8266_read_aplist(UART_T *uart) 00133 { 00134 //list all AP 00135 printf("list all AP around\r\n"); 00136 wait(0.1); 00137 while(esp8266_send_cmd(uart, (char*)"AT+CWLAP", content_buffer, 10000) != true) 00138 { 00139 printf("try again\r\n"); 00140 wait(0.5); 00141 } 00142 printf("%s\r\n", content_buffer); 00143 00144 return true; 00145 } 00146 00147 /* 00148 function: internal function, uart callback 00149 */ 00150 static void _uart_rx_callback(void) 00151 { 00152 unsigned int payload_len, header_len; 00153 unsigned int port; 00154 int res; 00155 char *payload_str; 00156 00157 while(suli_uart_readable(_uart)) 00158 { 00159 if(rx_buf_ptr < RX_BUF_LEN - 2) 00160 { 00161 rx_buf[rx_buf_ptr++] = suli_uart_read(_uart); 00162 } 00163 } 00164 //receiving state machine after recved all data for now 00165 switch(recv_machine) 00166 { 00167 case RECV_DATA: 00168 WaitForAnswer_data_Buffer = strstr(rx_buf, "\r\n+IPD");//check the "+IPD" response 00169 if(WaitForAnswer_data_Buffer != NULL)//user data recved 00170 { 00171 res = sscanf(rx_buf,"\r\n+IPD,%d,%d:", &port, &payload_len); 00172 payload_str = strtok(rx_buf, ":"); 00173 header_len = strlen(payload_str) + 1; 00174 if((res == 2) && (payload_len == rx_buf_ptr - header_len)) 00175 { 00176 memcpy(content_buffer, rx_buf + header_len, payload_len); 00177 user_cb_fun(content_buffer, payload_len); 00178 memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv 00179 rx_buf_ptr = 0; 00180 } 00181 } 00182 break; 00183 case RECV_CMD: 00184 WaitForAnswer_cmd_Buffer = strstr(rx_buf, cmd_buf);//check the cmd 00185 if(WaitForAnswer_cmd_Buffer != NULL)//right cmd 00186 { 00187 flag_recved_cmd = true; 00188 recv_machine = RECV_END; 00189 } 00190 break; 00191 case RECV_END: 00192 //check the "OK" response 00193 WaitForAnswer_ans_Buffer = strstr(WaitForAnswer_cmd_Buffer, "\r\nOK\r\n"); 00194 if(WaitForAnswer_ans_Buffer != NULL)//"OK"recved 00195 { 00196 //recv cmd response 00197 flag_recved_end = true; 00198 } 00199 //check the "ERROR" response 00200 WaitForAnswer_ans_Buffer = strstr(WaitForAnswer_cmd_Buffer, "\r\nERROR\r\n"); 00201 if(WaitForAnswer_ans_Buffer != NULL)//"ERROR"recved 00202 { 00203 flag_recved_end = true; 00204 } 00205 //check the "SEND OK" response 00206 WaitForAnswer_ans_Buffer = strstr(WaitForAnswer_cmd_Buffer, "\r\nSEND OK\r\n"); 00207 if(WaitForAnswer_ans_Buffer != NULL)//"SEND OK"recved 00208 { 00209 flag_send_ok = true; 00210 } 00211 break; 00212 default: 00213 break; 00214 } 00215 } 00216 00217 /* 00218 function: send data through ESP8266 00219 const char *command: AT command to be send 00220 char *content: returned data from ESP8266 00221 unsigned int timeout: timeout 00222 */ 00223 static bool esp8266_send_cmd(UART_T *uart, char *command, char *content, unsigned int timeout) 00224 { 00225 volatile uint32_t TxWaitForResponse_TimeStmp; 00226 unsigned int len; 00227 00228 //reset flags and state machine 00229 recv_machine = RECV_CMD; 00230 flag_recved_cmd = false; 00231 flag_recved_end = false; 00232 //clear the buffer 00233 memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv 00234 rx_buf_ptr = 0; 00235 //save the cmd just sent 00236 strcpy(cmd_buf, command); 00237 sprintf(cmd, "%s\r\n", command); 00238 //send cmd 00239 suli_uart_write_bytes(_uart, (uint8_t*)cmd, strlen(cmd)); 00240 00241 //wait for response 00242 TxWaitForResponse_TimeStmp = millis(); 00243 while(millis() - TxWaitForResponse_TimeStmp < timeout)//timeout control 00244 { 00245 if(flag_recved_cmd == true) 00246 { 00247 if(flag_recved_end == true) 00248 { 00249 WaitForAnswer_ans_Buffer = strstr(WaitForAnswer_cmd_Buffer, "\r\nOK\r\n");//check the "OK" response 00250 if(WaitForAnswer_ans_Buffer != NULL) 00251 { 00252 len = WaitForAnswer_ans_Buffer - WaitForAnswer_cmd_Buffer - strlen(cmd_buf) - 3; 00253 memset(content, 0, CONTENT_BUF_LEN); 00254 memcpy(content, WaitForAnswer_ans_Buffer - len, len); 00255 memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv 00256 rx_buf_ptr = 0; 00257 recv_machine = RECV_DATA; 00258 return true; 00259 } 00260 } 00261 } 00262 wait(0.1); 00263 } 00264 memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv 00265 rx_buf_ptr = 0; 00266 recv_machine = RECV_DATA; 00267 return false; 00268 } 00269 00270 /* 00271 function: send data through ESP8266 00272 char *data: data will be send 00273 unsigned int len: data length in byte 00274 */ 00275 bool grove_esp8266_write_msg(UART_T *uart, char *msg, unsigned int len) 00276 { 00277 volatile uint32_t TxWaitForResponse_TimeStmp; 00278 unsigned ptr = 0; 00279 00280 if(len > 2048) 00281 return false; 00282 00283 //send cmd 00284 sprintf(cmd, "AT+CIPSEND=4,%d", len); 00285 if(esp8266_send_cmd(uart, cmd, content_buffer, 200) != true) 00286 { 00287 return false; 00288 } 00289 //send user data 00290 while(len--) 00291 { 00292 suli_uart_write(uart, msg[ptr++]); 00293 } 00294 00295 //reset flags and state machine 00296 recv_machine = RECV_END; 00297 flag_recved_cmd = false; 00298 flag_recved_end = false; 00299 flag_send_ok = false; 00300 00301 //wait for response 00302 TxWaitForResponse_TimeStmp = millis(); 00303 while(millis() - TxWaitForResponse_TimeStmp < 500)//timeout control 00304 { 00305 if(flag_send_ok == true) 00306 { 00307 memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv 00308 rx_buf_ptr = 0; 00309 recv_machine = RECV_DATA; 00310 return true; 00311 } 00312 wait(0.01); 00313 } 00314 memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv 00315 rx_buf_ptr = 0; 00316 recv_machine = RECV_DATA; 00317 return false; 00318 } 00319 00320 /* 00321 callback function when a piece of message arrived 00322 this is a WEAK declaration 00323 */ 00324 __weak static void esp8266_callback(char *msg, unsigned int len) 00325 { 00326 msg[len] = '\0'; 00327 printf("esp8266 driver recv%3d bytes: %s\r\n", len, msg); 00328 printf("user can add his own callback function instead\r\n"); 00329 } 00330 00331 00332 00333 00334 00335 00336 00337 00338 00339 00340 00341 00342 00343 00344 00345 00346
Generated on Thu Jul 14 2022 10:03:58 by 1.7.2