Simple IoT Board用のライブラリです。 ESP8266ライブラリの軽量化 送信のみのソフトシリアルライブラリを含んでいます。
Dependents: SITB_HttpGetSample SITB_IFTTTSample SITB_INA226PRC AmbientExampleSITB ... more
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 #include "SoftSerialSendOnry.h" 00023 00024 extern SoftSerialSendOnry pc; 00025 00026 //#include <string> 00027 //#include <algorithm> 00028 00029 //Debug is disabled by default 00030 #if 0 00031 #define DBG(x, ...) pc.printf("[ESP8266 : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 00032 #define WARN(x, ...) pc.printf("[ESP8266 : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 00033 #define ERR(x, ...) pc.printf("[ESP8266 : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 00034 #else 00035 #define DBG(x, ...) //wait_us(10); 00036 #define WARN(x, ...) //wait_us(10); 00037 #define ERR(x, ...) 00038 #endif 00039 00040 #if 0 00041 #define INFO(x, ...) printf("[ESP8266 : INFO]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); 00042 #else 00043 #define INFO(x, ...) 00044 #endif 00045 00046 #define ESP_MAX_TRY_JOIN 3 00047 #define ESP_MAXID 4 // the largest possible ID Value (max num of sockets possible) 00048 00049 ESP8266 * ESP8266::inst; 00050 char* ip = NULL; 00051 00052 ESP8266::ESP8266(PinName tx, PinName rx, PinName reset, const char *ssid, const char *phrase, uint32_t baud) : 00053 wifi(tx, rx), reset_pin(reset), buf_ESP8266(ESP_MBUFFE_MAX) 00054 { 00055 INFO("Initializing ESP8266 object"); 00056 memset(&state, 0, sizeof(state)); 00057 00058 00059 strcpy(this->ssid, ssid); 00060 strcpy(this->phrase, phrase); 00061 inst = this; 00062 attach_rx(false); 00063 00064 wifi.baud(baud); // initial baud rate of the ESP8266 00065 00066 state.associated = false; 00067 state.cmdMode = false; 00068 } 00069 00070 bool ESP8266::join() 00071 { 00072 char cmd[100]; 00073 sendCommand( "AT+CWMODE=1", "change", NULL, 1000); 00074 //string cmd="AT+CWJAP=\""+(string)this->ssid+"\",\""+(string)this->phrase+"\""; 00075 sprintf(cmd,"AT+CWJAP=\"%s\",\"%s\"",this->ssid,this->phrase); 00076 if( sendCommand( cmd, "OK", NULL, 10000) ) { 00077 // successfully joined the network 00078 state.associated = true; 00079 INFO("ssid: %s, phrase: %s", this->ssid, this->phrase); 00080 return true; 00081 } 00082 return false; 00083 } 00084 00085 bool ESP8266::connect() 00086 { 00087 sendCommand("AT+CWDHCP=1,1","OK",NULL,1000); // DHCP Enabled in Station Mode 00088 return ESP8266::join(); 00089 } 00090 00091 bool ESP8266::is_connected() 00092 { 00093 return true; 00094 } 00095 00096 bool ESP8266::start(bool type,char* ip, int port, int id) 00097 { 00098 char cmd[256]; 00099 // Error Check 00100 if(id > ESP_MAXID) { 00101 ERR("startUDPMulti: max id is: %d, id given is %d",ESP_MAXID,id); 00102 return false; 00103 } 00104 // Single Connection Mode 00105 if(id < 0) { 00106 DBG("Start Single Connection Mode"); 00107 //char portstr[5]; 00108 bool check [3] = {0}; 00109 //sprintf(portstr, "%d", port); 00110 switch(type) { 00111 case ESP_UDP_TYPE : //UDP 00112 sprintf(cmd,"AT+CIPSTART=\"UDP\",\"%s\",%d",ip,port); 00113 check[0] = sendCommand(cmd, "OK", NULL, 10000); 00114 //check[0] = sendCommand(( "AT+CIPSTART=\"UDP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000); 00115 break; 00116 case ESP_TCP_TYPE : //TCP 00117 sprintf(cmd,"AT+CIPSTART=\"TCP\",\"%s\",%d",ip,port); 00118 check[0] = sendCommand(cmd, "OK", NULL, 10000); 00119 //check[0] = sendCommand(( "AT+CIPSTART=\"TCP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000); 00120 break; 00121 default: 00122 ERR("Default hit for starting connection, this shouldnt be possible!!"); 00123 break; 00124 } 00125 check[1] = sendCommand("AT+CIPMODE=1", "OK", NULL, 1000);// go into transparent mode 00126 check[2] = sendCommand("AT+CIPSEND", ">", NULL, 1000);// go into transparent mode 00127 // check that all commands were sucessful 00128 if(check[0] and check[1] and check[2]) { 00129 state.cmdMode = false; 00130 return true; 00131 } else { 00132 ERR("startUDPTransparent Failed for ip:%s, port:%d",ip,port); 00133 return false; 00134 } 00135 } 00136 // Multi Connection Mode 00137 else { 00138 //TODO: impliment Multi Connection Mode 00139 ERR("Not currently Supported!"); 00140 return false; 00141 } 00142 } 00143 00144 bool ESP8266::startUDP(char* ip, int port, int id, int length) 00145 { 00146 char cmd[256]; 00147 char portstr[5]; 00148 char idstr[1]; 00149 char lenstr[2]; 00150 00151 sprintf(portstr, "%d", port); 00152 sprintf(idstr, "%d", id); 00153 sprintf(lenstr, "%d", length); 00154 00155 sendCommand("AT+CIPMUX=1", "OK", NULL, 1000); 00156 sprintf(cmd,"AT+CIPSTART=%d,\"UDP\",\"%s\",%d,1112,0",id,ip,port); 00157 sendCommand(cmd, "OK", NULL, 10000); 00158 //sendCommand(( "AT+CIPSTART=" + string(idstr) + ",\"UDP\",\"" + (string) ip + "\"," + (string) portstr + ",1112,0").c_str(), "OK", NULL, 10000); 00159 sprintf(cmd,"AT+CIPSEND=%d,%d",id,length); 00160 sendCommand(cmd, ">", NULL, 1000);// go into transparent mode 00161 //sendCommand(("AT+CIPSEND=" + (string)idstr + "," + (string)lenstr).c_str(), ">", NULL, 1000);// go into transparent mode 00162 DBG("Data Mode\r\n"); 00163 state.cmdMode = false; 00164 00165 return true; 00166 } 00167 00168 bool ESP8266::startTCPServer(int port) 00169 { 00170 char cmd[100]; 00171 bool command_results[3]; 00172 command_results[0]=sendCommand("AT+CWMODE=3", "OK", NULL, 1000); 00173 command_results[1]=sendCommand("AT+CIPMUX=1", "OK", NULL, 1000); 00174 if(port == 333){ 00175 command_results[2]=sendCommand("AT+CIPSERVER=1", "OK", NULL, 1000); 00176 } 00177 else{ 00178 sprintf(cmd,"AT+CIPSERVER=1,%d",port); 00179 command_results[2]=sendCommand(cmd, "OK", NULL, 1000); 00180 } 00181 //sendCommand("AT+CIFSR", "OK", NULL, 1000); 00182 DBG("Data Mode\r\n"); 00183 state.cmdMode = false; 00184 if (command_results[0] and command_results[1] and command_results[2]){ 00185 return true; 00186 } 00187 else{ 00188 return false; 00189 } 00190 } 00191 00192 bool ESP8266::close() 00193 { 00194 wait(0.1f); 00195 send("+++",3); 00196 wait(1.0f); 00197 state.cmdMode = true; 00198 sendCommand("AT+CIPCLOSE","OK", NULL, 10000); 00199 return true; 00200 } 00201 00202 bool ESP8266::disconnect() 00203 { 00204 // if already disconnected, return 00205 if (!state.associated) 00206 return true; 00207 // send command to quit AP 00208 sendCommand("AT+CWQAP", "OK", NULL, 10000); 00209 state.associated = false; 00210 return true; 00211 } 00212 00213 int ESP8266::strfind(const char *str,const char *chkstr,int pos) 00214 { 00215 if( (strlen(str)-pos) < strlen(chkstr) ) return(-1); 00216 00217 00218 for(int i=pos;i<strlen(str);i++) 00219 { 00220 if(memcmp(chkstr,&str[i],strlen(chkstr))==0) 00221 { 00222 return(i); 00223 } 00224 } 00225 return(-1); 00226 } 00227 00228 char* ESP8266::substr(const char *str , char *outstr , int pos1 , int pos2 ) 00229 { 00230 int size = pos2 - pos1; 00231 00232 memcpy(outstr , &str[pos1] , size ); 00233 outstr[size] = '\0'; 00234 00235 return(outstr); 00236 } 00237 00238 int ESP8266::strcount(const char *str , char countstr ) 00239 { 00240 int ret = 0; 00241 00242 for(int i = 0 ; i < strlen(str) ; i++) 00243 { 00244 if( str[i] == countstr ) 00245 { 00246 ret++; 00247 } 00248 00249 } 00250 00251 return(ret); 00252 } 00253 00254 /* 00255 Assuming Returned data looks like this: 00256 +CIFSR:STAIP,"192.168.11.2" 00257 +CIFSR:STAMAC,"18:fe:34:9f:3a:f5" 00258 grabbing IP from first set of quotation marks 00259 */ 00260 char* ESP8266::getIPAddress() 00261 { 00262 char result[30] = {0}; 00263 char tmp[30] = {0}; 00264 int check = 0; 00265 check = sendCommand("AT+CIFSR", NULL, result, 1000); 00266 //pc.printf("\r\nReceivedInfo for IP Command is: %s\r\n",result); 00267 ip = ipString; 00268 if(check) { 00269 // Success 00270 uint8_t pos1 = 0, pos2 = 0; 00271 //uint8_t pos3 = 0, pos4 = 0; 00272 pos1 = strfind(result,"+CIFSR:STAIP",0); 00273 //pos1 = resultString.find("+CIFSR:STAIP"); 00274 pos1 = strfind(result,"\"",pos1); 00275 //pos1 = resultString.find('"',pos1); 00276 pos2 = strfind(result,"\"",pos1+1); 00277 //pos2 = resultString.find('"',pos1+1); 00278 //pos3 = resultString.find('"',pos2+1); //would find mac address 00279 //pos4 = resultString.find('"',pos3+1); 00280 strncpy(ipString,substr(result,tmp,pos1,pos2),sizeof(ipString)); 00281 INFO("IP: %s",ipString); 00282 ip = ipString; 00283 00284 } else { 00285 // Failure 00286 ERR("getIPAddress() failed"); 00287 ip = NULL; 00288 } 00289 return ip; 00290 } 00291 00292 bool ESP8266::gethostbyname(const char * host, char * ip) 00293 { 00294 int nb_digits = 0; 00295 char tmp[100]; 00296 00297 strcpy(ip,host); 00298 00299 return true; 00300 00301 // no dns needed 00302 int pos = strfind(host,".",0); 00303 if (pos != -1) { 00304 nb_digits = atoi(substr(host,tmp,0,pos)); 00305 } 00306 //printf("substrL %s\r\n", sub.c_str()); 00307 if (strcount(host,'.') == 3 && nb_digits > 0) { 00308 strcpy(ip, host); 00309 return true; 00310 } else { 00311 // dns needed, not currently available 00312 ERR("gethostbyname(): DNS Not currently available, only use IP Addresses!"); 00313 return false; 00314 } 00315 } 00316 00317 void ESP8266::reset() 00318 { 00319 reset_pin = 0; 00320 wait_us(20); 00321 reset_pin = 1; 00322 //wait(1); 00323 //reset_pin = !reset_pin 00324 //send("+++",3); 00325 wait(1); 00326 state.cmdMode = true; 00327 sendCommand("AT", "OK", NULL, 1000); 00328 sendCommand("AT+RST", "ready", NULL, 10000); 00329 state.associated = false; 00330 00331 } 00332 00333 bool ESP8266::reboot() 00334 { 00335 reset(); 00336 return true; 00337 } 00338 00339 void ESP8266::handler_rx(void) 00340 { 00341 //read characters 00342 char c; 00343 while (wifi.readable()) { 00344 c=wifi.getc(); 00345 buf_ESP8266.queue(c); 00346 //if (state.cmdMode) pc.printf("%c",c); //debug echo, needs fast serial console to prevent UART overruns 00347 } 00348 } 00349 00350 void ESP8266::attach_rx(bool callback) 00351 { 00352 if (!callback) { 00353 wifi.attach(NULL); 00354 } 00355 else { 00356 wifi.attach(this, &ESP8266::handler_rx); 00357 } 00358 } 00359 00360 int ESP8266::readable() 00361 { 00362 return buf_ESP8266.available(); 00363 } 00364 00365 int ESP8266::writeable() 00366 { 00367 return wifi.writeable(); 00368 } 00369 00370 char ESP8266::getc() 00371 { 00372 char c=0; 00373 while (!buf_ESP8266.available()); 00374 buf_ESP8266.dequeue(&c); 00375 return c; 00376 } 00377 00378 int ESP8266::putc(char c) 00379 { 00380 while (!wifi.writeable() || wifi.readable()); //wait for echoed command characters to be read first 00381 return wifi.putc(c); 00382 } 00383 00384 void ESP8266::flush() 00385 { 00386 buf_ESP8266.flush(); 00387 } 00388 00389 int ESP8266::send(const char * buf, int len) 00390 { 00391 //TODO: need to add handler for data > 2048B, this is the max packet size of the ESP8266. 00392 if(len >= 2048){ 00393 WARN("send buffer >= 2048B, need to chunk this up to be less."); 00394 } 00395 const char* bufptr=buf; 00396 for(int i=0; i<len; i++) { 00397 putc((int)*bufptr++); 00398 } 00399 return len; 00400 } 00401 00402 bool ESP8266::sendCommand(const char * cmd, const char * ACK, char * res, int timeout) 00403 { 00404 char read; 00405 char checking[512] = ""; 00406 int checking_size = 0; 00407 int fond = -1; 00408 Timer tmr; 00409 int result = 0; 00410 00411 DBG("sendCmd:\t %s",cmd); 00412 00413 attach_rx(true); 00414 00415 //We flush the buffer 00416 while (readable()) 00417 getc(); 00418 00419 if (!ACK || !strcmp(ACK, "NO")) { 00420 for (int i = 0; i < strlen(cmd); i++) { 00421 result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result; 00422 wait(0.005f); // prevents stuck recieve ready (?) need to let echoed character get read first 00423 } 00424 putc(13); //CR 00425 wait(0.005f); // wait for echo 00426 putc(10); //LF 00427 00428 } else { 00429 //We flush the buffer 00430 while (readable()) 00431 getc(); 00432 00433 tmr.start(); 00434 for (int i = 0; i < strlen(cmd); i++) { 00435 result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result; 00436 wait(.005); // wait for echo 00437 } 00438 putc(13); //CR 00439 wait(0.005f); // wait for echo 00440 putc(10); //LF 00441 00442 while (1) { 00443 if (tmr.read_ms() > timeout) { 00444 //We flush the buffer 00445 while (readable()) 00446 getc(); 00447 00448 DBG("check:\t %s", checking); 00449 00450 attach_rx(true); 00451 return -1; 00452 } else if (readable()) { 00453 read = getc(); 00454 //pc.printf("%c",read); //debug echo 00455 if ( read != '\r' && read != '\n') { 00456 checking[checking_size] = read; 00457 checking_size++; 00458 checking[checking_size] = '\0'; 00459 fond = strfind(checking,ACK,0); 00460 if (fond != -1) { 00461 wait(0.01f); 00462 00463 //We flush the buffer 00464 while (readable()) 00465 read = getc(); 00466 //printf("%c",read); //debug echo 00467 break; 00468 } 00469 } 00470 } 00471 } 00472 DBG("check: %s", checking); 00473 00474 attach_rx(true); 00475 return result; 00476 } 00477 00478 //the user wants the result from the command (ACK == NULL, res != NULL) 00479 if (res != NULL) { 00480 int i = 0; 00481 Timer timeout; 00482 timeout.start(); 00483 tmr.reset(); 00484 while (1) { 00485 if (timeout.read() > 2) { 00486 if (i == 0) { 00487 res = NULL; 00488 break; 00489 } 00490 res[i] = '\0'; 00491 DBG("user str 1: %s", res); 00492 00493 break; 00494 } else { 00495 if (tmr.read_ms() > 300) { 00496 res[i] = '\0'; 00497 DBG("user str: %s", res); 00498 00499 break; 00500 } 00501 if (readable()) { 00502 tmr.start(); 00503 read = getc(); 00504 00505 // we drop \r and \n 00506 if ( read != '\r' && read != '\n') { 00507 res[i++] = read; 00508 } 00509 } 00510 } 00511 } 00512 DBG("user str: %s", res); 00513 } 00514 00515 //We flush the buffer 00516 while (readable()) 00517 getc(); 00518 00519 attach_rx(true); 00520 DBG("result: %d", result) 00521 return result; 00522 }
Generated on Tue Jul 12 2022 18:13:35 by 1.7.2