Class library for using the ESP8266 wifi module.
ESP8266.cpp
- Committer:
- grantphillips
- Date:
- 2018-06-11
- Revision:
- 0:30dd9c0f7559
File content as of revision 0:30dd9c0f7559:
#include "ESP8266.h" #include "mbed.h" /***************************** Public functions ******************************/ ESP8266::ESP8266(PinName Tx, PinName Rx, PinName Rst) : esp(Tx, Rx), _rst(Rst) { esp.baud(115200); mDEBUG = false; } bool ESP8266::startup(uint8_t mode) { if(mode < 1 || mode > 3) //only 3 valid modes return false; _rst=0; wait(1.0); _rst=1; wait(1.0); if(!kick()) //check if connected return(false); if(!reset()) //reset ESP8266 return(false); if(!setWiFiMode(mode)) //set the WiFi mode return(false); if(!setMux(true)) //set to multiple connections return false; rxtemp_idx=0; //rxmsg_idx= 0; new_rxmsg = false; rxpass1=false, rxpass2=false, rxpass3=false; return true; } void ESP8266::getVersion(char* version) { string ver; eATGMR(ver); strcpy(version, ver.c_str()); } void ESP8266::getAPList(char* list) { string lst; eATCWLAP(lst); strcpy(list, lst.c_str()); } bool ESP8266::setSoftAPParam(string ssid, string pwd, uint8_t chl, uint8_t ecn) { return sATCWSAP(ssid, pwd, chl, ecn); } bool ESP8266::DHCP(bool enabled, int mode) { return sATCWDHCP(enabled, mode); } bool ESP8266::joinAP(string ssid, string pwd) { return sATCWJAP(ssid, pwd); } void ESP8266::getLocalIP(char* LocalIP) { string lst; eATCIFSR(lst); strcpy(LocalIP, lst.c_str()); } bool ESP8266::setLocalIP(string LocalIP) { return sATCIPSTA(LocalIP); } bool ESP8266::setSoftAPIP(string LocalIP) { return sATCIPAP(LocalIP); } bool ESP8266::TCPServerStart(uint32_t port) { if (sATCIPSERVER(1, port)) { esp.attach(this,&ESP8266::RxInterrupt); return true; } return false; } bool ESP8266::TCPPacketReceived(void) { return new_rxmsg; } void ESP8266::TCPPacketRead(uint8_t *ID, uint32_t *LEN, char DATA[]) { *ID = packetID; *LEN = packetLen; strcpy(DATA, packetData); new_rxmsg=false; } bool ESP8266::TCPPacketSend(uint8_t ID, uint32_t LEN, char DATA[]) { bool ret; esp.attach(NULL); ret=sATCIPSENDMultiple(ID, DATA, LEN); esp.attach(this,&ESP8266::RxInterrupt); return ret; } /***************************** Private functions *****************************/ bool ESP8266::kick(void) { return eAT(); } bool ESP8266::reset(void) { unsigned long start; if (eATRST()) { wait_ms(2000); t.start(); start = t.read_ms(); while (t.read_ms() - start < 3000) { if (eAT()) { wait_ms(1500); /* Waiting for stable */ return true; } wait_ms(100); } } return false; } bool ESP8266::setWiFiMode(uint8_t mode) { switch(mode) { case 1: { if (sATCWMODE(1)) return true; else return false; } case 2: { if (sATCWMODE(2)) return true; else return false; } case 3: { if (sATCWMODE(3)) return true; else return false; } default: return false; } } bool ESP8266::setMux(bool onoff) { if(onoff) return sATCIPMUX(1); else return sATCIPMUX(0); } bool ESP8266::recvFind(string target, uint32_t timeout) { string data_tmp; data_tmp = recvString(target, timeout); if (data_tmp.find(target) != std::string::npos) { return true; } return false; } string ESP8266::recvString(string target, uint32_t timeout) { string data; char a; t.start(); unsigned long start = t.read_ms(); while (t.read_ms() - start < timeout) { while(esp.readable() > 0) { a = esp.getc(); data += a; } if (data.find(target) != std::string::npos) { break; } } t.stop(); return data; } string ESP8266::recvString(string target1, string target2, uint32_t timeout) { string data; char a; t.start(); unsigned long start = t.read_ms(); while (t.read_ms() - start < timeout) { while(esp.readable() > 0) { a = esp.getc(); data += a; } if (data.find(target1) != std::string::npos) { break; } else if (data.find(target2) != std::string::npos) { break; } } t.stop(); return data; } string ESP8266::recvString(string target1, string target2, string target3, uint32_t timeout) { string data; char a; t.start(); unsigned long start = t.read_ms(); while (t.read_ms() - start < timeout) { while(esp.readable() > 0) { a = esp.getc(); data += a; } if (data.find(target1) != std::string::npos) { break; } else if (data.find(target2) != std::string::npos) { break; } else if (data.find(target3) != std::string::npos) { break; } } t.stop(); return data; } 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.find(target) != std::string::npos) { int32_t index1 = data_tmp.find(begin); int32_t index2 = data_tmp.find(end); if (index1 != std::string::npos && index2 != std::string::npos) { index1 += begin.length(); data = data_tmp.substr(index1, index2-index1); return true; } } data = ""; return false; } /************************ Private AT Command Functions ***********************/ bool ESP8266::eAT(void) { esp.printf("AT\r\n"); return recvFind("OK", 2000); } bool ESP8266::eATRST(void) { esp.printf("AT+RST\r\n"); return recvFind("OK", 2000); } bool ESP8266::eATGMR(string &version) { esp.printf("AT+GMR\r\n"); return recvFindAndFilter("OK", "\r\r\n", "\r\nSDK", version); } bool ESP8266::sATCWMODE(uint8_t mode) { string data; esp.printf("AT+CWMODE=%d\r\n", mode); data = recvString("OK", "no change"); if (data.find("OK") != std::string::npos || data.find("no change") != std::string::npos) { return true; } return false; } bool ESP8266::sATCIPMUX(uint8_t mode) { string data; esp.printf("AT+CIPMUX=%d\r\n",mode); data = recvString("OK", "Link is builded"); if (data.find("OK") != std::string::npos) { return true; } return false; } bool ESP8266::eATCWLAP(string &list) { string data; esp.printf("AT+CWLAP\r\n"); return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 10000); } bool ESP8266::sATCWJAP(string ssid, string pwd) { string data; esp.printf("AT+CWJAP=\"%s\",\"%s\"\r\n", ssid.c_str(), pwd.c_str()); data = recvString("OK", "FAIL", 15000); if (data.find("OK") != std::string::npos) { return true; } return false; } bool ESP8266::eATCIFSR(string &list) { esp.printf("AT+CIFSR\r\n"); return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list); } bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port) { string data; if (mode) { esp.printf("AT+CIPSERVER=1,%d\r\n", port); data = recvString("OK", "no change"); if (data.find("OK") != std::string::npos || data.find("no change") != std::string::npos) { return true; } return false; } else { esp.printf("AT+CIPSERVER=0\r\n"); return recvFind("\r\r\n"); } } bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, char buffer[], uint32_t len) { //esp.flush(); esp.printf("AT+CIPSEND=%d,%d\r\n", mux_id, len); if (recvFind(">", 5000)) { //esp.flush(); for (uint32_t i = 0; i < len; i++) { esp.printf("%c",buffer[i]); } return recvFind("SEND OK", 10000); } return false; } bool ESP8266::sATCWSAP(string ssid, string pwd, uint8_t chl, uint8_t ecn) { string data; esp.printf("AT+CWSAP=\"%s\",\"%s\",%d,%d\r\n", ssid.c_str(), pwd.c_str(), chl, ecn); data = recvString("OK", "ERROR", 5000); if (data.find("OK") != std::string::npos) { return true; } return false; } bool ESP8266::sATCWDHCP(bool enabled, int mode) { if(mode < 0 || mode > 2) { return false; } esp.printf("AT+CWDHCP=%d,%d\r\n", enabled?1:0, mode); return recvFind("OK", 2000); } bool ESP8266::sATCIPSTA(string ip) { esp.printf("AT+CIPSTA=\"%s\"\r\n", ip.c_str()); return recvFind("OK", 2000); } bool ESP8266::sATCIPAP(string ip) { esp.printf("AT+CIPAP=\"%s\"\r\n", ip.c_str()); return recvFind("OK", 2000); } /************************* Private Callback Functions *************************/ void ESP8266::RxInterrupt(void) { char c; c = esp.getc(); //read the incoming character if(c == '\n') { //rxmsg_idx = 0; rxpass1=false; rxpass2=false; rxpass3=false; rxtemp_idx=0; //new_rxmsg=false; } if(rxpass1 && rxpass2 && rxpass3) { if(rxtemp_idx < packetLen-1) { rxtemp[rxtemp_idx] = c; rxtemp_idx++; } else { rxtemp[rxtemp_idx] = c; rxtemp[rxtemp_idx+1] = '\0'; strcpy(packetData, rxtemp); //rxmsg_idx = 0; rxpass1=false; rxpass2=false; rxpass3=false; rxtemp_idx=0; new_rxmsg=true; } } else if(rxpass1 && rxpass2) { if(c != ':') { rxtemp[rxtemp_idx] = c; rxtemp_idx++; } else { rxtemp[rxtemp_idx] = '\0'; packetLen= atoi(rxtemp); rxtemp_idx=0; rxpass3=true; } } else if(rxpass1) { if(c != ',') { rxtemp[rxtemp_idx] = c; rxtemp_idx++; } else { rxtemp[rxtemp_idx] = '\0'; packetID = atoi(rxtemp); rxtemp_idx=0; rxpass2=true; } } else { rxtemp[rxtemp_idx] = c; rxtemp_idx++; if(rxtemp_idx == 6) { if(rxtemp[1] == '+' && rxtemp[2] == 'I' && rxtemp[3] == 'P' && rxtemp[4] == 'D' && rxtemp[5] == ',') { rxpass1 = true; } } /* rxmsg[rxmsg_idx] = c; rxmsg_idx++; if(rxmsg_idx == 6) { if(rxmsg[1] == '+' && rxmsg[2] == 'I' && rxmsg[3] == 'P' && rxmsg[4] == 'D' && rxmsg[5] == ',') { rxpass1 = true; } }*/ } }