grove_esp8266

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers grove_esp8266.cpp Source File

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