source: rtos_arduino/trunk/arduino_lib/libraries/ESP8266/ESP8266.cpp@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 17.5 KB
Line 
1/**
2 * @file ESP8266.cpp
3 * @brief The implementation of class ESP8266.
4 * @author Wu Pengfei<pengfei.wu@itead.cc>
5 * @date 2015.02
6 *
7 * @par Copyright:
8 * Copyright (c) 2015 ITEAD Intelligent Systems Co., Ltd. \n\n
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version. \n\n
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 */
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
45ESP8266::begin(SoftwareSerial &uart, uint32_t baud)
46{
47 m_puart = &uart;
48 m_baud = baud;
49 m_puart->begin(baud);
50 rx_empty();
51}
52#else
53void ESP8266::begin(HardwareSerial &uart, uint32_t baud)
54{
55 m_puart = &uart;
56 m_baud = baud;
57 m_puart->begin(baud);
58 rx_empty();
59}
60#endif
61
62bool ESP8266::kick(void)
63{
64 return eAT();
65}
66
67bool ESP8266::restart(void)
68{
69 unsigned long start;
70 if (eATRST()) {
71 m_puart->end();
72 delay(2000);
73 m_puart->begin(m_baud);
74 start = millis();
75 while (millis() - start < 3000) {
76 if (eAT()) {
77 delay(1500); /* Waiting for stable */
78 return true;
79 }
80 delay(100);
81 }
82 }
83 return false;
84}
85
86String ESP8266::getVersion(void)
87{
88 String version;
89 eATGMR(version);
90 return version;
91}
92
93bool ESP8266::setOprToStation(void)
94{
95 uint8_t mode;
96 if (!qATCWMODE(&mode)) {
97 return false;
98 }
99 if (mode == 1) {
100 return true;
101 } else {
102 if (sATCWMODE(1) && restart()) {
103 return true;
104 } else {
105 return false;
106 }
107 }
108}
109
110bool ESP8266::setOprToSoftAP(void)
111{
112 uint8_t mode;
113 if (!qATCWMODE(&mode)) {
114 return false;
115 }
116 if (mode == 2) {
117 return true;
118 } else {
119 if (sATCWMODE(2) && restart()) {
120 return true;
121 } else {
122 return false;
123 }
124 }
125}
126
127bool ESP8266::setOprToStationSoftAP(void)
128{
129 uint8_t mode;
130 if (!qATCWMODE(&mode)) {
131 return false;
132 }
133 if (mode == 3) {
134 return true;
135 } else {
136 if (sATCWMODE(3) && restart()) {
137 return true;
138 } else {
139 return false;
140 }
141 }
142}
143
144String ESP8266::getAPList(void)
145{
146 String list;
147 eATCWLAP(list);
148 return list;
149}
150
151bool ESP8266::joinAP(String ssid, String pwd)
152{
153 return sATCWJAP(ssid, pwd);
154}
155
156bool ESP8266::leaveAP(void)
157{
158 return eATCWQAP();
159}
160
161bool ESP8266::setSoftAPParam(String ssid, String pwd, uint8_t chl, uint8_t ecn)
162{
163 return sATCWSAP(ssid, pwd, chl, ecn);
164}
165
166String ESP8266::getJoinedDeviceIP(void)
167{
168 String list;
169 eATCWLIF(list);
170 return list;
171}
172
173String ESP8266::getIPStatus(void)
174{
175 String list;
176 eATCIPSTATUS(list);
177 return list;
178}
179
180String ESP8266::getLocalIP(void)
181{
182 String list;
183 eATCIFSR(list);
184 return list;
185}
186
187bool ESP8266::enableMUX(void)
188{
189 return sATCIPMUX(1);
190}
191
192bool ESP8266::disableMUX(void)
193{
194 return sATCIPMUX(0);
195}
196
197bool ESP8266::createTCP(String addr, uint32_t port)
198{
199 return sATCIPSTARTSingle("TCP", addr, port);
200}
201
202bool ESP8266::releaseTCP(void)
203{
204 return eATCIPCLOSESingle();
205}
206
207bool ESP8266::registerUDP(String addr, uint32_t port)
208{
209 return sATCIPSTARTSingle("UDP", addr, port);
210}
211
212bool ESP8266::unregisterUDP(void)
213{
214 return eATCIPCLOSESingle();
215}
216
217bool ESP8266::createTCP(uint8_t mux_id, String addr, uint32_t port)
218{
219 return sATCIPSTARTMultiple(mux_id, "TCP", addr, port);
220}
221
222bool ESP8266::releaseTCP(uint8_t mux_id)
223{
224 return sATCIPCLOSEMulitple(mux_id);
225}
226
227bool ESP8266::registerUDP(uint8_t mux_id, String addr, uint32_t port)
228{
229 return sATCIPSTARTMultiple(mux_id, "UDP", addr, port);
230}
231
232bool ESP8266::unregisterUDP(uint8_t mux_id)
233{
234 return sATCIPCLOSEMulitple(mux_id);
235}
236
237bool ESP8266::setTCPServerTimeout(uint32_t timeout)
238{
239 return sATCIPSTO(timeout);
240}
241
242bool ESP8266::startTCPServer(uint32_t port)
243{
244 if (sATCIPSERVER(1, port)) {
245 return true;
246 }
247 return false;
248}
249
250bool ESP8266::stopTCPServer(void)
251{
252 sATCIPSERVER(0);
253 restart();
254 return false;
255}
256
257bool ESP8266::startServer(uint32_t port)
258{
259 return startTCPServer(port);
260}
261
262bool ESP8266::stopServer(void)
263{
264 return stopTCPServer();
265}
266
267bool ESP8266::send(const uint8_t *buffer, uint32_t len)
268{
269 return sATCIPSENDSingle(buffer, len);
270}
271
272bool ESP8266::send(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
273{
274 return sATCIPSENDMultiple(mux_id, buffer, len);
275}
276
277bool ESP8266::send(String &str)
278{
279 return sATCIPSENDSingle(str);
280}
281
282bool ESP8266::send(uint8_t mux_id, String &str)
283{
284 return sATCIPSENDMultiple(mux_id, str);
285}
286
287uint32_t ESP8266::recv(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
288{
289 return recvPkg(buffer, buffer_size, NULL, timeout, NULL);
290}
291
292uint32_t ESP8266::recv(uint8_t mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
293{
294 uint8_t id;
295 uint32_t ret;
296 ret = recvPkg(buffer, buffer_size, NULL, timeout, &id);
297 if (ret > 0 && id == mux_id) {
298 return ret;
299 }
300 return 0;
301}
302
303uint32_t ESP8266::recv(uint8_t *coming_mux_id, uint8_t *buffer, uint32_t buffer_size, uint32_t timeout)
304{
305 return recvPkg(buffer, buffer_size, NULL, timeout, coming_mux_id);
306}
307
308/*----------------------------------------------------------------------------*/
309/* +IPD,<id>,<len>:<data> */
310/* +IPD,<len>:<data> */
311
312uint32_t ESP8266::recvPkg(uint8_t *buffer, uint32_t buffer_size, uint32_t *data_len, uint32_t timeout, uint8_t *coming_mux_id)
313{
314 String data;
315 char a;
316 int32_t index_PIPDcomma = -1;
317 int32_t index_colon = -1; /* : */
318 int32_t index_comma = -1; /* , */
319 int32_t len = -1;
320 int8_t id = -1;
321 bool has_data = false;
322 uint32_t ret;
323 unsigned long start;
324 uint32_t i;
325
326 if (buffer == NULL) {
327 return 0;
328 }
329
330 start = millis();
331 while (millis() - start < timeout) {
332 if(m_puart->available() > 0) {
333 a = m_puart->read();
334 data += a;
335 }else{
336 delay(1);
337 }
338
339 index_PIPDcomma = data.indexOf("+IPD,");
340 if (index_PIPDcomma != -1) {
341 index_colon = data.indexOf(':', index_PIPDcomma + 5);
342 if (index_colon != -1) {
343 index_comma = data.indexOf(',', index_PIPDcomma + 5);
344 /* +IPD,id,len:data */
345 if (index_comma != -1 && index_comma < index_colon) {
346 id = data.substring(index_PIPDcomma + 5, index_comma).toInt();
347 if (id < 0 || id > 4) {
348 return 0;
349 }
350 len = data.substring(index_comma + 1, index_colon).toInt();
351 if (len <= 0) {
352 return 0;
353 }
354 } else { /* +IPD,len:data */
355 len = data.substring(index_PIPDcomma + 5, index_colon).toInt();
356 if (len <= 0) {
357 return 0;
358 }
359 }
360 has_data = true;
361 break;
362 }
363 }
364 }
365
366 if (has_data) {
367 i = 0;
368 ret = len > buffer_size ? buffer_size : len;
369 start = millis();
370 while (millis() - start < 3000) {
371 while(m_puart->available() > 0 && i < ret) {
372 a = m_puart->read();
373 buffer[i++] = a;
374 }
375 if (i == ret) {
376 rx_empty();
377 if (data_len) {
378 *data_len = len;
379 }
380 if (index_comma != -1 && coming_mux_id) {
381 *coming_mux_id = id;
382 }
383 return ret;
384 }
385 delay(1);
386 }
387 }
388 return 0;
389}
390
391void ESP8266::rx_empty(void)
392{
393 while(m_puart->available() > 0) {
394 m_puart->read();
395 }
396}
397
398String ESP8266::recvString(String target, uint32_t timeout)
399{
400 String data;
401 char a;
402 unsigned long start = millis();
403 while (millis() - start < timeout) {
404 while(m_puart->available() > 0) {
405 a = m_puart->read();
406 if(a == '\0') continue;
407 data += a;
408 }
409 if (data.indexOf(target) != -1) {
410 break;
411 }
412 delay(1);
413 }
414 return data;
415}
416
417String ESP8266::recvString(String target1, String target2, uint32_t timeout)
418{
419 String data;
420 char a;
421 unsigned long start = millis();
422 while (millis() - start < timeout) {
423 while(m_puart->available() > 0) {
424 a = m_puart->read();
425 if(a == '\0') continue;
426 data += a;
427 }
428 if (data.indexOf(target1) != -1) {
429 break;
430 } else if (data.indexOf(target2) != -1) {
431 break;
432 }
433 delay(1);
434 }
435 return data;
436}
437
438String ESP8266::recvString(String target1, String target2, String target3, uint32_t timeout)
439{
440 String data;
441 char a;
442 unsigned long start = millis();
443 while (millis() - start < timeout) {
444 while(m_puart->available() > 0) {
445 a = m_puart->read();
446 if(a == '\0') continue;
447 data += a;
448 }
449 if (data.indexOf(target1) != -1) {
450 break;
451 } else if (data.indexOf(target2) != -1) {
452 break;
453 } else if (data.indexOf(target3) != -1) {
454 break;
455 }
456 delay(1);
457 }
458 return data;
459}
460
461bool ESP8266::recvFind(String target, uint32_t timeout)
462{
463 String data_tmp;
464 data_tmp = recvString(target, timeout);
465 if (data_tmp.indexOf(target) != -1) {
466 return true;
467 }
468 return false;
469}
470
471bool ESP8266::recvFindAndFilter(String target, String begin, String end, String &data, uint32_t timeout)
472{
473 String data_tmp;
474 data_tmp = recvString(target, timeout);
475 if (data_tmp.indexOf(target) != -1) {
476 int32_t index1 = data_tmp.indexOf(begin);
477 int32_t index2 = data_tmp.indexOf(end);
478 if (index1 != -1 && index2 != -1) {
479 index1 += begin.length();
480 data = data_tmp.substring(index1, index2);
481 return true;
482 }
483 }
484 data = "";
485 return false;
486}
487
488bool ESP8266::eAT(void)
489{
490 rx_empty();
491 m_puart->println("AT");
492 return recvFind("OK");
493}
494
495bool ESP8266::eATRST(void)
496{
497 rx_empty();
498 m_puart->println("AT+RST");
499 return recvFind("OK");
500}
501
502bool ESP8266::eATGMR(String &version)
503{
504 rx_empty();
505 m_puart->println("AT+GMR");
506 return recvFindAndFilter("OK", "\r\r\n", "\r\nOK", version);
507}
508
509bool ESP8266::qATCWMODE(uint8_t *mode)
510{
511 String str_mode;
512 bool ret;
513 if (!mode) {
514 return false;
515 }
516 rx_empty();
517 m_puart->println("AT+CWMODE?");
518 ret = recvFindAndFilter("OK", "+CWMODE:", "\r\n\r\nOK", str_mode);
519 if (ret) {
520 *mode = (uint8_t)str_mode.toInt();
521 return true;
522 } else {
523 return false;
524 }
525}
526
527bool ESP8266::sATCWMODE(uint8_t mode)
528{
529 String data;
530 rx_empty();
531 m_puart->print("AT+CWMODE=");
532 m_puart->println(mode);
533
534 data = recvString("OK", "no change");
535 if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
536 return true;
537 }
538 return false;
539}
540
541bool ESP8266::sATCWJAP(String ssid, String pwd)
542{
543 String data;
544 rx_empty();
545 m_puart->print("AT+CWJAP=\"");
546 m_puart->print(ssid);
547 m_puart->print("\",\"");
548 m_puart->print(pwd);
549 m_puart->println("\"");
550
551 data = recvString("OK", "FAIL", 10000);
552 if (data.indexOf("OK") != -1) {
553 return true;
554 }
555 return false;
556}
557
558bool ESP8266::eATCWLAP(String &list)
559{
560 String data;
561 rx_empty();
562 m_puart->println("AT+CWLAP");
563 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list, 10000);
564}
565
566bool ESP8266::eATCWQAP(void)
567{
568 String data;
569 rx_empty();
570 m_puart->println("AT+CWQAP");
571 return recvFind("OK");
572}
573
574bool ESP8266::sATCWSAP(String ssid, String pwd, uint8_t chl, uint8_t ecn)
575{
576 String data;
577 rx_empty();
578 m_puart->print("AT+CWSAP=\"");
579 m_puart->print(ssid);
580 m_puart->print("\",\"");
581 m_puart->print(pwd);
582 m_puart->print("\",");
583 m_puart->print(chl);
584 m_puart->print(",");
585 m_puart->println(ecn);
586
587 data = recvString("OK", "ERROR", 5000);
588 if (data.indexOf("OK") != -1) {
589 return true;
590 }
591 return false;
592}
593
594bool ESP8266::eATCWLIF(String &list)
595{
596 String data;
597 rx_empty();
598 m_puart->println("AT+CWLIF");
599 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
600}
601bool ESP8266::eATCIPSTATUS(String &list)
602{
603 String data;
604 delay(100);
605 rx_empty();
606 m_puart->println("AT+CIPSTATUS");
607 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
608}
609bool ESP8266::sATCIPSTARTSingle(String type, String addr, uint32_t port)
610{
611 String data;
612 rx_empty();
613 m_puart->print("AT+CIPSTART=\"");
614 m_puart->print(type);
615 m_puart->print("\",\"");
616 m_puart->print(addr);
617 m_puart->print("\",");
618 m_puart->println(port);
619
620 data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
621 if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
622 return true;
623 }
624 return false;
625}
626bool ESP8266::sATCIPSTARTMultiple(uint8_t mux_id, String type, String addr, uint32_t port)
627{
628 String data;
629 rx_empty();
630 m_puart->print("AT+CIPSTART=");
631 m_puart->print(mux_id);
632 m_puart->print(",\"");
633 m_puart->print(type);
634 m_puart->print("\",\"");
635 m_puart->print(addr);
636 m_puart->print("\",");
637 m_puart->println(port);
638
639 data = recvString("OK", "ERROR", "ALREADY CONNECT", 10000);
640 if (data.indexOf("OK") != -1 || data.indexOf("ALREADY CONNECT") != -1) {
641 return true;
642 }
643 return false;
644}
645bool ESP8266::sATCIPSENDSingle(const uint8_t *buffer, uint32_t len)
646{
647 rx_empty();
648 m_puart->print("AT+CIPSEND=");
649 m_puart->println(len);
650 if (recvFind(">", 5000)) {
651 rx_empty();
652 for (uint32_t i = 0; i < len; i++) {
653 m_puart->write(buffer[i]);
654 }
655 return recvFind("SEND OK", 10000);
656 }
657 return false;
658}
659bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, const uint8_t *buffer, uint32_t len)
660{
661 rx_empty();
662 m_puart->print("AT+CIPSEND=");
663 m_puart->print(mux_id);
664 m_puart->print(",");
665 m_puart->println(len);
666 if (recvFind(">", 5000)) {
667 rx_empty();
668 for (uint32_t i = 0; i < len; i++) {
669 m_puart->write(buffer[i]);
670 }
671 return recvFind("SEND OK", 10000);
672 }
673 return false;
674}
675bool ESP8266::sATCIPSENDSingle(String &str)
676{
677 rx_empty();
678 m_puart->print("AT+CIPSEND=");
679 m_puart->println(str.length());
680 if (recvFind(">", 5000)) {
681 rx_empty();
682 for (uint32_t i = 0; i < str.length(); i++) {
683 m_puart->write(str.charAt(i));
684 }
685 return recvFind("SEND OK", 10000);
686 }
687 return false;
688}
689bool ESP8266::sATCIPSENDMultiple(uint8_t mux_id, String &str)
690{
691 rx_empty();
692 m_puart->print("AT+CIPSEND=");
693 m_puart->print(mux_id);
694 m_puart->print(",");
695 m_puart->println(str.length());
696 if (recvFind(">", 5000)) {
697 rx_empty();
698 for (uint32_t i = 0; i < str.length(); i++) {
699 m_puart->write(str.charAt(i));
700 }
701 return recvFind("SEND OK", 10000);
702 }
703 return false;
704}
705bool ESP8266::sATCIPCLOSEMulitple(uint8_t mux_id)
706{
707 String data;
708 rx_empty();
709 m_puart->print("AT+CIPCLOSE=");
710 m_puart->println(mux_id);
711
712 data = recvString("OK", "link is not", 5000);
713 if (data.indexOf("OK") != -1 || data.indexOf("link is not") != -1) {
714 return true;
715 }
716 return false;
717}
718bool ESP8266::eATCIPCLOSESingle(void)
719{
720 rx_empty();
721 m_puart->println("AT+CIPCLOSE");
722 return recvFind("OK", 5000);
723}
724bool ESP8266::eATCIFSR(String &list)
725{
726 rx_empty();
727 m_puart->println("AT+CIFSR");
728 return recvFindAndFilter("OK", "\r\r\n", "\r\n\r\nOK", list);
729}
730bool ESP8266::sATCIPMUX(uint8_t mode)
731{
732 String data;
733 rx_empty();
734 m_puart->print("AT+CIPMUX=");
735 m_puart->println(mode);
736
737 data = recvString("OK", "Link is builded");
738 if (data.indexOf("OK") != -1) {
739 return true;
740 }
741 return false;
742}
743bool ESP8266::sATCIPSERVER(uint8_t mode, uint32_t port)
744{
745 String data;
746 if (mode) {
747 rx_empty();
748 m_puart->print("AT+CIPSERVER=1,");
749 m_puart->println(port);
750
751 data = recvString("OK", "no change");
752 if (data.indexOf("OK") != -1 || data.indexOf("no change") != -1) {
753 return true;
754 }
755 return false;
756 } else {
757 rx_empty();
758 m_puart->println("AT+CIPSERVER=0");
759 return recvFind("\r\r\n");
760 }
761}
762bool ESP8266::sATCIPSTO(uint32_t timeout)
763{
764 rx_empty();
765 m_puart->print("AT+CIPSTO=");
766 m_puart->println(timeout);
767 return recvFind("OK");
768}
769
Note: See TracBrowser for help on using the repository browser.