| API For Arduino developers

- Main Page
- Related Pages
- Classes
- Files
- Examples

- File List

ESP8266.cpp
Go to the documentation of this file.
1
21 #include "ESP8266.h"
22
23 #define LOG_OUTPUT_DEBUG (1)
24 #define LOG_OUTPUT_DEBUG_PREFIX (1)
25
26 #define logDebug(arg)\
27 do {\
28 if (LOG_OUTPUT_DEBUG)\
29 {\
30 if (LOG_OUTPUT_DEBUG_PREFIX)\
31 {\
32 Serial.print("[LOG Debug: ");\
33 Serial.print((const char*)__FILE__);\
34 Serial.print(",");\
35 Serial.print((unsigned int)__LINE__);\
36 Serial.print(",");\
37 Serial.print((const char*)__FUNCTION__);\
38 Serial.print("] ");\
39 }\
40 Serial.print(arg);\
41 }\
42 } while(0)
43
44 #ifdef ESP8266_USE_SOFTWARE_SERIAL
45 ESP8266::ESP8266(SoftwareSerial &uart, uint32_t baud): m_puart(&uart)
46 {
47 m_puart->begin(baud);
48 rx_empty();
49 }
50 #else
51 ESP8266::ESP8266(HardwareSerial &uart, uint32_t baud): m_puart(&uart)
52 {
53 m_puart->begin(baud);
54 rx_empty();
55 }
56 #endif
57
58 bool ESP8266::kick(void)
59 {
60 return eAT();
61 }
62
63 bool ESP8266::restart(void)
64 {
65 unsigned long start;
66 if (eATRST()) {
67 delay(2000);
68 start = millis();
69 while (millis() - start < 3000) {
70 if (eAT()) {
71 delay(1500); /* Waiting for stable */
72 return true;
73 }
74 delay(100);
75 }
76 }
77 return false;
78 }
79
80 String ESP8266::getVersion(void)
81 {
82 String version;
83 eATGMR(version);
84 return version;
85 }
86
87 bool ESP8266::setOprToStation(void)
88 {
89 uint8_t mode;
90 if (!qATCWMODE(&mode)) {
91 return false;
92 }
93 if (mode == 1) {
94 return true;
95 } else {
96 if (sATCWMODE(1) && restart()) {
97 return true;
98 } else {
99 return false;
100 }
101 }
102 }
103
104 bool ESP8266::setOprToSoftAP(void)
105 {
106 uint8_t mode;
107 if (!qATCWMODE(&mode)) {
108 return false;
109 }
110 if (mode == 2) {
111 return true;
112 } else {
113 if (sATCWMODE(2) && restart()) {
114 return true;
115 } else {
116 return false;
117 }
118 }
119 }
120
121 bool ESP8266::setOprToStationSoftAP(void)
122 {
123 uint8_t mode;
124 if (!qATCWMODE(&mode)) {
125 return false;
126 }
127 if (mode == 3) {
128 return true;
129 } else {
130 if (sATCWMODE(3) && restart()) {
131 return true;
132 } else {
133 return false;
134 }
135 }
136 }
137
138 String ESP8266::getAPList(void)
139 {
140 String list;
141 eATCWLAP(list);
142 return list;
143 }
144
145 bool ESP8266::joinAP(String ssid, String pwd)
146 {
147 return sATCWJAP(ssid, pwd);
148 }
149
150 bool ESP8266::leaveAP(void)
151 {
152 return eATCWQAP();
153 }
154
155 bool ESP8266::setSoftAPParam(String ssid, String pwd, uint8_t chl, uint8_t ecn)
156 {
157 return sATCWSAP(ssid, pwd, chl, ecn);
158 }
159
160 String ESP8266::getJoinedDeviceIP(void)
161 {
162 String list;
163 eATCWLIF(list);
164 return list;
165 }
166
167 String ESP8266::getIPStatus(void)
168 {
169 String list;
170 eATCIPSTATUS(list);
171 return list;
172 }
173
174 String ESP8266::getLocalIP(void)
175 {
176 String list;
177 eATCIFSR(list);
178 return list;
179 }
180
181 bool ESP8266::enableMUX(void)
182 {
183 return sATCIPMUX(1);
184 }
185
186 bool ESP8266::disableMUX(void)
187 {
188 return sATCIPMUX(0);
189 }
190
191 bool ESP8266::createTCP(String addr, uint32_t port)
192 {
193 return sATCIPSTARTSingle("TCP", addr, port);
194 }
195
196 bool ESP8266::releaseTCP(void)
197 {
198 return eATCIPCLOSESingle();
199 }
200
201 bool ESP8266::registerUDP(String addr, uint32_t port)
202 {
203 return sATCIPSTARTSingle("UDP", addr, port);
204 }
205
206 bool ESP8266::unregisterUDP(void)
207 {
208 return eATCIPCLOSESingle();
209 }
210
211 bool ESP8266::createTCP(uint8_t mux_id, String addr, uint32_t port)
212 {
213 return sATCIPSTARTMultiple(mux_id, "TCP", addr, port);
214 }
215
216 bool ESP8266::releaseTCP(uint8_t mux_id)
217 {
218 return sATCIPCLOSEMulitple(mux_id);
219 }
220
221 bool ESP8266::registerUDP(uint8_t mux_id, String addr, uint32_t port)
222 {
223 return sATCIPSTARTMultiple(mux_id, "UDP", addr, port);
224 }
225
226 bool ESP8266::unregisterUDP(uint8_t mux_id)
227 {
228 return sATCIPCLOSEMulitple(mux_id);
229 }
230
231 bool ESP8266::setTCPServerTimeout(uint32_t timeout)
232 {
233 return sATCIPSTO(timeout);
234 }
235
236 bool ESP8266::startTCPServer(uint32_t port)
237 {
238 if (sATCIPSERVER(1, port)) {
239 return true;
240 }
241 return false;
242 }
243
244 bool ESP8266::stopTCPServer(void)
245 {
246 sATCIPSERVER(0);
247 restart();
248 return false;
249 }
250
251 bool ESP8266::startServer(uint32_t port)
252 {
253 return startTCPServer(port);
254 }
255
256 bool ESP8266::stopServer(void)
257 {
258 return stopTCPServer();
259 }
260
261 bool ESP8266::send(const uint8_t *buffer, uint32_t len)
262 {
263 return sATCIPSENDSingle(buffer, len);
264 }
265
266 bool ESP8266::send(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
267 {
268 return sATCIPSENDMultiple(mux_id, buffer, len);
269 }
270
271 uint32_t ESP8266::recv(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
272 {
273 return recvPkg(buffer, buffer_size, NULL, timeout, NULL);
274 }
275
276 uint32_t ESP8266::recv(uint8_t mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
277 {
278 uint8_t id;
279 uint32_t ret;
280 ret = recvPkg(buffer, buffer_size, NULL, timeout, &id);
281 if (ret > 0 && id == mux_id) {
282 return ret;
283 }
284 return 0;
285 }
286
287 uint32_t ESP8266::recv(uint8_t *coming_mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
288 {
289 return recvPkg(buffer, buffer_size, NULL, timeout, coming_mux_id);
290 }
291
292 /*----------------------------------------------------------------------------*/
293
294 uint32_t ESP8266::recvPkg(uint8_t *buffer, uint32_t buffer_size, uint32_t *data_len, uint32_t timeout, uint8_t *coming_mux_id)
295 {
296 String data;
297 char a;
298 int32_t index_PIPDcomma = -1;
299 int32_t index_colon = -1; /* : */
300 int32_t index_comma = -1; /* , */
301 int32_t len = -1;
302 int8_t id = -1;
303 bool has_data = false;
304 //logDebug("start recv pkg");
305
306 unsigned long start = millis();
307 while (millis() - start < timeout) {
308 while(m_puart->available() > 0) {
309 a = m_puart->read();
310 data += a;
311 }
312
313 index_PIPDcomma = data.indexOf("+IPD,");
314 if (index_PIPDcomma != -1) {
315 //logDebug("index_PIPDcomma found = %d", index_PIPDcomma);
316 index_colon = data.indexOf(':', index_PIPDcomma + 5);
317 if (index_colon != -1) {
318 //logDebug("data1 = %s\r\n", data.c_str());
319 //logDebug("index_colon found = %d", index_colon);
320
321 index_comma = data.indexOf(',', index_PIPDcomma + 5);
322 //logDebug("index_comma found = %d", index_comma);
323
324 if (index_comma != -1 && index_comma < index_colon) { /* +IPD,id,len:data */
325 //logDebug("id = %d", id);
326 id = data.substring(index_PIPDcomma + 5, index_comma).toInt();
327 //logDebug("id = %d", id);
328 if (id < 0 || id > 4) {
329 return 0;
330 }
331 //logDebug("len = %d", len);
332 len = data.substring(index_comma + 1, index_colon).toInt();
333 //logDebug("len = %d", len);
334 if (len <= 0) {
335 return 0;
336 }
337 //logDebug("has id");
338 } else { /* +IPD,len:data */
339 len = data.substring(index_PIPDcomma + 5, index_colon).toInt();
340 //logDebug("len = %d", len);
341 if (len <= 0) {
342 return 0;
343 }
344 //logDebug("no id");
345 }
346 has_data = true;
347 //logDebug("has_data true");
348 break;
349 }
350 }
351 }
352 //logDebug("has_data = %u\r\n", has_data);
353 //logDebug("data2 = %s\r\n", data.c_str());
354
355 if (has_data) {
356 start = millis();
357 while (millis() - start < 3000) {
358 while(m_puart->available() > 0) {
359 a = m_puart->read();
360 data += a;
361 }
362 //logDebug("data3 = %s\r\n", data.c_str());
363 if (data.length() >= index_colon + 1 + len) {
364 if (data_len) {
365 *data_len = len;
366 }
367 if (index_comma != -1 && coming_mux_id) {
368 *coming_mux_id = id;
369 }
370 //logDebug("len = %d", len);
371 //logDebug("buffer_size = %d", buffer_size);
372 uint32_t ret = len > buffer_size ? buffer_size : len;
373
374 memcpy(buffer,
375 data.substring(index_colon + 1, index_colon + 1 + len).c_str(),
376 ret);
377 //logDebug("ret = %u\r\n", ret);
378 return ret;
379 }
380 }
381 }
382 //logDebug("end recv pkg");
383 return 0;
384 }
385
386 void ESP8266::rx_empty(void)
387 {
388 while(m_puart->available() > 0) {
389 m_puart->read();
390 }
391 }
392
393 String ESP8266::recvString(String target, uint32_t timeout)
394 {
395 String data;
396 char a;
397 unsigned long start = millis();
398 while (millis() - start < timeout) {
399 while(m_puart->available() > 0) {
400 a = m_puart->read();
401 if(a == '\0') continue;
402 data += a;
403 }
404 if (data.indexOf(target) != -1) {
405 break;
406 }
407 }
408 return data;
409 }
410
411 String ESP8266::recvString(String target1, String target2, uint32_t timeout)
412 {
413 String data;
414 char a;
415 unsigned long start = millis();
416 while (millis() - start < timeout) {
417 while(m_puart->available() > 0) {
418 a = m_puart->read();
419 if(a == '\0') continue;
420 data += a;
421 }
422 if (data.indexOf(target1) != -1) {
423 break;
424 } else if (data.indexOf(target2) != -1) {
425 break;
426 }
427 }
428 return data;
429 }
430
431 String ESP8266::recvString(String target1, String target2, String target3, uint32_t timeout)
432 {
433 String data;
434 char a;
435 unsigned long start = millis();
436 while (millis() - start < timeout) {
437 while(m_puart->available() > 0) {
438 a = m_puart->read();
439 if(a == '\0') continue;
440 data += a;
441 }
442 if (data.indexOf(target1) != -1) {
443 break;
444 } else if (data.indexOf(target2) != -1) {
445 break;
446 } else if (data.indexOf(target3) != -1) {
447 break;
448 }
449 }
450 return data;
451 }
452
453 bool ESP8266::recvFind(String target, uint32_t timeout)
454 {
455 String data_tmp;
456 data_tmp = recvString(target, timeout);
457 if (data_tmp.indexOf(target) != -1) {
458 return true;
459 }
460 return false;
461 }
462
463 bool ESP8266::recvFindAndFilter(String target, String begin, String end, String &data, uint32_t timeout)
464 {
465 String data_tmp;
466 data_tmp = recvString(target, timeout);
467 if (data_tmp.indexOf(target) != -1) {
468 int32_t index1 = data_tmp.indexOf(begin);
469 int32_t index2 = data_tmp.indexOf(end);
470 if (index1 != -1 && index2 != -1) {
471 index1 += begin.length();
472 data = data_tmp.substring(index1, index2);
473 return true;
474 }
475 }
476 data = "";
477 return false;
478 }
479
480 bool ESP8266::eAT(void)
481 {
482 rx_empty();
483 m_puart->println("AT");
484 return recvFind("OK");
485 }
486
487 bool ESP8266::eATRST(void)
488 {
489 rx_empty();
490 m_puart->println("AT+RST");
491 return recvFind("OK");
492 }
493
494 bool ESP8266::eATGMR(String &version)
495 {
496 rx_empty();
497 m_puart->println("AT+GMR");
498 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", version);
499 }
500
501 bool ESP8266::qATCWMODE(uint8_t *mode)
502 {
503 String str_mode;
504 bool ret;
505 if (!mode) {
506 return false;
507 }
508 rx_empty();
509 m_puart->println("AT+CWMODE?");
510 ret = recvFindAndFilter("OK", "+CWMODE:", "\r\n\r\nOK", str_mode);
511 if (ret) {
512 *mode = (uint8_t)str_mode.toInt();
513 return true;
514 } else {
515 return false;
516 }
517 }
518
519 bool ESP8266::sATCWMODE(uint8_t mode)
520 {
521 String data;
522 rx_empty();
523 m_puart->print("AT+CWMODE=");
524 m_puart->println(mode);
525
526 data = recvString("OK", "no change");
527 if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
528 return true;
529 }
530 return false;
531 }
532
533 bool ESP8266::sATCWJAP(String ssid, String pwd)
534 {
535 String data;
536 rx_empty();
537 m_puart->print("AT+CWJAP=\"");
538 m_puart->print(ssid);
539 m_puart->print("\",\"");
540 m_puart->print(pwd);
541 m_puart->println("\"");
542
543 data = recvString("OK", "FAIL", 10000);
544 if (data.indexOf("OK") != -1) {
545 return true;
546 }
547 return false;
548 }
549
550 bool ESP8266::eATCWLAP(String &list)
551 {
552 String data;
553 rx_empty();
554 m_puart->println("AT+CWLAP");
555 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 10000);
556 }
557
558 bool ESP8266::eATCWQAP(void)
559 {
560 String data;
561 rx_empty();
562 m_puart->println("AT+CWQAP");
563 return recvFind("OK");
564 }
565
566 bool ESP8266::sATCWSAP(String ssid, String pwd, uint8_t chl, uint8_t ecn)
567 {
568 String data;
569 rx_empty();
570 m_puart->print("AT+CWSAP=\"");
571 m_puart->print(ssid);
572 m_puart->print("\",\"");
573 m_puart->print(pwd);
574 m_puart->print("\",");
575 m_puart->print(chl);
576 m_puart->print(",");
577 m_puart->println(ecn);
578
579 data = recvString("OK", "ERROR", 5000);
580 if (data.indexOf("OK") != -1) {
581 return true;
582 }
583 return false;
584 }
585
586 bool ESP8266::eATCWLIF(String &list)
587 {
588 String data;
589 rx_empty();
590 m_puart->println("AT+CWLIF");
591 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
592 }
593 bool ESP8266::eATCIPSTATUS(String &list)
594 {
595 String data;
596 delay(100);
597 rx_empty();
598 m_puart->println("AT+CIPSTATUS");
599 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
600 }
601 bool ESP8266::sATCIPSTARTSingle(String type, String addr, uint32_t port)
602 {
603 String data;
604 rx_empty();
605 m_puart->print("AT+CIPSTART=\"");
606 m_puart->print(type);
607 m_puart->print("\",\"");
608 m_puart->print(addr);
609 m_puart->print("\",");
610 m_puart->println(port);
611
612 data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
613 if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
614 return true;
615 }
616 return false;
617 }
618 bool ESP8266::sATCIPSTARTMultiple(uint8_t mux_id, String type, String addr, uint32_t port)
619 {
620 String data;
621 rx_empty();
622 m_puart->print("AT+CIPSTART=");
623 m_puart->print(mux_id);
624 m_puart->print(",\"");
625 m_puart->print(type);
626 m_puart->print("\",\"");
627 m_puart->print(addr);
628 m_puart->print("\",");
629 m_puart->println(port);
630
631 data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
632 if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
633 return true;
634 }
635 return false;
636 }
637 bool ESP8266::sATCIPSENDSingle(const uint8_t *buffer, uint32_t len)
638 {
639 rx_empty();
640 m_puart->print("AT+CIPSEND=");
641 m_puart->println(len);
642 if (recvFind(">", 5000)) {
643 rx_empty();
644 for (uint32_t i = 0; i < len; i++) {
645 m_puart->write(buffer[i]);
646 }
647 return recvFind("SEND OK", 10000);
648 }
649 return false;
650 }
651 bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
652 {
653 rx_empty();
654 m_puart->print("AT+CIPSEND=");
655 m_puart->print(mux_id);
656 m_puart->print(",");
657 m_puart->println(len);
658 if (recvFind(">", 5000)) {
659 rx_empty();
660 for (uint32_t i = 0; i < len; i++) {
661 m_puart->write(buffer[i]);
662 }
663 return recvFind("SEND OK", 10000);
664 }
665 return false;
666 }
667 bool ESP8266::sATCIPCLOSEMulitple(uint8_t mux_id)
668 {
669 String data;
670 rx_empty();
671 m_puart->print("AT+CIPCLOSE=");
672 m_puart->println(mux_id);
673
674 data = recvString("OK", "link is not", 5000);
675 if (data.indexOf("OK") != -1 || data.indexOf("link is not") != -1) {
676 return true;
677 }
678 return false;
679 }
680 bool ESP8266::eATCIPCLOSESingle(void)
681 {
682 rx_empty();
683 m_puart->println("AT+CIPCLOSE");
684 return recvFind("OK", 5000);
685 }
686 bool ESP8266::eATCIFSR(String &list)
687 {
688 rx_empty();
689 m_puart->println("AT+CIFSR");
690 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
691 }
692 bool ESP8266::sATCIPMUX(uint8_t mode)
693 {
694 String data;
695 rx_empty();
696 m_puart->print("AT+CIPMUX=");
697 m_puart->println(mode);
698
699 data = recvString("OK", "Link is builded");
700 if (data.indexOf("OK") != -1) {
701 return true;
702 }
703 return false;
704 }
705 bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port)
706 {
707 String data;
708 if (mode) {
709 rx_empty();
710 m_puart->print("AT+CIPSERVER=1,");
711 m_puart->println(port);
712
713 data = recvString("OK", "no change");
714 if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
715 return true;
716 }
717 return false;
718 } else {
719 rx_empty();
720 m_puart->println("AT+CIPSERVER=0");
721 return recvFind("\r\r\n");
722 }
723 }
724 bool ESP8266::sATCIPSTO(uint32_t timeout)
725 {
726 rx_empty();
727 m_puart->print("AT+CIPSTO=");
728 m_puart->println(timeout);
729 return recvFind("OK");
730 }
731
ESP8266::send
bool send(const uint8_t *buffer, uint32_t len)
Send data based on TCP or UDP builded already in single mode.
Definition: ESP8266.cpp:261
ESP8266::getVersion
String getVersion(void)
Get the version of AT Command Set.
Definition: ESP8266.cpp:80
ESP8266::releaseTCP
bool releaseTCP(void)
Release TCP connection in single mode.
Definition: ESP8266.cpp:196
ESP8266::recv
uint32_t recv(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout=1000)
Receive data from TCP or UDP builded already in single mode.
Definition: ESP8266.cpp:271
ESP8266::enableMUX
bool enableMUX(void)
Enable IP MUX(multiple connection mode).
Definition: ESP8266.cpp:181
ESP8266::getLocalIP
String getLocalIP(void)
Get the IP address of ESP8266.
Definition: ESP8266.cpp:174
ESP8266::setOprToSoftAP
bool setOprToSoftAP(void)
Set operation mode to softap.
Definition: ESP8266.cpp:104
ESP8266.h
The definition of class ESP8266.
ESP8266::setOprToStationSoftAP
bool setOprToStationSoftAP(void)
Set operation mode to station + softap.
Definition: ESP8266.cpp:121
ESP8266::createTCP
bool createTCP(String addr, uint32_t port)
Create TCP connection in single mode.
Definition: ESP8266.cpp:191
ESP8266::unregisterUDP
bool unregisterUDP(void)
Unregister UDP port number in single mode.
Definition: ESP8266.cpp:206
ESP8266::startServer
bool startServer(uint32_t port=333)
Start Server(Only in multiple mode).
Definition: ESP8266.cpp:251
ESP8266::stopTCPServer
bool stopTCPServer(void)
Stop TCP Server(Only in multiple mode).
Definition: ESP8266.cpp:244
ESP8266::stopServer
bool stopServer(void)
Stop Server(Only in multiple mode).
Definition: ESP8266.cpp:256
ESP8266::disableMUX
bool disableMUX(void)
Disable IP MUX(single connection mode).
Definition: ESP8266.cpp:186
ESP8266::restart
bool restart(void)
Restart ESP8266 by "AT+RST".
Definition: ESP8266.cpp:63
ESP8266::kick
bool kick(void)
Verify ESP8266 whether live or not.
Definition: ESP8266.cpp:58
ESP8266::joinAP
bool joinAP(String ssid, String pwd)
Join in AP.
Definition: ESP8266.cpp:145
ESP8266::registerUDP
bool registerUDP(String addr, uint32_t port)
Register UDP port number in single mode.
Definition: ESP8266.cpp:201
ESP8266::leaveAP
bool leaveAP(void)
Leave AP joined before.
Definition: ESP8266.cpp:150
ESP8266::setTCPServerTimeout
bool setTCPServerTimeout(uint32_t timeout=180)
Set the timeout of TCP Server.
Definition: ESP8266.cpp:231
ESP8266::startTCPServer
bool startTCPServer(uint32_t port=333)
Start TCP Server(Only in multiple mode).
Definition: ESP8266.cpp:236
ESP8266::setSoftAPParam
bool setSoftAPParam(String ssid, String pwd, uint8_t chl=7, uint8_t ecn=4)
Set SoftAP parameters.
Definition: ESP8266.cpp:155
ESP8266::setOprToStation
bool setOprToStation(void)
Set operation mode to staion.
Definition: ESP8266.cpp:87
ESP8266::getAPList
String getAPList(void)
Search available AP list and return it.
Definition: ESP8266.cpp:138
ESP8266::getIPStatus
String getIPStatus(void)
Get the current status of connection(UDP and TCP).
Definition: ESP8266.cpp:167
ESP8266::getJoinedDeviceIP
String getJoinedDeviceIP(void)
Get the IP list of devices connected to SoftAP.
Definition: ESP8266.cpp:160