ESP8266 uart wifi module via AT command
Esp8266.cpp@0:ee86ca9e494d, 2015-05-03 (annotated)
- Committer:
- steeven
- Date:
- Sun May 03 14:45:51 2015 +0000
- Revision:
- 0:ee86ca9e494d
ESP8266 driver module
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
steeven | 0:ee86ca9e494d | 1 | #include <ESP8266/Esp8266.h> |
steeven | 0:ee86ca9e494d | 2 | |
steeven | 0:ee86ca9e494d | 3 | namespace steeven { |
steeven | 0:ee86ca9e494d | 4 | |
steeven | 0:ee86ca9e494d | 5 | void Esp8266::init() { |
steeven | 0:ee86ca9e494d | 6 | _ch_pd = 1; |
steeven | 0:ee86ca9e494d | 7 | _rst = 1; |
steeven | 0:ee86ca9e494d | 8 | wait_rst(); |
steeven | 0:ee86ca9e494d | 9 | cmd_data("AT+GMR"); //get version |
steeven | 0:ee86ca9e494d | 10 | |
steeven | 0:ee86ca9e494d | 11 | } |
steeven | 0:ee86ca9e494d | 12 | |
steeven | 0:ee86ca9e494d | 13 | void Esp8266::wait_rst() { |
steeven | 0:ee86ca9e494d | 14 | cmd_data(NULL, NULL, 0, 10000, "\r\nready\r\n"); |
steeven | 0:ee86ca9e494d | 15 | } |
steeven | 0:ee86ca9e494d | 16 | |
steeven | 0:ee86ca9e494d | 17 | // 1: client, 2: AP, 3: mixed |
steeven | 0:ee86ca9e494d | 18 | void Esp8266::switchClientMode(int mode) { |
steeven | 0:ee86ca9e494d | 19 | int reset = 0; |
steeven | 0:ee86ca9e494d | 20 | |
steeven | 0:ee86ca9e494d | 21 | //remembered in flash, don't change and restart if not changed. |
steeven | 0:ee86ca9e494d | 22 | if (query_int("AT+CWMODE?") != mode) { |
steeven | 0:ee86ca9e494d | 23 | sprintf(_buf, "AT+CWMODE=%d", mode); |
steeven | 0:ee86ca9e494d | 24 | cmd_data(_buf); |
steeven | 0:ee86ca9e494d | 25 | reset = 1; |
steeven | 0:ee86ca9e494d | 26 | } |
steeven | 0:ee86ca9e494d | 27 | if (query_int("AT+CIPMUX?") != 0) { |
steeven | 0:ee86ca9e494d | 28 | cmd_data("AT+CIPMUX=0", NULL, 0, 3000, "OK\r"); // no multiple connection |
steeven | 0:ee86ca9e494d | 29 | reset = 1; |
steeven | 0:ee86ca9e494d | 30 | } |
steeven | 0:ee86ca9e494d | 31 | if (reset) { |
steeven | 0:ee86ca9e494d | 32 | cmd_data("AT+RST"); |
steeven | 0:ee86ca9e494d | 33 | wait_rst(); |
steeven | 0:ee86ca9e494d | 34 | } |
steeven | 0:ee86ca9e494d | 35 | } |
steeven | 0:ee86ca9e494d | 36 | |
steeven | 0:ee86ca9e494d | 37 | int Esp8266::connect(const char *ap, const char *pswd) { |
steeven | 0:ee86ca9e494d | 38 | char buf[100]; |
steeven | 0:ee86ca9e494d | 39 | int n = 0; |
steeven | 0:ee86ca9e494d | 40 | const char *noip = "+CIFSR:STAIP,\"0.0.0.0\""; |
steeven | 0:ee86ca9e494d | 41 | |
steeven | 0:ee86ca9e494d | 42 | if (strcmp(ap, query("AT+CWJAP?")) != 0) { |
steeven | 0:ee86ca9e494d | 43 | sprintf(buf, "AT+SWJAP=\"%s\",\"%s\"", ap, pswd); |
steeven | 0:ee86ca9e494d | 44 | cmd_data(buf); |
steeven | 0:ee86ca9e494d | 45 | } |
steeven | 0:ee86ca9e494d | 46 | |
steeven | 0:ee86ca9e494d | 47 | while (cmd_data("AT+CIFSR", buf, sizeof(buf)) && n++ < 10) { |
steeven | 0:ee86ca9e494d | 48 | if (memcmp(buf, noip, strlen(noip)) != 0) |
steeven | 0:ee86ca9e494d | 49 | return 1; |
steeven | 0:ee86ca9e494d | 50 | wait(0.3); |
steeven | 0:ee86ca9e494d | 51 | } |
steeven | 0:ee86ca9e494d | 52 | return 0; |
steeven | 0:ee86ca9e494d | 53 | } |
steeven | 0:ee86ca9e494d | 54 | |
steeven | 0:ee86ca9e494d | 55 | int Esp8266::send(const char *host, int port, const char *tx, |
steeven | 0:ee86ca9e494d | 56 | void (*cb)(char *, int)) { |
steeven | 0:ee86ca9e494d | 57 | char buf[100]; |
steeven | 0:ee86ca9e494d | 58 | int r; |
steeven | 0:ee86ca9e494d | 59 | |
steeven | 0:ee86ca9e494d | 60 | ASSERT(cmd_data("AT+CIPMODE=0")); //none-transparent data xfer mode |
steeven | 0:ee86ca9e494d | 61 | //TODO |
steeven | 0:ee86ca9e494d | 62 | cmd_data("AT+CIPCLOSE"); |
steeven | 0:ee86ca9e494d | 63 | // AT+CIPSTART="TCP","www.baidu.com",80 |
steeven | 0:ee86ca9e494d | 64 | sprintf(buf, "AT+CIPSTART=\"TCP\",\"%s\",%d", host, port); |
steeven | 0:ee86ca9e494d | 65 | ASSERT(cmd_data(buf)); |
steeven | 0:ee86ca9e494d | 66 | sprintf(buf, "AT+CIPSEND=%d", strlen(tx)); |
steeven | 0:ee86ca9e494d | 67 | // AT+CIPSEND=4 |
steeven | 0:ee86ca9e494d | 68 | ASSERT(cmd_data(buf, NULL, 0, 5000, "OK\r\n", NULL)); |
steeven | 0:ee86ca9e494d | 69 | // _dbg = 2; |
steeven | 0:ee86ca9e494d | 70 | ASSERT(cmd_data(tx, NULL, 0, 5000, "SEND OK\r\n\r\n", "")); |
steeven | 0:ee86ca9e494d | 71 | // _dbg = 0; |
steeven | 0:ee86ca9e494d | 72 | _rcv_cnt = 0; |
steeven | 0:ee86ca9e494d | 73 | _rcv_exp = 0; |
steeven | 0:ee86ca9e494d | 74 | _rcv_start = 0; |
steeven | 0:ee86ca9e494d | 75 | _rcv_cb = cb; |
steeven | 0:ee86ca9e494d | 76 | _uart.attach(this, &Esp8266::ipd_rx, SerialBase::RxIrq); |
steeven | 0:ee86ca9e494d | 77 | return 1; |
steeven | 0:ee86ca9e494d | 78 | } |
steeven | 0:ee86ca9e494d | 79 | |
steeven | 0:ee86ca9e494d | 80 | //Esp8266::~Esp8266() { |
steeven | 0:ee86ca9e494d | 81 | // _uart.close(); |
steeven | 0:ee86ca9e494d | 82 | //} |
steeven | 0:ee86ca9e494d | 83 | |
steeven | 0:ee86ca9e494d | 84 | //"+IPD,xxx:" |
steeven | 0:ee86ca9e494d | 85 | void Esp8266::ipd_dect() { |
steeven | 0:ee86ca9e494d | 86 | int i; |
steeven | 0:ee86ca9e494d | 87 | DBG("testing IPD...\n"); |
steeven | 0:ee86ca9e494d | 88 | if (memcmp("+IPD,", _buf, 5) == 0) { |
steeven | 0:ee86ca9e494d | 89 | DBG("IPD found...\n"); |
steeven | 0:ee86ca9e494d | 90 | for (i = 5; i < _rcv_cnt; ++i) { |
steeven | 0:ee86ca9e494d | 91 | if (_buf[i] >= '0' && _buf[i] <= '9') |
steeven | 0:ee86ca9e494d | 92 | continue; |
steeven | 0:ee86ca9e494d | 93 | if (_buf[i] == ':') { |
steeven | 0:ee86ca9e494d | 94 | DBG("':' found...\n"); |
steeven | 0:ee86ca9e494d | 95 | _buf[i] = 0; |
steeven | 0:ee86ca9e494d | 96 | break; |
steeven | 0:ee86ca9e494d | 97 | } |
steeven | 0:ee86ca9e494d | 98 | } |
steeven | 0:ee86ca9e494d | 99 | if (i == _rcv_cnt) //not found |
steeven | 0:ee86ca9e494d | 100 | return; |
steeven | 0:ee86ca9e494d | 101 | _rcv_exp = atoi(&_buf[5]); |
steeven | 0:ee86ca9e494d | 102 | _rcv_start = i + 1; |
steeven | 0:ee86ca9e494d | 103 | log('['); |
steeven | 0:ee86ca9e494d | 104 | DBG("IPD:%d %d\n", _rcv_start, _rcv_exp); |
steeven | 0:ee86ca9e494d | 105 | } else if (memcmp(_buf, "CLOSED", 5) == 0) { |
steeven | 0:ee86ca9e494d | 106 | DBG("connection closed\n"); |
steeven | 0:ee86ca9e494d | 107 | if (_rcv_cb != NULL) |
steeven | 0:ee86ca9e494d | 108 | _rcv_cb(NULL, 0); //end of rcv |
steeven | 0:ee86ca9e494d | 109 | _rcv_cb = NULL; |
steeven | 0:ee86ca9e494d | 110 | //notify receiver |
steeven | 0:ee86ca9e494d | 111 | _uart.attach(NULL, SerialBase::RxIrq); |
steeven | 0:ee86ca9e494d | 112 | } |
steeven | 0:ee86ca9e494d | 113 | } |
steeven | 0:ee86ca9e494d | 114 | |
steeven | 0:ee86ca9e494d | 115 | void Esp8266::ipd_rx() { |
steeven | 0:ee86ca9e494d | 116 | char ch; |
steeven | 0:ee86ca9e494d | 117 | int i = 0; |
steeven | 0:ee86ca9e494d | 118 | while (_uart.readable()) { |
steeven | 0:ee86ca9e494d | 119 | ch = _uart.getc(); |
steeven | 0:ee86ca9e494d | 120 | log(ch); |
steeven | 0:ee86ca9e494d | 121 | if (_rcv_exp == 0 && (ch == '\r' || ch == '\n')) { |
steeven | 0:ee86ca9e494d | 122 | DBG("ignore leading blank"); |
steeven | 0:ee86ca9e494d | 123 | continue; |
steeven | 0:ee86ca9e494d | 124 | } |
steeven | 0:ee86ca9e494d | 125 | _buf[_rcv_cnt++] = ch; |
steeven | 0:ee86ca9e494d | 126 | i++; |
steeven | 0:ee86ca9e494d | 127 | if (_rcv_exp == 0) { |
steeven | 0:ee86ca9e494d | 128 | if (_rcv_cnt > 5 && _rcv_cnt <= 11) { // expecting "+IPD:xxx" or "CLOSED" |
steeven | 0:ee86ca9e494d | 129 | ipd_dect(); |
steeven | 0:ee86ca9e494d | 130 | } |
steeven | 0:ee86ca9e494d | 131 | if (_rcv_cnt>11 && _rcv_exp==0) { //failed to detect IPD |
steeven | 0:ee86ca9e494d | 132 | _uart.attach(NULL, SerialBase::RxIrq); |
steeven | 0:ee86ca9e494d | 133 | _buf[_rcv_cnt] = 0; |
steeven | 0:ee86ca9e494d | 134 | LOG("\nFailed to detect IPD: %s", _buf); |
steeven | 0:ee86ca9e494d | 135 | return; |
steeven | 0:ee86ca9e494d | 136 | } |
steeven | 0:ee86ca9e494d | 137 | } |
steeven | 0:ee86ca9e494d | 138 | if (_rcv_cnt >= (int) sizeof(_buf)) { |
steeven | 0:ee86ca9e494d | 139 | error("rx buffer overflow size\n"); |
steeven | 0:ee86ca9e494d | 140 | } |
steeven | 0:ee86ca9e494d | 141 | if (_rcv_exp > 0 && _rcv_exp + _rcv_start == _rcv_cnt) { //reach end of pkt |
steeven | 0:ee86ca9e494d | 142 | if (_rcv_cb != NULL) |
steeven | 0:ee86ca9e494d | 143 | _rcv_cb(&_buf[_rcv_start], _rcv_exp); //end of IPD |
steeven | 0:ee86ca9e494d | 144 | _rcv_exp = 0; |
steeven | 0:ee86ca9e494d | 145 | _rcv_cnt = 0; |
steeven | 0:ee86ca9e494d | 146 | _rcv_start = 0; |
steeven | 0:ee86ca9e494d | 147 | log(']'); |
steeven | 0:ee86ca9e494d | 148 | } |
steeven | 0:ee86ca9e494d | 149 | } |
steeven | 0:ee86ca9e494d | 150 | DBG(" %d %d\n", i, _rcv_cnt); |
steeven | 0:ee86ca9e494d | 151 | } |
steeven | 0:ee86ca9e494d | 152 | |
steeven | 0:ee86ca9e494d | 153 | } // namespace steeven |