モータードライバとWi-FiモジュールESP-WROOM-02をmbed LPC1114FN28に繋げて、RCWControllerからコントロールするプログラム
Dependencies: mbed
ESP8266.cpp
00001 /* Copyright (C) 2012 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00005 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00006 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00007 * furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "mbed.h" 00020 #include "ESP8266.h" 00021 #include "Endpoint.h" 00022 00023 //#include <string> 00024 //#include <algorithm> 00025 #include "SoftSerialSendOnry.h" 00026 00027 extern SoftSerialSendOnry pc; 00028 //Debug is disabled by default 00029 #if 0 00030 #define DBG(x, ...) pc.printf("[ESP8266 : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 00031 #define WARN(x, ...) pc.printf("[ESP8266 : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 00032 #define ERR(x, ...) pc.printf("[ESP8266 : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 00033 #else 00034 #define DBG(x, ...) //wait_us(10); 00035 #define WARN(x, ...) //wait_us(10); 00036 #define ERR(x, ...) 00037 #endif 00038 00039 #if 0 00040 #define INFO(x, ...) printf("[ESP8266 : INFO]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 00041 #else 00042 #define INFO(x, ...) 00043 #endif 00044 00045 #define ESP_MAX_TRY_JOIN 3 00046 #define ESP_MAXID 4 // the largest possible ID Value (max num of sockets possible) 00047 00048 ESP8266 * ESP8266::inst; 00049 char* ip = NULL; 00050 00051 ESP8266::ESP8266(PinName tx, PinName rx, PinName reset, const char *ssid, const char *phrase, uint32_t baud) : 00052 wifi(tx, rx), reset_pin(reset), buf_ESP8266(ESP_MBUFFE_MAX) 00053 { 00054 INFO("Initializing ESP8266 object"); 00055 memset(&state, 0, sizeof(state)); 00056 00057 00058 strcpy(this->ssid, ssid); 00059 strcpy(this->phrase, phrase); 00060 inst = this; 00061 attach_rx(false); 00062 00063 wifi.baud(baud); // initial baud rate of the ESP8266 00064 00065 state.associated = false; 00066 state.cmdMode = false; 00067 } 00068 00069 bool ESP8266::join() 00070 { 00071 char cmd[100]; 00072 sendCommand( "AT+CWMODE=1", "change", NULL, 1000); 00073 //string cmd="AT+CWJAP=\""+(string)this->ssid+"\",\""+(string)this->phrase+"\""; 00074 sprintf(cmd,"AT+CWJAP=\"%s\",\"%s\"",this->ssid,this->phrase); 00075 if( sendCommand( cmd, "OK", NULL, 10000) ) { 00076 // successfully joined the network 00077 state.associated = true; 00078 INFO("ssid: %s, phrase: %s", this->ssid, this->phrase); 00079 return true; 00080 } 00081 return false; 00082 } 00083 00084 bool ESP8266::single_ap() 00085 { 00086 char cmd[100]; 00087 sendCommand( "AT+CWMODE=2", "change", NULL, 1000); 00088 //string cmd="AT+CWJAP=\""+(string)this->ssid+"\",\""+(string)this->phrase+"\""; 00089 sprintf(cmd,"AT+CWSAP=\"%s\",\"%s\",11,3",this->ssid,this->phrase); 00090 if( sendCommand( cmd, "OK", NULL, 10000) ) { 00091 // successfully joined the network 00092 state.associated = true; 00093 INFO("ssid: %s, phrase: %s", this->ssid, this->phrase); 00094 wait(1); 00095 // Enable DHCP 00096 sendCommand("AT+CWDHCP=0,1","OK",NULL,1000); 00097 wait(1); 00098 return true; 00099 } 00100 return false; 00101 } 00102 00103 bool ESP8266::connect() 00104 { 00105 sendCommand("AT+CWDHCP=1,1","OK",NULL,1000); // DHCP Enabled in Station Mode 00106 return ESP8266::join(); 00107 } 00108 00109 bool ESP8266::is_connected() 00110 { 00111 return true; 00112 } 00113 00114 bool ESP8266::start(bool type,char* ip, int port, int id) 00115 { 00116 char cmd[256]; 00117 // Error Check 00118 if(id > ESP_MAXID) { 00119 ERR("startUDPMulti: max id is: %d, id given is %d",ESP_MAXID,id); 00120 return false; 00121 } 00122 // Single Connection Mode 00123 if(id < 0) { 00124 DBG("Start Single Connection Mode"); 00125 //char portstr[5]; 00126 bool check [3] = {0}; 00127 //sprintf(portstr, "%d", port); 00128 switch(type) { 00129 case ESP_UDP_TYPE : //UDP 00130 sprintf(cmd,"AT+CIPSTART=\"UDP\",\"%s\",%d,%d,0",ip,port,port+1); 00131 pc.printf("%s\r\n",cmd); 00132 check[0] = sendCommand(cmd, "OK", NULL, 10000); 00133 //check[0] = sendCommand(( "AT+CIPSTART=\"UDP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000); 00134 break; 00135 case ESP_TCP_TYPE : //TCP 00136 sprintf(cmd,"AT+CIPSTART=\"TCP\",\"%s\",%d",ip,port); 00137 check[0] = sendCommand(cmd, "OK", NULL, 10000); 00138 //check[0] = sendCommand(( "AT+CIPSTART=\"TCP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000); 00139 break; 00140 default: 00141 ERR("Default hit for starting connection, this shouldnt be possible!!"); 00142 break; 00143 } 00144 check[1] = sendCommand("AT+CIPMODE=1", "OK", NULL, 1000);// go into transparent mode 00145 check[2] = sendCommand("AT+CIPSEND", ">", NULL, 1000);// go into transparent mode 00146 // check that all commands were sucessful 00147 if(check[0] and check[1] and check[2]) { 00148 state.cmdMode = false; 00149 return true; 00150 } else { 00151 ERR("startUDPTransparent Failed for ip:%s, port:%d",ip,port); 00152 return false; 00153 } 00154 } 00155 // Multi Connection Mode 00156 else { 00157 //TODO: impliment Multi Connection Mode 00158 ERR("Not currently Supported!"); 00159 return false; 00160 } 00161 } 00162 00163 bool ESP8266::startUDP(char* ip, int port, int id, int length) 00164 { 00165 char cmd[256]; 00166 char portstr[5]; 00167 char idstr[1]; 00168 char lenstr[2]; 00169 00170 sprintf(portstr, "%d", port); 00171 sprintf(idstr, "%d", id); 00172 sprintf(lenstr, "%d", length); 00173 00174 sendCommand("AT+CIPMUX=1", "OK", NULL, 1000); 00175 sprintf(cmd,"AT+CIPSTART=%d,\"UDP\",\"%s\",%d,1112,0",id,ip,port); 00176 sendCommand(cmd, "OK", NULL, 10000); 00177 //sendCommand(( "AT+CIPSTART=" + string(idstr) + ",\"UDP\",\"" + (string) ip + "\"," + (string) portstr + ",1112,0").c_str(), "OK", NULL, 10000); 00178 sprintf(cmd,"AT+CIPSEND=%d,%d",id,length); 00179 sendCommand(cmd, ">", NULL, 1000);// go into transparent mode 00180 //sendCommand(("AT+CIPSEND=" + (string)idstr + "," + (string)lenstr).c_str(), ">", NULL, 1000);// go into transparent mode 00181 DBG("Data Mode\r\n"); 00182 state.cmdMode = false; 00183 00184 return true; 00185 } 00186 00187 bool ESP8266::startTCPServer(int port) 00188 { 00189 char cmd[100]; 00190 bool command_results[3]; 00191 command_results[0]=sendCommand("AT+CWMODE=3", "OK", NULL, 1000); 00192 command_results[1]=sendCommand("AT+CIPMUX=1", "OK", NULL, 1000); 00193 if(port == 333){ 00194 command_results[2]=sendCommand("AT+CIPSERVER=1", "OK", NULL, 1000); 00195 } 00196 else{ 00197 sprintf(cmd,"AT+CIPSERVER=1,%d",port); 00198 command_results[2]=sendCommand(cmd, "OK", NULL, 1000); 00199 } 00200 //sendCommand("AT+CIFSR", "OK", NULL, 1000); 00201 DBG("Data Mode\r\n"); 00202 state.cmdMode = false; 00203 if (command_results[0] and command_results[1] and command_results[2]){ 00204 return true; 00205 } 00206 else{ 00207 return false; 00208 } 00209 } 00210 00211 bool ESP8266::close() 00212 { 00213 wait(0.1f); 00214 send("+++",3); 00215 wait(1.0f); 00216 state.cmdMode = true; 00217 sendCommand("AT+CIPCLOSE","OK", NULL, 10000); 00218 return true; 00219 } 00220 00221 bool ESP8266::disconnect() 00222 { 00223 // if already disconnected, return 00224 if (!state.associated) 00225 return true; 00226 // send command to quit AP 00227 sendCommand("AT+CWQAP", "OK", NULL, 10000); 00228 state.associated = false; 00229 return true; 00230 } 00231 00232 int ESP8266::strfind(const char *str,const char *chkstr,int pos) 00233 { 00234 if( (strlen(str)-pos) < strlen(chkstr) ) return(-1); 00235 00236 00237 for(int i=pos;i<strlen(str);i++) 00238 { 00239 if(memcmp(chkstr,&str[i],strlen(chkstr))==0) 00240 { 00241 return(i); 00242 } 00243 } 00244 return(-1); 00245 } 00246 00247 char* ESP8266::substr(const char *str , char *outstr , int pos1 , int pos2 ) 00248 { 00249 int size = pos2 - pos1; 00250 00251 memcpy(outstr , &str[pos1] , size ); 00252 outstr[size] = '\0'; 00253 00254 return(outstr); 00255 } 00256 00257 int ESP8266::strcount(const char *str , char countstr ) 00258 { 00259 int ret = 0; 00260 00261 for(int i = 0 ; i < strlen(str) ; i++) 00262 { 00263 if( str[i] == countstr ) 00264 { 00265 ret++; 00266 } 00267 00268 } 00269 00270 return(ret); 00271 } 00272 00273 /* 00274 Assuming Returned data looks like this: 00275 +CIFSR:STAIP,"192.168.11.2" 00276 +CIFSR:STAMAC,"18:fe:34:9f:3a:f5" 00277 grabbing IP from first set of quotation marks 00278 */ 00279 char* ESP8266::getIPAddress() 00280 { 00281 char result[80] = {0}; 00282 char tmp[30] = {0}; 00283 int check = 0; 00284 check = sendCommand("AT+CIFSR", NULL, result, 1000); 00285 pc.printf("\r\nReceivedInfo for IP Command is: %s\r\n",result); 00286 ip = ipString; 00287 if(check) { 00288 // Success 00289 uint8_t pos1 = 0, pos2 = 0; 00290 //uint8_t pos3 = 0, pos4 = 0; 00291 //pos1 = strfind(result,"+CIFSR:STAIP",0); 00292 pos1 = strfind(result,"+CIFSR:APIP",0); 00293 //pos1 = resultString.find("+CIFSR:STAIP"); 00294 pos1 = strfind(result,"\"",pos1); 00295 //pos1 = resultString.find('"',pos1); 00296 pos2 = strfind(result,"\"",pos1+1); 00297 //pos2 = resultString.find('"',pos1+1); 00298 //pos3 = resultString.find('"',pos2+1); //would find mac address 00299 //pos4 = resultString.find('"',pos3+1); 00300 strncpy(ipString,substr(result,tmp,pos1+1,pos2),sizeof(ipString)); 00301 ipString[pos2 - pos1 +1] = 0; // null terminate string correctly. 00302 INFO("IP: %s",ipString); 00303 ip = ipString; 00304 00305 } else { 00306 // Failure 00307 ERR("getIPAddress() failed"); 00308 ip = NULL; 00309 } 00310 return ip; 00311 } 00312 00313 bool ESP8266::gethostbyname(const char * host, char * ip) 00314 { 00315 int nb_digits = 0; 00316 char tmp[100]; 00317 00318 strcpy(ip,host); 00319 00320 return true; 00321 #if 0 00322 // no dns needed 00323 int pos = strfind(host,".",0); 00324 if (pos != -1) { 00325 nb_digits = atoi(substr(host,tmp,0,pos)); 00326 } 00327 //printf("substrL %s\r\n", sub.c_str()); 00328 if (strcount(host,'.') == 3 && nb_digits > 0) { 00329 strcpy(ip, host); 00330 return true; 00331 } else { 00332 // dns needed, not currently available 00333 ERR("gethostbyname(): DNS Not currently available, only use IP Addresses!"); 00334 return false; 00335 } 00336 #endif 00337 } 00338 00339 void ESP8266::reset() 00340 { 00341 reset_pin = 0; 00342 wait_us(20); 00343 reset_pin = 1; 00344 //wait(1); 00345 //reset_pin = !reset_pin 00346 //send("+++",3); 00347 wait(1); 00348 state.cmdMode = true; 00349 sendCommand("AT", "OK", NULL, 1000); 00350 sendCommand("AT+RST", "ready", NULL, 10000); 00351 state.associated = false; 00352 00353 } 00354 00355 bool ESP8266::reboot() 00356 { 00357 reset(); 00358 return true; 00359 } 00360 00361 void ESP8266::handler_rx(void) 00362 { 00363 //read characters 00364 char c; 00365 while (wifi.readable()) { 00366 c=wifi.getc(); 00367 buf_ESP8266.queue(c); 00368 //if (state.cmdMode) pc.printf("%c",c); //debug echo, needs fast serial console to prevent UART overruns 00369 } 00370 } 00371 00372 void ESP8266::attach_rx(bool callback) 00373 { 00374 if (!callback) { 00375 wifi.attach(NULL); 00376 } 00377 else { 00378 wifi.attach(this, &ESP8266::handler_rx); 00379 } 00380 } 00381 00382 int ESP8266::readable() 00383 { 00384 return buf_ESP8266.available(); 00385 } 00386 00387 int ESP8266::writeable() 00388 { 00389 return wifi.writeable(); 00390 } 00391 00392 char ESP8266::getc() 00393 { 00394 char c=0; 00395 while (!buf_ESP8266.available()); 00396 buf_ESP8266.dequeue(&c); 00397 return c; 00398 } 00399 00400 int ESP8266::putc(char c) 00401 { 00402 while (!wifi.writeable() || wifi.readable()); //wait for echoed command characters to be read first 00403 return wifi.putc(c); 00404 } 00405 00406 void ESP8266::flush() 00407 { 00408 buf_ESP8266.flush(); 00409 } 00410 00411 int ESP8266::send(const char * buf, int len) 00412 { 00413 //TODO: need to add handler for data > 2048B, this is the max packet size of the ESP8266. 00414 if(len >= 2048){ 00415 WARN("send buffer >= 2048B, need to chunk this up to be less."); 00416 } 00417 const char* bufptr=buf; 00418 for(int i=0; i<len; i++) { 00419 putc((int)*bufptr++); 00420 } 00421 return len; 00422 } 00423 00424 bool ESP8266::sendCommand(const char * cmd, const char * ACK, char * res, int timeout) 00425 { 00426 char read; 00427 char checking[512] = ""; 00428 int checking_size = 0; 00429 int fond = -1; 00430 Timer tmr; 00431 int result = 0; 00432 00433 DBG("sendCmd:\t %s",cmd); 00434 00435 attach_rx(true); 00436 00437 //We flush the buffer 00438 while (readable()) 00439 getc(); 00440 00441 if (!ACK || !strcmp(ACK, "NO")) { 00442 for (int i = 0; i < strlen(cmd); i++) { 00443 result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result; 00444 wait(0.005f); // prevents stuck recieve ready (?) need to let echoed character get read first 00445 } 00446 putc(13); //CR 00447 wait(0.005f); // wait for echo 00448 putc(10); //LF 00449 00450 } else { 00451 //We flush the buffer 00452 while (readable()) 00453 getc(); 00454 00455 tmr.start(); 00456 for (int i = 0; i < strlen(cmd); i++) { 00457 result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result; 00458 wait(.005); // wait for echo 00459 } 00460 putc(13); //CR 00461 wait(0.005f); // wait for echo 00462 putc(10); //LF 00463 00464 while (1) { 00465 if (tmr.read_ms() > timeout) { 00466 //We flush the buffer 00467 while (readable()) 00468 getc(); 00469 00470 DBG("check:\t %s", checking); 00471 00472 attach_rx(true); 00473 return -1; 00474 } else if (readable()) { 00475 read = getc(); 00476 //pc.printf("%c",read); //debug echo 00477 if ( read != '\r' && read != '\n') { 00478 checking[checking_size] = read; 00479 checking_size++; 00480 checking[checking_size] = '\0'; 00481 fond = strfind(checking,ACK,0); 00482 if (fond != -1) { 00483 wait(0.01f); 00484 00485 //We flush the buffer 00486 while (readable()) 00487 read = getc(); 00488 //printf("%c",read); //debug echo 00489 break; 00490 } 00491 } 00492 } 00493 } 00494 DBG("check: %s", checking); 00495 00496 attach_rx(true); 00497 return result; 00498 } 00499 00500 //the user wants the result from the command (ACK == NULL, res != NULL) 00501 if (res != NULL) { 00502 int i = 0; 00503 Timer timeout; 00504 timeout.start(); 00505 tmr.reset(); 00506 while (1) { 00507 if (timeout.read() > 2) { 00508 if (i == 0) { 00509 res = NULL; 00510 break; 00511 } 00512 res[i] = '\0'; 00513 DBG("user str 1: %s", res); 00514 00515 break; 00516 } else { 00517 if (tmr.read_ms() > 300) { 00518 res[i] = '\0'; 00519 DBG("user str: %s", res); 00520 00521 break; 00522 } 00523 if (readable()) { 00524 tmr.start(); 00525 read = getc(); 00526 00527 // we drop \r and \n 00528 if ( read != '\r' && read != '\n') { 00529 res[i++] = read; 00530 } 00531 } 00532 } 00533 } 00534 DBG("user str: %s", res); 00535 } 00536 00537 //We flush the buffer 00538 while (readable()) 00539 getc(); 00540 00541 attach_rx(true); 00542 DBG("result: %d", result) 00543 return result; 00544 }
Generated on Sat Jul 16 2022 20:39:12 by 1.7.2