Provide an easy-to-use way to manipulate ESP8266.
Dependents: WeeESP8266_TCPClientMultiple WeeESP8266_TCPClientSingle WeeESP8266_TCPServer WeeESP8266_UDPClientMultiple ... more
ESP8266.cpp
- Committer:
- itead
- Date:
- 2015-02-11
- Revision:
- 21:d1a7f48ab3ba
- Parent:
- 17:60ab5d5686d3
File content as of revision 21:d1a7f48ab3ba:
/** * @file ESP8266.cpp * @brief The implementation of class ESP8266. * @author Wu Pengfei<pengfei.wu@itead.cc> * @date 2015.02 * * @par Copyright: * Copyright (c) 2015 ITEAD Intelligent Systems Co., Ltd. \n\n * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. \n\n * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "ESP8266.h" #include "log.h" ESP8266::ESP8266(ArduinoSerial &uart): m_puart(&uart) { m_puart->begin(9600); m_puart->flush(); } bool ESP8266::kick(void) { return eAT(); } bool ESP8266::restart(void) { unsigned long start; if (eATRST()) { delay(2000); start = millis(); while (millis() - start < 3000) { if (eAT()) { delay(1500); /* Waiting for stable */ return true; } delay(100); } } return false; } String ESP8266::getVersion(void) { String version; eATGMR(version); return version; } bool ESP8266::setOprToStation(void) { uint8_t mode; if (!qATCWMODE(&mode)) { return false; } if (mode == 1) { return true; } else { if (sATCWMODE(1) && restart()) { return true; } else { return false; } } } bool ESP8266::setOprToSoftAP(void) { uint8_t mode; if (!qATCWMODE(&mode)) { return false; } if (mode == 2) { return true; } else { if (sATCWMODE(2) && restart()) { return true; } else { return false; } } } bool ESP8266::setOprToStationSoftAP(void) { uint8_t mode; if (!qATCWMODE(&mode)) { return false; } if (mode == 3) { return true; } else { if (sATCWMODE(3) && restart()) { return true; } else { return false; } } } String ESP8266::getAPList(void) { String list; eATCWLAP(list); return list; } bool ESP8266::joinAP(String ssid, String pwd) { return sATCWJAP(ssid, pwd); } bool ESP8266::leaveAP(void) { return eATCWQAP(); } bool ESP8266::setSoftAPParam(String ssid, String pwd, uint8_t chl, uint8_t ecn) { return sATCWSAP(ssid, pwd, chl, ecn); } String ESP8266::getJoinedDeviceIP(void) { String list; eATCWLIF(list); return list; } String ESP8266::getIPStatus(void) { String list; eATCIPSTATUS(list); return list; } String ESP8266::getLocalIP(void) { String list; eATCIFSR(list); return list; } bool ESP8266::enableMUX(void) { return sATCIPMUX(1); } bool ESP8266::disableMUX(void) { return sATCIPMUX(0); } bool ESP8266::createTCP(String addr, uint32_t port) { return sATCIPSTARTSingle("TCP", addr, port); } bool ESP8266::releaseTCP(void) { return eATCIPCLOSESingle(); } bool ESP8266::registerUDP(String addr, uint32_t port) { return sATCIPSTARTSingle("UDP", addr, port); } bool ESP8266::unregisterUDP(void) { return eATCIPCLOSESingle(); } bool ESP8266::createTCP(uint8_t mux_id, String addr, uint32_t port) { return sATCIPSTARTMultiple(mux_id, "TCP", addr, port); } bool ESP8266::releaseTCP(uint8_t mux_id) { return sATCIPCLOSEMulitple(mux_id); } bool ESP8266::registerUDP(uint8_t mux_id, String addr, uint32_t port) { return sATCIPSTARTMultiple(mux_id, "UDP", addr, port); } bool ESP8266::unregisterUDP(uint8_t mux_id) { return sATCIPCLOSEMulitple(mux_id); } bool ESP8266::setTCPServerTimeout(uint32_t timeout) { return sATCIPSTO(timeout); } bool ESP8266::startTCPServer(uint32_t port) { if (sATCIPSERVER(1, port)) { return true; } return false; } bool ESP8266::stopTCPServer(void) { sATCIPSERVER(0); restart(); return false; } bool ESP8266::send(const uint8_t *buffer, uint32_t len) { return sATCIPSENDSingle(buffer, len); } bool ESP8266::send(uint8_t mux_id, const uint8_t *buffer, uint32_t len) { return sATCIPSENDMultiple(mux_id, buffer, len); } uint32_t ESP8266::recv(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout) { return recvPkg(buffer, buffer_size, NULL, timeout, NULL); } uint32_t ESP8266::recv(uint8_t mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout) { uint8_t id; uint32_t ret; ret = recvPkg(buffer, buffer_size, NULL, timeout, &id); if (ret > 0 && id == mux_id) { return ret; } return 0; } uint32_t ESP8266::recv(uint8_t *coming_mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout) { return recvPkg(buffer, buffer_size, NULL, timeout, coming_mux_id); } /*----------------------------------------------------------------------------*/ uint32_t ESP8266::recvPkg(uint8_t *buffer, uint32_t buffer_size, uint32_t *data_len, uint32_t timeout, uint8_t *coming_mux_id) { String data; char a; int32_t index_PIPDcomma = -1; int32_t index_colon = -1; /* : */ int32_t index_comma = -1; /* , */ int32_t len = -1; int8_t id = -1; bool has_data = false; logDebug("start recv pkg"); unsigned long start = millis(); while (millis() - start < timeout) { while(m_puart->available() > 0) { a = m_puart->readChr(); data += a; } index_PIPDcomma = data.indexOf("+IPD,"); if (index_PIPDcomma != -1) { logDebug("index_PIPDcomma found = %d", index_PIPDcomma); index_colon = data.indexOf(':', index_PIPDcomma + 5); if (index_colon != -1) { logDebug("data1 = %s\r\n", data.c_str()); logDebug("index_colon found = %d", index_colon); index_comma = data.indexOf(',', index_PIPDcomma + 5); logDebug("index_comma found = %d", index_comma); if (index_comma != -1 && index_comma < index_colon) { /* +IPD,id,len:data */ logDebug("id = %d", id); id = data.substring(index_PIPDcomma + 5, index_comma).toInt(); logDebug("id = %d", id); if (id < 0 || id > 4) { return 0; } logDebug("len = %d", len); len = data.substring(index_comma + 1, index_colon).toInt(); logDebug("len = %d", len); if (len <= 0) { return 0; } logDebug("has id"); } else { /* +IPD,len:data */ len = data.substring(index_PIPDcomma + 5, index_colon).toInt(); logDebug("len = %d", len); if (len <= 0) { return 0; } logDebug("no id"); } has_data = true; logDebug("has_data true"); break; } } } //logDebug("has_data = %u\r\n", has_data); //logDebug("data2 = %s\r\n", data.c_str()); if (has_data) { start = millis(); while (millis() - start < 3000) { while(m_puart->available() > 0) { a = m_puart->readChr(); data += a; } //logDebug("data3 = %s\r\n", data.c_str()); if (data.length() >= index_colon + 1 + len) { if (data_len) { *data_len = len; } if (index_comma != -1 && coming_mux_id) { *coming_mux_id = id; } //logDebug("len = %d", len); //logDebug("buffer_size = %d", buffer_size); uint32_t ret = len > buffer_size ? buffer_size : len; memcpy(buffer, data.substring(index_colon + 1, index_colon + 1 + len).c_str(), ret); logDebug("ret = %u\r\n", ret); return ret; } } } logDebug("end recv pkg"); return 0; } String ESP8266::recvString(String target, uint32_t timeout) { String data; char a; unsigned long start = millis(); while (millis() - start < timeout) { while(m_puart->available() > 0) { a = m_puart->readChr(); data += a; } if (data.indexOf(target) != -1) { break; } } return data; } String ESP8266::recvString(String target1, String target2, uint32_t timeout) { String data; char a; unsigned long start = millis(); while (millis() - start < timeout) { while(m_puart->available() > 0) { a = m_puart->readChr(); data += a; } if (data.indexOf(target1) != -1) { break; } else if (data.indexOf(target2) != -1) { break; } } return data; } String ESP8266::recvString(String target1, String target2, String target3, uint32_t timeout) { String data; char a; unsigned long start = millis(); while (millis() - start < timeout) { while(m_puart->available() > 0) { a = m_puart->readChr(); data += a; } if (data.indexOf(target1) != -1) { break; } else if (data.indexOf(target2) != -1) { break; } else if (data.indexOf(target3) != -1) { break; } } return data; } bool ESP8266::recvFind(String target, uint32_t timeout) { String data_tmp; data_tmp = recvString(target, timeout); if (data_tmp.indexOf(target) != -1) { return true; } return false; } bool ESP8266::recvFindAndFilter(String target, String begin, String end, String &data, uint32_t timeout) { String data_tmp; data_tmp = recvString(target, timeout); if (data_tmp.indexOf(target) != -1) { int32_t index1 = data_tmp.indexOf(begin); int32_t index2 = data_tmp.indexOf(end); if (index1 != -1 && index2 != -1) { index1 += begin.length(); data = data_tmp.substring(index1, index2); return true; } } data = ""; return false; } bool ESP8266::eAT(void) { m_puart->flush(); m_puart->println("AT"); return recvFind("OK"); } bool ESP8266::eATRST(void) { m_puart->flush(); m_puart->println("AT+RST"); return recvFind("OK"); } bool ESP8266::eATGMR(String &version) { m_puart->flush(); m_puart->println("AT+GMR"); return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", version); } bool ESP8266::qATCWMODE(uint8_t *mode) { String str_mode; bool ret; if (!mode) { return false; } m_puart->flush(); m_puart->println("AT+CWMODE?"); ret = recvFindAndFilter("OK", "+CWMODE:", "\r\n\r\nOK", str_mode); if (ret) { *mode = (uint8_t)str_mode.toInt(); return true; } else { return false; } } bool ESP8266::sATCWMODE(uint8_t mode) { String data; m_puart->flush(); m_puart->print("AT+CWMODE="); m_puart->println(mode); data = recvString("OK", "no change"); if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) { return true; } return false; } bool ESP8266::sATCWJAP(String ssid, String pwd) { String data; m_puart->flush(); m_puart->print("AT+CWJAP=\""); m_puart->print(ssid); m_puart->print("\",\""); m_puart->print(pwd); m_puart->println("\""); data = recvString("OK", "FAIL", 10000); if (data.indexOf("OK") != -1) { return true; } return false; } bool ESP8266::eATCWLAP(String &list) { String data; m_puart->flush(); m_puart->println("AT+CWLAP"); return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 10000); } bool ESP8266::eATCWQAP(void) { String data; m_puart->flush(); m_puart->println("AT+CWQAP"); return recvFind("OK"); } bool ESP8266::sATCWSAP(String ssid, String pwd, uint8_t chl, uint8_t ecn) { String data; m_puart->flush(); m_puart->print("AT+CWSAP=\""); m_puart->print(ssid); m_puart->print("\",\""); m_puart->print(pwd); m_puart->print("\","); m_puart->print(chl); m_puart->print(","); m_puart->println(ecn); data = recvString("OK", "ERROR", 5000); if (data.indexOf("OK") != -1) { return true; } return false; } bool ESP8266::eATCWLIF(String &list) { String data; m_puart->flush(); m_puart->println("AT+CWLIF"); return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list); } bool ESP8266::eATCIPSTATUS(String &list) { String data; delay(100); m_puart->flush(); m_puart->println("AT+CIPSTATUS"); return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list); } bool ESP8266::sATCIPSTARTSingle(String type, String addr, uint32_t port) { String data; m_puart->flush(); m_puart->print("AT+CIPSTART=\""); m_puart->print(type); m_puart->print("\",\""); m_puart->print(addr); m_puart->print("\","); m_puart->println(port); data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000); if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) { return true; } return false; } bool ESP8266::sATCIPSTARTMultiple(uint8_t mux_id, String type, String addr, uint32_t port) { String data; m_puart->flush(); m_puart->print("AT+CIPSTART="); m_puart->print(mux_id); m_puart->print(",\""); m_puart->print(type); m_puart->print("\",\""); m_puart->print(addr); m_puart->print("\","); m_puart->println(port); data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000); if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) { return true; } return false; } bool ESP8266::sATCIPSENDSingle(const uint8_t *buffer, uint32_t len) { m_puart->flush(); m_puart->print("AT+CIPSEND="); m_puart->println(len); if (recvFind(">", 5000)) { m_puart->flush(); for (uint32_t i = 0; i < len; i++) { m_puart->write(buffer[i]); } return recvFind("SEND OK", 10000); } return false; } bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, const uint8_t *buffer, uint32_t len) { m_puart->flush(); m_puart->print("AT+CIPSEND="); m_puart->print(mux_id); m_puart->print(","); m_puart->println(len); if (recvFind(">", 5000)) { m_puart->flush(); for (uint32_t i = 0; i < len; i++) { m_puart->write(buffer[i]); } return recvFind("SEND OK", 10000); } return false; } bool ESP8266::sATCIPCLOSEMulitple(uint8_t mux_id) { String data; m_puart->flush(); m_puart->print("AT+CIPCLOSE="); m_puart->println(mux_id); data = recvString("OK", "Link is not", 5000); if (data.indexOf("OK") != -1 || data.indexOf("Link is not") != -1) { return true; } return false; } bool ESP8266::eATCIPCLOSESingle(void) { m_puart->flush(); m_puart->println("AT+CIPCLOSE"); return recvFind("OK", 5000); } bool ESP8266::eATCIFSR(String &list) { m_puart->flush(); m_puart->println("AT+CIFSR"); return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list); } bool ESP8266::sATCIPMUX(uint8_t mode) { String data; m_puart->flush(); m_puart->print("AT+CIPMUX="); m_puart->println(mode); data = recvString("OK", "Link is builded"); if (data.indexOf("OK") != -1) { return true; } return false; } bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port) { String data; if (mode) { m_puart->flush(); m_puart->print("AT+CIPSERVER=1,"); m_puart->println(port); data = recvString("OK", "no change"); if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) { return true; } return false; } else { m_puart->flush(); m_puart->println("AT+CIPSERVER=0"); return recvFind("\r\r\n"); } } bool ESP8266::sATCIPSTO(uint32_t timeout) { m_puart->flush(); m_puart->print("AT+CIPSTO="); m_puart->println(timeout); return recvFind("OK"); }