Provide an easy-to-use way to manipulate ESP8266.
Dependents: WeeESP8266_TCPClientMultiple WeeESP8266_TCPClientSingle WeeESP8266_TCPServer WeeESP8266_UDPClientMultiple ... more
ESP8266.cpp
00001 /** 00002 * @file ESP8266.cpp 00003 * @brief The implementation of class ESP8266. 00004 * @author Wu Pengfei<pengfei.wu@itead.cc> 00005 * @date 2015.02 00006 * 00007 * @par Copyright: 00008 * Copyright (c) 2015 ITEAD Intelligent Systems Co., Ltd. \n\n 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License as 00011 * published by the Free Software Foundation; either version 2 of 00012 * the License, or (at your option) any later version. \n\n 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00014 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00015 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00016 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00017 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00018 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00019 * THE SOFTWARE. 00020 */ 00021 #include "ESP8266.h" 00022 #include "log.h" 00023 00024 ESP8266::ESP8266(ArduinoSerial &uart): m_puart(&uart) 00025 { 00026 m_puart->begin(9600); 00027 m_puart->flush(); 00028 } 00029 00030 00031 bool ESP8266::kick(void) 00032 { 00033 return eAT(); 00034 } 00035 00036 bool ESP8266::restart(void) 00037 { 00038 unsigned long start; 00039 if (eATRST()) { 00040 delay(2000); 00041 start = millis(); 00042 while (millis() - start < 3000) { 00043 if (eAT()) { 00044 delay(1500); /* Waiting for stable */ 00045 return true; 00046 } 00047 delay(100); 00048 } 00049 } 00050 return false; 00051 } 00052 00053 String ESP8266::getVersion(void) 00054 { 00055 String version; 00056 eATGMR(version); 00057 return version; 00058 } 00059 00060 bool ESP8266::setOprToStation(void) 00061 { 00062 uint8_t mode; 00063 if (!qATCWMODE(&mode)) { 00064 return false; 00065 } 00066 if (mode == 1) { 00067 return true; 00068 } else { 00069 if (sATCWMODE(1) && restart()) { 00070 return true; 00071 } else { 00072 return false; 00073 } 00074 } 00075 } 00076 00077 bool ESP8266::setOprToSoftAP(void) 00078 { 00079 uint8_t mode; 00080 if (!qATCWMODE(&mode)) { 00081 return false; 00082 } 00083 if (mode == 2) { 00084 return true; 00085 } else { 00086 if (sATCWMODE(2) && restart()) { 00087 return true; 00088 } else { 00089 return false; 00090 } 00091 } 00092 } 00093 00094 bool ESP8266::setOprToStationSoftAP(void) 00095 { 00096 uint8_t mode; 00097 if (!qATCWMODE(&mode)) { 00098 return false; 00099 } 00100 if (mode == 3) { 00101 return true; 00102 } else { 00103 if (sATCWMODE(3) && restart()) { 00104 return true; 00105 } else { 00106 return false; 00107 } 00108 } 00109 } 00110 00111 String ESP8266::getAPList(void) 00112 { 00113 String list; 00114 eATCWLAP(list); 00115 return list; 00116 } 00117 00118 bool ESP8266::joinAP(String ssid, String pwd) 00119 { 00120 return sATCWJAP(ssid, pwd); 00121 } 00122 00123 bool ESP8266::leaveAP(void) 00124 { 00125 return eATCWQAP(); 00126 } 00127 00128 bool ESP8266::setSoftAPParam(String ssid, String pwd, uint8_t chl, uint8_t ecn) 00129 { 00130 return sATCWSAP(ssid, pwd, chl, ecn); 00131 } 00132 00133 String ESP8266::getJoinedDeviceIP(void) 00134 { 00135 String list; 00136 eATCWLIF(list); 00137 return list; 00138 } 00139 00140 String ESP8266::getIPStatus(void) 00141 { 00142 String list; 00143 eATCIPSTATUS(list); 00144 return list; 00145 } 00146 00147 String ESP8266::getLocalIP(void) 00148 { 00149 String list; 00150 eATCIFSR(list); 00151 return list; 00152 } 00153 00154 bool ESP8266::enableMUX(void) 00155 { 00156 return sATCIPMUX(1); 00157 } 00158 00159 bool ESP8266::disableMUX(void) 00160 { 00161 return sATCIPMUX(0); 00162 } 00163 00164 bool ESP8266::createTCP(String addr, uint32_t port) 00165 { 00166 return sATCIPSTARTSingle("TCP", addr, port); 00167 } 00168 00169 bool ESP8266::releaseTCP(void) 00170 { 00171 return eATCIPCLOSESingle(); 00172 } 00173 00174 bool ESP8266::registerUDP(String addr, uint32_t port) 00175 { 00176 return sATCIPSTARTSingle("UDP", addr, port); 00177 } 00178 00179 bool ESP8266::unregisterUDP(void) 00180 { 00181 return eATCIPCLOSESingle(); 00182 } 00183 00184 bool ESP8266::createTCP(uint8_t mux_id, String addr, uint32_t port) 00185 { 00186 return sATCIPSTARTMultiple(mux_id, "TCP", addr, port); 00187 } 00188 00189 bool ESP8266::releaseTCP(uint8_t mux_id) 00190 { 00191 return sATCIPCLOSEMulitple(mux_id); 00192 } 00193 00194 bool ESP8266::registerUDP(uint8_t mux_id, String addr, uint32_t port) 00195 { 00196 return sATCIPSTARTMultiple(mux_id, "UDP", addr, port); 00197 } 00198 00199 bool ESP8266::unregisterUDP(uint8_t mux_id) 00200 { 00201 return sATCIPCLOSEMulitple(mux_id); 00202 } 00203 00204 bool ESP8266::setTCPServerTimeout(uint32_t timeout) 00205 { 00206 return sATCIPSTO(timeout); 00207 } 00208 00209 bool ESP8266::startTCPServer(uint32_t port) 00210 { 00211 if (sATCIPSERVER(1, port)) { 00212 return true; 00213 } 00214 return false; 00215 } 00216 00217 bool ESP8266::stopTCPServer(void) 00218 { 00219 sATCIPSERVER(0); 00220 restart(); 00221 return false; 00222 } 00223 00224 bool ESP8266::send(const uint8_t *buffer, uint32_t len) 00225 { 00226 return sATCIPSENDSingle(buffer, len); 00227 } 00228 00229 bool ESP8266::send(uint8_t mux_id, const uint8_t *buffer, uint32_t len) 00230 { 00231 return sATCIPSENDMultiple(mux_id, buffer, len); 00232 } 00233 00234 uint32_t ESP8266::recv(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout) 00235 { 00236 return recvPkg(buffer, buffer_size, NULL, timeout, NULL); 00237 } 00238 00239 uint32_t ESP8266::recv(uint8_t mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout) 00240 { 00241 uint8_t id; 00242 uint32_t ret; 00243 ret = recvPkg(buffer, buffer_size, NULL, timeout, &id); 00244 if (ret > 0 && id == mux_id) { 00245 return ret; 00246 } 00247 return 0; 00248 } 00249 00250 uint32_t ESP8266::recv(uint8_t *coming_mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout) 00251 { 00252 return recvPkg(buffer, buffer_size, NULL, timeout, coming_mux_id); 00253 } 00254 00255 /*----------------------------------------------------------------------------*/ 00256 00257 uint32_t ESP8266::recvPkg(uint8_t *buffer, uint32_t buffer_size, uint32_t *data_len, uint32_t timeout, uint8_t *coming_mux_id) 00258 { 00259 String data; 00260 char a; 00261 int32_t index_PIPDcomma = -1; 00262 int32_t index_colon = -1; /* : */ 00263 int32_t index_comma = -1; /* , */ 00264 int32_t len = -1; 00265 int8_t id = -1; 00266 bool has_data = false; 00267 logDebug("start recv pkg"); 00268 00269 unsigned long start = millis(); 00270 while (millis() - start < timeout) { 00271 while(m_puart->available() > 0) { 00272 a = m_puart->readChr(); 00273 data += a; 00274 } 00275 00276 index_PIPDcomma = data.indexOf("+IPD,"); 00277 if (index_PIPDcomma != -1) { 00278 logDebug("index_PIPDcomma found = %d", index_PIPDcomma); 00279 index_colon = data.indexOf(':', index_PIPDcomma + 5); 00280 if (index_colon != -1) { 00281 logDebug("data1 = %s\r\n", data.c_str()); 00282 logDebug("index_colon found = %d", index_colon); 00283 00284 index_comma = data.indexOf(',', index_PIPDcomma + 5); 00285 logDebug("index_comma found = %d", index_comma); 00286 00287 if (index_comma != -1 && index_comma < index_colon) { /* +IPD,id,len:data */ 00288 logDebug("id = %d", id); 00289 id = data.substring(index_PIPDcomma + 5, index_comma).toInt(); 00290 logDebug("id = %d", id); 00291 if (id < 0 || id > 4) { 00292 return 0; 00293 } 00294 logDebug("len = %d", len); 00295 len = data.substring(index_comma + 1, index_colon).toInt(); 00296 logDebug("len = %d", len); 00297 if (len <= 0) { 00298 return 0; 00299 } 00300 logDebug("has id"); 00301 } else { /* +IPD,len:data */ 00302 len = data.substring(index_PIPDcomma + 5, index_colon).toInt(); 00303 logDebug("len = %d", len); 00304 if (len <= 0) { 00305 return 0; 00306 } 00307 logDebug("no id"); 00308 } 00309 has_data = true; 00310 logDebug("has_data true"); 00311 break; 00312 } 00313 } 00314 } 00315 //logDebug("has_data = %u\r\n", has_data); 00316 //logDebug("data2 = %s\r\n", data.c_str()); 00317 00318 if (has_data) { 00319 start = millis(); 00320 while (millis() - start < 3000) { 00321 while(m_puart->available() > 0) { 00322 a = m_puart->readChr(); 00323 data += a; 00324 } 00325 //logDebug("data3 = %s\r\n", data.c_str()); 00326 if (data.length() >= index_colon + 1 + len) { 00327 if (data_len) { 00328 *data_len = len; 00329 } 00330 if (index_comma != -1 && coming_mux_id) { 00331 *coming_mux_id = id; 00332 } 00333 //logDebug("len = %d", len); 00334 //logDebug("buffer_size = %d", buffer_size); 00335 uint32_t ret = len > buffer_size ? buffer_size : len; 00336 00337 memcpy(buffer, 00338 data.substring(index_colon + 1, index_colon + 1 + len).c_str(), 00339 ret); 00340 logDebug("ret = %u\r\n", ret); 00341 return ret; 00342 } 00343 } 00344 } 00345 logDebug("end recv pkg"); 00346 return 0; 00347 } 00348 00349 String ESP8266::recvString(String target, uint32_t timeout) 00350 { 00351 String data; 00352 char a; 00353 unsigned long start = millis(); 00354 while (millis() - start < timeout) { 00355 while(m_puart->available() > 0) { 00356 a = m_puart->readChr(); 00357 data += a; 00358 } 00359 if (data.indexOf(target) != -1) { 00360 break; 00361 } 00362 } 00363 return data; 00364 } 00365 00366 String ESP8266::recvString(String target1, String target2, uint32_t timeout) 00367 { 00368 String data; 00369 char a; 00370 unsigned long start = millis(); 00371 while (millis() - start < timeout) { 00372 while(m_puart->available() > 0) { 00373 a = m_puart->readChr(); 00374 data += a; 00375 } 00376 if (data.indexOf(target1) != -1) { 00377 break; 00378 } else if (data.indexOf(target2) != -1) { 00379 break; 00380 } 00381 } 00382 return data; 00383 } 00384 00385 String ESP8266::recvString(String target1, String target2, String target3, uint32_t timeout) 00386 { 00387 String data; 00388 char a; 00389 unsigned long start = millis(); 00390 while (millis() - start < timeout) { 00391 while(m_puart->available() > 0) { 00392 a = m_puart->readChr(); 00393 data += a; 00394 } 00395 if (data.indexOf(target1) != -1) { 00396 break; 00397 } else if (data.indexOf(target2) != -1) { 00398 break; 00399 } else if (data.indexOf(target3) != -1) { 00400 break; 00401 } 00402 } 00403 return data; 00404 } 00405 00406 bool ESP8266::recvFind(String target, uint32_t timeout) 00407 { 00408 String data_tmp; 00409 data_tmp = recvString(target, timeout); 00410 if (data_tmp.indexOf(target) != -1) { 00411 return true; 00412 } 00413 return false; 00414 } 00415 00416 bool ESP8266::recvFindAndFilter(String target, String begin, String end, String &data, uint32_t timeout) 00417 { 00418 String data_tmp; 00419 data_tmp = recvString(target, timeout); 00420 if (data_tmp.indexOf(target) != -1) { 00421 int32_t index1 = data_tmp.indexOf(begin); 00422 int32_t index2 = data_tmp.indexOf(end); 00423 if (index1 != -1 && index2 != -1) { 00424 index1 += begin.length(); 00425 data = data_tmp.substring(index1, index2); 00426 return true; 00427 } 00428 } 00429 data = ""; 00430 return false; 00431 } 00432 00433 bool ESP8266::eAT(void) 00434 { 00435 m_puart->flush(); 00436 m_puart->println("AT"); 00437 return recvFind("OK"); 00438 } 00439 00440 bool ESP8266::eATRST(void) 00441 { 00442 m_puart->flush(); 00443 m_puart->println("AT+RST"); 00444 return recvFind("OK"); 00445 } 00446 00447 bool ESP8266::eATGMR(String &version) 00448 { 00449 m_puart->flush(); 00450 m_puart->println("AT+GMR"); 00451 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", version); 00452 } 00453 00454 bool ESP8266::qATCWMODE(uint8_t *mode) 00455 { 00456 String str_mode; 00457 bool ret; 00458 if (!mode) { 00459 return false; 00460 } 00461 m_puart->flush(); 00462 m_puart->println("AT+CWMODE?"); 00463 ret = recvFindAndFilter("OK", "+CWMODE:", "\r\n\r\nOK", str_mode); 00464 if (ret) { 00465 *mode = (uint8_t)str_mode.toInt(); 00466 return true; 00467 } else { 00468 return false; 00469 } 00470 } 00471 00472 bool ESP8266::sATCWMODE(uint8_t mode) 00473 { 00474 String data; 00475 m_puart->flush(); 00476 m_puart->print("AT+CWMODE="); 00477 m_puart->println(mode); 00478 00479 data = recvString("OK", "no change"); 00480 if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) { 00481 return true; 00482 } 00483 return false; 00484 } 00485 00486 bool ESP8266::sATCWJAP(String ssid, String pwd) 00487 { 00488 String data; 00489 m_puart->flush(); 00490 m_puart->print("AT+CWJAP=\""); 00491 m_puart->print(ssid); 00492 m_puart->print("\",\""); 00493 m_puart->print(pwd); 00494 m_puart->println("\""); 00495 00496 data = recvString("OK", "FAIL", 10000); 00497 if (data.indexOf("OK") != -1) { 00498 return true; 00499 } 00500 return false; 00501 } 00502 00503 bool ESP8266::eATCWLAP(String &list) 00504 { 00505 String data; 00506 m_puart->flush(); 00507 m_puart->println("AT+CWLAP"); 00508 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 10000); 00509 } 00510 00511 bool ESP8266::eATCWQAP(void) 00512 { 00513 String data; 00514 m_puart->flush(); 00515 m_puart->println("AT+CWQAP"); 00516 return recvFind("OK"); 00517 } 00518 00519 bool ESP8266::sATCWSAP(String ssid, String pwd, uint8_t chl, uint8_t ecn) 00520 { 00521 String data; 00522 m_puart->flush(); 00523 m_puart->print("AT+CWSAP=\""); 00524 m_puart->print(ssid); 00525 m_puart->print("\",\""); 00526 m_puart->print(pwd); 00527 m_puart->print("\","); 00528 m_puart->print(chl); 00529 m_puart->print(","); 00530 m_puart->println(ecn); 00531 00532 data = recvString("OK", "ERROR", 5000); 00533 if (data.indexOf("OK") != -1) { 00534 return true; 00535 } 00536 return false; 00537 } 00538 00539 bool ESP8266::eATCWLIF(String &list) 00540 { 00541 String data; 00542 m_puart->flush(); 00543 m_puart->println("AT+CWLIF"); 00544 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list); 00545 } 00546 bool ESP8266::eATCIPSTATUS(String &list) 00547 { 00548 String data; 00549 delay(100); 00550 m_puart->flush(); 00551 m_puart->println("AT+CIPSTATUS"); 00552 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list); 00553 } 00554 bool ESP8266::sATCIPSTARTSingle(String type, String addr, uint32_t port) 00555 { 00556 String data; 00557 m_puart->flush(); 00558 m_puart->print("AT+CIPSTART=\""); 00559 m_puart->print(type); 00560 m_puart->print("\",\""); 00561 m_puart->print(addr); 00562 m_puart->print("\","); 00563 m_puart->println(port); 00564 00565 data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000); 00566 if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) { 00567 return true; 00568 } 00569 return false; 00570 } 00571 bool ESP8266::sATCIPSTARTMultiple(uint8_t mux_id, String type, String addr, uint32_t port) 00572 { 00573 String data; 00574 m_puart->flush(); 00575 m_puart->print("AT+CIPSTART="); 00576 m_puart->print(mux_id); 00577 m_puart->print(",\""); 00578 m_puart->print(type); 00579 m_puart->print("\",\""); 00580 m_puart->print(addr); 00581 m_puart->print("\","); 00582 m_puart->println(port); 00583 00584 data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000); 00585 if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) { 00586 return true; 00587 } 00588 return false; 00589 } 00590 bool ESP8266::sATCIPSENDSingle(const uint8_t *buffer, uint32_t len) 00591 { 00592 m_puart->flush(); 00593 m_puart->print("AT+CIPSEND="); 00594 m_puart->println(len); 00595 if (recvFind(">", 5000)) { 00596 m_puart->flush(); 00597 for (uint32_t i = 0; i < len; i++) { 00598 m_puart->write(buffer[i]); 00599 } 00600 return recvFind("SEND OK", 10000); 00601 } 00602 return false; 00603 } 00604 bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, const uint8_t *buffer, uint32_t len) 00605 { 00606 m_puart->flush(); 00607 m_puart->print("AT+CIPSEND="); 00608 m_puart->print(mux_id); 00609 m_puart->print(","); 00610 m_puart->println(len); 00611 if (recvFind(">", 5000)) { 00612 m_puart->flush(); 00613 for (uint32_t i = 0; i < len; i++) { 00614 m_puart->write(buffer[i]); 00615 } 00616 return recvFind("SEND OK", 10000); 00617 } 00618 return false; 00619 } 00620 bool ESP8266::sATCIPCLOSEMulitple(uint8_t mux_id) 00621 { 00622 String data; 00623 m_puart->flush(); 00624 m_puart->print("AT+CIPCLOSE="); 00625 m_puart->println(mux_id); 00626 00627 data = recvString("OK", "Link is not", 5000); 00628 if (data.indexOf("OK") != -1 || data.indexOf("Link is not") != -1) { 00629 return true; 00630 } 00631 return false; 00632 } 00633 bool ESP8266::eATCIPCLOSESingle(void) 00634 { 00635 m_puart->flush(); 00636 m_puart->println("AT+CIPCLOSE"); 00637 return recvFind("OK", 5000); 00638 } 00639 bool ESP8266::eATCIFSR(String &list) 00640 { 00641 m_puart->flush(); 00642 m_puart->println("AT+CIFSR"); 00643 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list); 00644 } 00645 bool ESP8266::sATCIPMUX(uint8_t mode) 00646 { 00647 String data; 00648 m_puart->flush(); 00649 m_puart->print("AT+CIPMUX="); 00650 m_puart->println(mode); 00651 00652 data = recvString("OK", "Link is builded"); 00653 if (data.indexOf("OK") != -1) { 00654 return true; 00655 } 00656 return false; 00657 } 00658 bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port) 00659 { 00660 String data; 00661 if (mode) { 00662 m_puart->flush(); 00663 m_puart->print("AT+CIPSERVER=1,"); 00664 m_puart->println(port); 00665 00666 data = recvString("OK", "no change"); 00667 if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) { 00668 return true; 00669 } 00670 return false; 00671 } else { 00672 m_puart->flush(); 00673 m_puart->println("AT+CIPSERVER=0"); 00674 return recvFind("\r\r\n"); 00675 } 00676 } 00677 bool ESP8266::sATCIPSTO(uint32_t timeout) 00678 { 00679 m_puart->flush(); 00680 m_puart->print("AT+CIPSTO="); 00681 m_puart->println(timeout); 00682 return recvFind("OK"); 00683 }
Generated on Fri Jul 15 2022 19:47:41 by 1.7.2