Provide an easy-to-use way to manipulate ESP8266.
Fork of WeeESP8266 by
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, int baud_rate): m_puart(&uart) 00025 { 00026 m_puart->begin(baud_rate); 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(int *pStatus) 00141 { 00142 String list; 00143 eATCIPSTATUS(list, pStatus); 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 00547 bool ESP8266::eATCIPSTATUS(String &list, int *pStatus) 00548 { 00549 String data; 00550 m_puart->flush(); 00551 m_puart->println("AT+CIPSTATUS"); 00552 bool ok = recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list); 00553 if (ok && pStatus) { 00554 int index_colon = list.indexOf(':'); 00555 if (index_colon != -1) 00556 *pStatus = list[index_colon+1] - '0'; 00557 else 00558 *pStatus = -1; 00559 } 00560 return ok; 00561 } 00562 00563 bool ESP8266::sATCIPSTARTSingle(String type, String addr, uint32_t port) 00564 { 00565 String data; 00566 m_puart->flush(); 00567 m_puart->print("AT+CIPSTART=\""); 00568 m_puart->print(type); 00569 m_puart->print("\",\""); 00570 m_puart->print(addr); 00571 m_puart->print("\","); 00572 m_puart->println(port); 00573 00574 data = recvString("OK", "ERROR", "ALREAY CONNECT", 10000); 00575 if (data.indexOf("OK") != -1 || data.indexOf("ALREAY CONNECT") != -1) { 00576 return true; 00577 } 00578 return false; 00579 } 00580 bool ESP8266::sATCIPSTARTMultiple(uint8_t mux_id, String type, String addr, uint32_t port) 00581 { 00582 String data; 00583 m_puart->flush(); 00584 m_puart->print("AT+CIPSTART="); 00585 m_puart->print(mux_id); 00586 m_puart->print(",\""); 00587 m_puart->print(type); 00588 m_puart->print("\",\""); 00589 m_puart->print(addr); 00590 m_puart->print("\","); 00591 m_puart->println(port); 00592 00593 data = recvString("OK", "ERROR", "ALREAY CONNECT", 10000); 00594 if (data.indexOf("OK") != -1 || data.indexOf("ALREAY CONNECT") != -1) { 00595 return true; 00596 } 00597 return false; 00598 } 00599 bool ESP8266::sATCIPSENDSingle(const uint8_t *buffer, uint32_t len) 00600 { 00601 m_puart->flush(); 00602 m_puart->print("AT+CIPSEND="); 00603 m_puart->println(len); 00604 if (recvFind(">", 5000)) { 00605 m_puart->flush(); 00606 for (uint32_t i = 0; i < len; i++) { 00607 m_puart->write(buffer[i]); 00608 } 00609 return recvFind("SEND OK", 10000); 00610 } 00611 return false; 00612 } 00613 bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, const uint8_t *buffer, uint32_t len) 00614 { 00615 m_puart->flush(); 00616 m_puart->print("AT+CIPSEND="); 00617 m_puart->print(mux_id); 00618 m_puart->print(","); 00619 m_puart->println(len); 00620 if (recvFind(">", 5000)) { 00621 m_puart->flush(); 00622 for (uint32_t i = 0; i < len; i++) { 00623 m_puart->write(buffer[i]); 00624 } 00625 return recvFind("SEND OK", 10000); 00626 } 00627 return false; 00628 } 00629 bool ESP8266::sATCIPCLOSEMulitple(uint8_t mux_id) 00630 { 00631 String data; 00632 m_puart->flush(); 00633 m_puart->print("AT+CIPCLOSE="); 00634 m_puart->println(mux_id); 00635 00636 data = recvString("OK", "Link is not", 5000); 00637 if (data.indexOf("OK") != -1 || data.indexOf("Link is not") != -1) { 00638 return true; 00639 } 00640 return false; 00641 } 00642 bool ESP8266::eATCIPCLOSESingle(void) 00643 { 00644 m_puart->flush(); 00645 m_puart->println("AT+CIPCLOSE"); 00646 return recvFind("OK", 5000); 00647 } 00648 bool ESP8266::eATCIFSR(String &list) 00649 { 00650 m_puart->flush(); 00651 m_puart->println("AT+CIFSR"); 00652 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list); 00653 } 00654 bool ESP8266::sATCIPMUX(uint8_t mode) 00655 { 00656 String data; 00657 m_puart->flush(); 00658 m_puart->print("AT+CIPMUX="); 00659 m_puart->println(mode); 00660 00661 data = recvString("OK", "Link is builded"); 00662 if (data.indexOf("OK") != -1) { 00663 return true; 00664 } 00665 return false; 00666 } 00667 bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port) 00668 { 00669 String data; 00670 if (mode) { 00671 m_puart->flush(); 00672 m_puart->print("AT+CIPSERVER=1,"); 00673 m_puart->println(port); 00674 00675 data = recvString("OK", "no change"); 00676 if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) { 00677 return true; 00678 } 00679 return false; 00680 } else { 00681 m_puart->flush(); 00682 m_puart->println("AT+CIPSERVER=0"); 00683 return recvFind("\r\r\n"); 00684 } 00685 } 00686 bool ESP8266::sATCIPSTO(uint32_t timeout) 00687 { 00688 m_puart->flush(); 00689 m_puart->print("AT+CIPSTO="); 00690 m_puart->println(timeout); 00691 return recvFind("OK"); 00692 }
Generated on Sun Jul 17 2022 01:36:00 by 1.7.2