Tuned for OS2 to reduce flash code size for smaller MCU's. Added further functions since 2018 v1.7 firmware. Improved faster large web page sending. Built in fast NTP Client time and RTC setting function. ATParser message handling improvements and updated.
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
Generated on Tue Jul 19 2022 11:38:05 by 1.7.2