Paul Staron / ESP8266-OS2

Dependencies:  

Dependents:   ESP8266-NTP-Test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ESP8266.cpp Source File

ESP8266.cpp

00001 
00002 #include "ESP8266.h"
00003 
00004 ESP8266::ESP8266(PinName tx, PinName rx, bool debug)
00005     : _serial(tx, rx, 1024), _parser(_serial)   // set our buffer to ESP max buffer size
00006 {
00007     _serial.baud(115200);
00008     _parser.debugOn(debug);
00009     _parser.send("ATE0");     // set no ESP echo
00010 }
00011 
00012 bool ESP8266::reset(void)
00013 {
00014     if (_parser.send("AT+RST")          // soft reset ESP
00015         && _parser.recv("OK\r\nready")
00016         && _parser.send("ATE0")     // set no ESP echo
00017         && _parser.recv("OK")) {
00018         return true;
00019         }   
00020     else return false;
00021 }
00022 
00023 bool ESP8266::startup(int mode)
00024 {
00025     //only 3 valid modes
00026     if(mode < 1 || mode > 3) {
00027         return false;
00028     }  
00029          _parser.send("AT+CWMODE=%d", mode)       //set mode 
00030         && _parser.recv("OK")
00031         && _parser.send("AT+CIPMUX=1") 
00032         && _parser.recv("OK");
00033      return true;
00034 }
00035 
00036 bool ESP8266::startServer(int mode,int port,int timeout)
00037 {    
00038         //only 3 valid modes
00039     if(mode < 1 || mode > 3) {
00040         return false;
00041     }
00042          _parser.send("AT+CWMODE=%d",mode)        //set mode
00043         && _parser.recv("OK")
00044         && _parser.send("AT+CIPMUX=1") 
00045         && _parser.recv("OK")
00046         && _parser.send("AT+CIPSERVER=1,%d",port)   //start server at port 80
00047         && _parser.recv("OK")    
00048         && _parser.send("AT+CIPSTO=%d",timeout)     //Server timeout=5 seconds
00049         && _parser.recv("OK");    
00050         
00051      return true;
00052 }
00053 
00054 const char *ESP8266::getFirmware(void)
00055 {
00056     int previous_timeout = _parser._timeout; // get current ESP timeout
00057     setTimeout(200);   
00058     _parser.send("AT+GMR");
00059     _parser.getESP((char*)_firmware);
00060      setTimeout(previous_timeout);   // restore previous ESP timeout       
00061     return _firmware;
00062 }
00063 
00064 bool ESP8266::dhcp(bool enabled, int mode)
00065 {
00066     //only 3 valid modes
00067     if(mode < 0 || mode > 2) {
00068         return false;
00069     }
00070     return _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode)
00071         && _parser.recv("OK");
00072 }
00073 
00074 bool ESP8266::connect(const char *ap, const char *passPhrase)
00075 {
00076     strcpy(_ssid, ap);
00077     return _parser.send("AT+CWJAP=\"%s\",\"%s\"", ap, passPhrase)
00078         && _parser.recv("OK");
00079 }
00080 
00081 bool ESP8266::disconnect(void)
00082 {
00083     return _parser.send("AT+CWQAP") && _parser.recv("OK");
00084 }
00085 
00086 const char *ESP8266::getIPAddress(void)
00087 {
00088     if (!(_parser.send("AT+CIFSR")
00089         && _parser.recv("+CIFSR:APIP,\"%[^\"]\"", _APIP_buffer)
00090         && _parser.recv("+CIFSR:APMAC,\"%[^\"]\"", _APMAC_buffer)
00091         && _parser.recv("+CIFSR:STAIP,\"%[^\"]\"", _STAIP_buffer)
00092         && _parser.recv("+CIFSR:STAMAC,\"%[^\"]\"", _STAMAC_buffer)
00093         && _parser.recv("OK"))) {
00094         return 0;
00095     }
00096     return _STAIP_buffer;
00097 }
00098 
00099 const char *ESP8266::getMACAddress(void)
00100 {
00101     if (!(_parser.send("AT+CIFSR")
00102         && _parser.recv("+CIFSR:STAMAC,\"%[^\"]\"", _STAMAC_buffer)
00103         && _parser.recv("OK"))) {
00104         return 0;
00105     }
00106     return _STAMAC_buffer;
00107 }
00108 
00109 bool ESP8266::isConnected(void)
00110 { 
00111     if(strcmp(getIPAddress(),"0.0.0.0")==0) {return 0;}
00112         else {return 1;}
00113 }
00114 
00115 bool ESP8266::open(const char *type, int id, const char* addr, int port)
00116 {
00117     //IDs only 0-4
00118     if(id > 4) {
00119         return false;
00120     }
00121     return _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port)
00122         && _parser.recv("OK");
00123 }
00124 
00125 bool ESP8266::send(int id, const void *data, uint32_t amount)
00126 {
00127     //May take a second try if device is busy
00128     for (unsigned i = 0; i < 2; i++) {
00129         if (_parser.send("AT+CIPSEND=%d,%d", id, amount)
00130             && _parser.recv(">")
00131             && _parser.write((char*)data, (int)amount) >= 0) {
00132             while(!_parser.recv("SEND OK"));    // wait for ESP response to confirm data sent
00133             return true;
00134         }
00135     }
00136     return false;
00137 }
00138 
00139 bool ESP8266::sendWebPage(int id, const char * page, uint32_t amount)
00140 {
00141     unsigned int lenOfPacketToTx;
00142     unsigned int pageToSendAddress=0;
00143     // we test for 'SEND OK' otherwise comms fail, this function needs to escape, 3 second timeout.
00144     t.reset();t.start();    
00145     while(amount>0 && t.read()<3){
00146         if(amount>2048){amount-=2048;lenOfPacketToTx=2048;} //ESP send buffer limit
00147             else{lenOfPacketToTx=amount;amount=0;}                                
00148         _parser.send("AT+CIPSEND=%d,%d", id, lenOfPacketToTx);
00149         while(!_parser.recv(">"));      // wait for ready to send >            
00150         page=(page+pageToSendAddress);            
00151         while(lenOfPacketToTx--){
00152             _parser.putc(*page++);      // send page data
00153         }
00154         pageToSendAddress+=lenOfPacketToTx;
00155         while(!_parser.recv("SEND OK") && t.read()<2);                    
00156     }
00157     memset(request,'\0',sizeof(request));
00158     ipdLen=0;t.stop();t.reset();
00159     if(t.read()>2) return false; // comms failed     
00160         else return true;     
00161 }
00162 
00163 const char *ESP8266::recvWebRequest(void )
00164 {   
00165     char dummy[50]; // this is not working as expected, we need add a 'dummy' field
00166     _parser.recv("+IPD,%d,%d:%s %s %s",&linkId,&ipdLen,requestType,request,dummy);
00167     return request;
00168 }
00169 
00170 int32_t ESP8266::recv(int id, void *data, uint32_t amount)
00171 {
00172     int32_t recv_amount = -1;
00173     int recv_id;
00174     if (!(_parser.recv("+IPD,%d,%d:", &recv_id, &recv_amount)
00175         && recv_id == id
00176         && recv_amount <= amount
00177         && _parser.read((char*)data, recv_amount)
00178         && _parser.recv("OK"))) {
00179     }
00180     return recv_amount;
00181 }
00182 
00183 bool ESP8266::close(int id)
00184 {
00185     int previous_timeout = _parser._timeout; // get current ESP timeout
00186     setTimeout(100);
00187     // May take a few try's if device is busy but keep short as possible ESP timeout retry delay.
00188     for (unsigned i = 0; i < 3; i++) {
00189         if (_parser.send("AT+CIPCLOSE=%d", id)
00190             && _parser.recv("OK")) {
00191             return true;
00192         }
00193     }
00194     setTimeout(previous_timeout);   // restore previous ESP timeout
00195     return false;
00196 }
00197 
00198 int8_t ESP8266::getRSSI()
00199 {
00200     int previous_timeout = _parser._timeout; // get current ESP timeout
00201     setTimeout(5000);
00202     _parser.send("AT+CWLAPOPT=1,4");    // get current connection
00203     _parser.recv("OK");    
00204     int8_t rssi;
00205     if (!(_parser.send("AT+CWLAP=\"%s\"", _ssid)
00206         && _parser.recv("+CWLAP:(%d)", &rssi)
00207         && _parser.recv("OK"))) {
00208     }
00209     setTimeout(previous_timeout);   // restore previous ESP timeout 
00210     return rssi;
00211 }
00212 
00213 int32_t ESP8266::getNTP(char * NTPpool,int tzoffset, int setRTC)
00214 {
00215     // example NTPpool = "1.nl.pool.ntp.org"
00216     // serial.printf("Seconds since 1970 = %d\r\n", esp.getNTP("1.nl.pool.ntp.org",3600));    
00217     const int NTP_PACKET_SIZE = 48;
00218     unsigned char packetBuffer[NTP_PACKET_SIZE];
00219     int NTP_OFFSET = (2208988800 - tzoffset);
00220     memset(packetBuffer, 0x00, NTP_PACKET_SIZE);
00221     // Initialize values needed to form NTP request
00222     packetBuffer[0]  = 0b11100011;      // LI, Version, Mode
00223     packetBuffer[1]  = 0;               // Stratum, or type of clock
00224     packetBuffer[2]  = 6;               // Polling Interval
00225     packetBuffer[3]  = 0xEC;            // Peer Clock Precision
00226     // [4]-[11]: 8 bytes of zero for Root Delay & Root Dispersion
00227     packetBuffer[12] = 49;
00228     packetBuffer[13] = 0x4E;
00229     packetBuffer[14] = 49;
00230     packetBuffer[15] = 52;
00231     int previous_timeout = _parser._timeout; // get current ESP timeout
00232     uint32_t recv_size = 0;
00233     int tries1 = 10;
00234     while ((recv_size != NTP_PACKET_SIZE) && (tries1 > 0)){
00235         tries1--;
00236         setTimeout(2000);        
00237         open("UDP", 1, NTPpool, 123);
00238         setTimeout(100);
00239         send(1, packetBuffer, NTP_PACKET_SIZE);
00240         int tries2 = 50;
00241         while ((recv_size != NTP_PACKET_SIZE) && (tries2 > 0)){
00242             tries2--;
00243             recv_size = recv(1, packetBuffer, NTP_PACKET_SIZE);
00244         }
00245     }
00246     setTimeout(previous_timeout);   // restore previous ESP timeout
00247     close(1);
00248     if(recv_size==48){
00249         uint32_t secsSince1970=((packetBuffer[40]<<24)|(packetBuffer[41]<<16)|(packetBuffer[42]<<8)|packetBuffer[43])-NTP_OFFSET;
00250         if (setRTC){set_time(secsSince1970);} // may need to add a second to offset any MCU delay
00251         return secsSince1970;
00252     }
00253     else{return 0;}   
00254 }
00255 
00256 void ESP8266::setTimeout(uint32_t timeout_ms)
00257 {
00258     _parser.setTimeout(timeout_ms);
00259 }
00260 
00261 bool ESP8266::readable()
00262 {
00263     return _serial.readable();
00264 }
00265 
00266 bool ESP8266::writeable()
00267 {
00268     return _serial.writeable();
00269 }
00270