Class library for using the ESP8266 wifi module.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ESP8266.cpp Source File

ESP8266.cpp

00001 #include "ESP8266.h"
00002 #include "mbed.h"
00003 
00004 /***************************** Public functions ******************************/
00005 ESP8266::ESP8266(PinName Tx, PinName Rx, PinName Rst) : esp(Tx, Rx), _rst(Rst) {
00006     esp.baud(115200);
00007     mDEBUG = false;
00008 }
00009 
00010 bool ESP8266::startup(uint8_t mode) {
00011     
00012     if(mode < 1 || mode > 3)    //only 3 valid modes
00013         return false;
00014     _rst=0;
00015     wait(1.0);
00016     _rst=1;
00017     wait(1.0);
00018     if(!kick())             //check if connected
00019         return(false);
00020     if(!reset())            //reset ESP8266
00021         return(false);
00022     if(!setWiFiMode(mode))  //set the WiFi mode
00023         return(false);
00024     if(!setMux(true))       //set to multiple connections
00025         return false;
00026 
00027     rxtemp_idx=0;
00028     //rxmsg_idx= 0;           
00029     new_rxmsg = false;    
00030     rxpass1=false, rxpass2=false, rxpass3=false;
00031     
00032     return true;
00033 }
00034 
00035 void ESP8266::getVersion(char* version) {
00036     string ver;
00037 
00038     eATGMR(ver);
00039     strcpy(version, ver.c_str());
00040 }
00041 
00042 void ESP8266::getAPList(char* list) {
00043     string lst;
00044     
00045     eATCWLAP(lst);
00046     strcpy(list, lst.c_str());
00047 }
00048 
00049 bool ESP8266::setSoftAPParam(string ssid, string pwd, uint8_t chl, uint8_t ecn) {
00050     return sATCWSAP(ssid, pwd, chl, ecn);
00051 }
00052 
00053 bool ESP8266::DHCP(bool enabled, int mode) {
00054     return sATCWDHCP(enabled, mode);
00055 }
00056 
00057 bool ESP8266::joinAP(string ssid, string pwd) {
00058     return sATCWJAP(ssid, pwd);
00059 }
00060 
00061 void ESP8266::getLocalIP(char* LocalIP) {
00062     string lst;
00063     
00064     eATCIFSR(lst);
00065     strcpy(LocalIP, lst.c_str());
00066 }
00067 
00068 bool ESP8266::setLocalIP(string LocalIP) {
00069     return sATCIPSTA(LocalIP);
00070 }
00071 
00072 bool ESP8266::setSoftAPIP(string LocalIP) {
00073     return sATCIPAP(LocalIP);
00074 }
00075 
00076 bool ESP8266::TCPServerStart(uint32_t port) {
00077     if (sATCIPSERVER(1, port)) {
00078         esp.attach(this,&ESP8266::RxInterrupt);
00079         return true;
00080     }
00081     return false;
00082 }
00083 
00084 bool ESP8266::TCPPacketReceived(void) {
00085     return new_rxmsg;
00086 }
00087 
00088 void ESP8266::TCPPacketRead(uint8_t *ID, uint32_t *LEN, char DATA[]) {
00089     *ID = packetID;
00090     *LEN = packetLen;
00091     strcpy(DATA, packetData);
00092     new_rxmsg=false;
00093 }
00094 
00095 bool ESP8266::TCPPacketSend(uint8_t ID, uint32_t LEN, char DATA[]) {
00096     bool ret;
00097     
00098     esp.attach(NULL);
00099     ret=sATCIPSENDMultiple(ID, DATA, LEN);
00100     esp.attach(this,&ESP8266::RxInterrupt);
00101     return ret;
00102 }
00103 
00104 /***************************** Private functions *****************************/
00105 bool ESP8266::kick(void) {
00106     return eAT();
00107 }
00108 
00109 bool ESP8266::reset(void) {
00110     unsigned long start;
00111     if (eATRST()) {
00112         wait_ms(2000);
00113         t.start();
00114         start = t.read_ms();
00115         while (t.read_ms() - start < 3000) {
00116             if (eAT()) {
00117                 wait_ms(1500); /* Waiting for stable */
00118                 return true;
00119             }
00120             wait_ms(100);
00121         }
00122     }
00123     return false;
00124 }
00125 
00126 bool ESP8266::setWiFiMode(uint8_t mode) {
00127     switch(mode) {
00128         case 1:  {
00129                     if (sATCWMODE(1)) 
00130                         return true;
00131                     else
00132                         return false;  
00133                  } 
00134         case 2:  {
00135                     if (sATCWMODE(2)) 
00136                         return true;
00137                     else
00138                         return false;  
00139                  } 
00140         case 3:  {
00141                     if (sATCWMODE(3)) 
00142                         return true;
00143                     else
00144                         return false;  
00145                  } 
00146         default: return false;
00147     } 
00148 }
00149 
00150 bool ESP8266::setMux(bool onoff) {
00151     if(onoff)
00152         return sATCIPMUX(1);
00153     else
00154         return sATCIPMUX(0);
00155 }
00156 
00157 bool ESP8266::recvFind(string target, uint32_t timeout) {
00158     string data_tmp;
00159     data_tmp = recvString(target, timeout);
00160     if (data_tmp.find(target) != std::string::npos) {
00161         return true;
00162     }
00163     return false;
00164 }
00165 
00166 string ESP8266::recvString(string target, uint32_t timeout) {
00167     string data;
00168     char a;
00169     t.start();
00170     unsigned long start = t.read_ms();
00171     while (t.read_ms() - start < timeout) {
00172         while(esp.readable() > 0) {
00173             a = esp.getc();
00174             data += a;
00175         }
00176         if (data.find(target) != std::string::npos) {
00177             break;
00178         }   
00179     }
00180     t.stop();
00181     
00182     return data;
00183 }
00184 
00185 string ESP8266::recvString(string target1, string target2, uint32_t timeout) {
00186     string data;
00187     char a;
00188     t.start();
00189     unsigned long start = t.read_ms();
00190     while (t.read_ms() - start < timeout) {
00191         while(esp.readable() > 0) {
00192             a = esp.getc();
00193             data += a;
00194         }
00195         if (data.find(target1) != std::string::npos) {
00196             break;
00197         } else if (data.find(target2) != std::string::npos) {
00198             break;
00199         }
00200     }
00201     t.stop();
00202 
00203     return data;
00204 }
00205 
00206 string ESP8266::recvString(string target1, string target2, string target3, uint32_t timeout) {
00207     string data;
00208     char a;
00209     t.start();
00210     unsigned long start = t.read_ms();
00211     while (t.read_ms() - start < timeout) {
00212         while(esp.readable() > 0) {
00213             a = esp.getc();
00214             data += a;
00215         }
00216         if (data.find(target1) != std::string::npos) {
00217             break;
00218         } else if (data.find(target2) != std::string::npos) {
00219             break;
00220         } else if (data.find(target3) != std::string::npos) {
00221             break;
00222         }
00223     }
00224     t.stop();
00225 
00226     return data;
00227 }
00228 
00229 bool ESP8266::recvFindAndFilter(string target, string begin, string end, string &data, uint32_t timeout) {
00230     string data_tmp;
00231     data_tmp = recvString(target, timeout);
00232     if (data_tmp.find(target) != std::string::npos) {
00233         int32_t index1 = data_tmp.find(begin);
00234         int32_t index2 = data_tmp.find(end);
00235         if (index1 != std::string::npos && index2 != std::string::npos) {
00236             index1 += begin.length();
00237             data = data_tmp.substr(index1, index2-index1);
00238             return true;
00239         }
00240     }
00241     data = "";
00242     return false;
00243 }
00244 
00245 
00246 
00247 
00248 /************************ Private AT Command Functions ***********************/
00249 bool ESP8266::eAT(void) {
00250     esp.printf("AT\r\n");
00251     return recvFind("OK", 2000);
00252 }
00253 
00254 bool ESP8266::eATRST(void) {
00255     esp.printf("AT+RST\r\n");
00256     return recvFind("OK", 2000);
00257 }
00258 
00259 bool ESP8266::eATGMR(string &version) {
00260     esp.printf("AT+GMR\r\n");
00261     return recvFindAndFilter("OK", "\r\r\n", "\r\nSDK", version);    
00262 }
00263 
00264 bool ESP8266::sATCWMODE(uint8_t mode) {
00265     string data;
00266     esp.printf("AT+CWMODE=%d\r\n", mode);
00267     
00268     data = recvString("OK", "no change");
00269     if (data.find("OK") != std::string::npos || data.find("no change") != std::string::npos) {
00270         return true;
00271     }
00272     return false;
00273 }
00274 
00275 bool ESP8266::sATCIPMUX(uint8_t mode)
00276 {
00277     string data;
00278     esp.printf("AT+CIPMUX=%d\r\n",mode);
00279     
00280     data = recvString("OK", "Link is builded");
00281     if (data.find("OK") != std::string::npos) {
00282         return true;
00283     }
00284     return false;
00285 }
00286 
00287 bool ESP8266::eATCWLAP(string &list) {
00288     string data;
00289     esp.printf("AT+CWLAP\r\n");
00290     return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 10000);
00291 }
00292 
00293 bool ESP8266::sATCWJAP(string ssid, string pwd) {
00294     string data;
00295     esp.printf("AT+CWJAP=\"%s\",\"%s\"\r\n", ssid.c_str(), pwd.c_str());
00296     
00297     data = recvString("OK", "FAIL", 15000);
00298     if (data.find("OK") != std::string::npos) {
00299         return true;
00300     }
00301     return false;
00302 }
00303 
00304 bool ESP8266::eATCIFSR(string &list) {
00305     esp.printf("AT+CIFSR\r\n");
00306     return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
00307 }
00308 
00309 bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port) {
00310     string data;
00311     if (mode) {
00312         esp.printf("AT+CIPSERVER=1,%d\r\n", port);
00313         
00314         data = recvString("OK", "no change");
00315         if (data.find("OK") != std::string::npos || data.find("no change") != std::string::npos) {
00316             return true;
00317         }
00318         return false;
00319     } else {
00320         esp.printf("AT+CIPSERVER=0\r\n");
00321         return recvFind("\r\r\n");
00322     }
00323 }
00324 
00325 bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, char buffer[], uint32_t len) {
00326     //esp.flush();
00327     esp.printf("AT+CIPSEND=%d,%d\r\n", mux_id, len);
00328     if (recvFind(">", 5000)) {
00329         //esp.flush();
00330         for (uint32_t i = 0; i < len; i++) {
00331             esp.printf("%c",buffer[i]);
00332         }
00333         return recvFind("SEND OK", 10000);
00334     }
00335     return false;
00336 }
00337 
00338 bool ESP8266::sATCWSAP(string ssid, string pwd, uint8_t chl, uint8_t ecn)
00339 {
00340     string data;
00341     esp.printf("AT+CWSAP=\"%s\",\"%s\",%d,%d\r\n", ssid.c_str(), pwd.c_str(), chl, ecn);
00342     
00343     data = recvString("OK", "ERROR", 5000);
00344     if (data.find("OK") != std::string::npos) {
00345         return true;
00346     }
00347     return false;
00348 }
00349 
00350 bool ESP8266::sATCWDHCP(bool enabled, int mode) {
00351     if(mode < 0 || mode > 2) {
00352         return false;
00353     }
00354     esp.printf("AT+CWDHCP=%d,%d\r\n", enabled?1:0, mode);
00355     return recvFind("OK", 2000);
00356 }
00357 
00358 bool ESP8266::sATCIPSTA(string ip) {
00359     esp.printf("AT+CIPSTA=\"%s\"\r\n", ip.c_str());
00360     return recvFind("OK", 2000);
00361 }
00362 
00363 bool ESP8266::sATCIPAP(string ip) {
00364     esp.printf("AT+CIPAP=\"%s\"\r\n", ip.c_str());
00365     return recvFind("OK", 2000);
00366 }
00367 
00368 /************************* Private Callback Functions *************************/
00369 void ESP8266::RxInterrupt(void)
00370 {
00371     char c;
00372     
00373     c = esp.getc();                              //read the incoming character
00374     if(c == '\n') {
00375         //rxmsg_idx = 0;
00376         rxpass1=false;
00377         rxpass2=false;
00378         rxpass3=false;
00379         rxtemp_idx=0;
00380         //new_rxmsg=false;
00381     }
00382     
00383     if(rxpass1 && rxpass2 && rxpass3) {
00384         if(rxtemp_idx < packetLen-1) {
00385             rxtemp[rxtemp_idx] = c;
00386             rxtemp_idx++;
00387         }
00388         else {
00389             rxtemp[rxtemp_idx] = c;
00390             rxtemp[rxtemp_idx+1] = '\0';
00391             strcpy(packetData, rxtemp);
00392             //rxmsg_idx = 0;
00393             rxpass1=false;
00394             rxpass2=false;
00395             rxpass3=false;
00396             rxtemp_idx=0;
00397             new_rxmsg=true;
00398         }
00399     }
00400     else if(rxpass1 && rxpass2) {
00401         if(c != ':') {
00402             rxtemp[rxtemp_idx] = c;
00403             rxtemp_idx++;
00404         }
00405         else {
00406             rxtemp[rxtemp_idx] = '\0';
00407             packetLen= atoi(rxtemp);
00408             rxtemp_idx=0;
00409             rxpass3=true;
00410         }
00411     }
00412     else if(rxpass1) {
00413         if(c != ',') {
00414             rxtemp[rxtemp_idx] = c;
00415             rxtemp_idx++;
00416         }
00417         else {
00418             rxtemp[rxtemp_idx] = '\0';
00419             packetID = atoi(rxtemp);
00420             rxtemp_idx=0;
00421             rxpass2=true;
00422         }
00423     }
00424     else {
00425         rxtemp[rxtemp_idx] = c;
00426         rxtemp_idx++;
00427         
00428         if(rxtemp_idx == 6) {
00429             if(rxtemp[1] == '+' && rxtemp[2] == 'I' && rxtemp[3] == 'P' && rxtemp[4] == 'D' && rxtemp[5] == ',') {
00430                 rxpass1 = true;
00431             } 
00432         }
00433         /*
00434         rxmsg[rxmsg_idx] = c;
00435         rxmsg_idx++;
00436         
00437         if(rxmsg_idx == 6) {
00438             if(rxmsg[1] == '+' && rxmsg[2] == 'I' && rxmsg[3] == 'P' && rxmsg[4] == 'D' && rxmsg[5] == ',') {
00439                 rxpass1 = true;
00440             } 
00441         }*/
00442     }
00443 }