ESP8266 uart wifi module via AT command
Fork of ESP8266 by
Diff: Esp8266.cpp
- Revision:
- 0:ee86ca9e494d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Esp8266.cpp Sun May 03 14:45:51 2015 +0000 @@ -0,0 +1,153 @@ +#include <ESP8266/Esp8266.h> + +namespace steeven { + +void Esp8266::init() { + _ch_pd = 1; + _rst = 1; + wait_rst(); + cmd_data("AT+GMR"); //get version + +} + +void Esp8266::wait_rst() { + cmd_data(NULL, NULL, 0, 10000, "\r\nready\r\n"); +} + +// 1: client, 2: AP, 3: mixed +void Esp8266::switchClientMode(int mode) { + int reset = 0; + + //remembered in flash, don't change and restart if not changed. + if (query_int("AT+CWMODE?") != mode) { + sprintf(_buf, "AT+CWMODE=%d", mode); + cmd_data(_buf); + reset = 1; + } + if (query_int("AT+CIPMUX?") != 0) { + cmd_data("AT+CIPMUX=0", NULL, 0, 3000, "OK\r"); // no multiple connection + reset = 1; + } + if (reset) { + cmd_data("AT+RST"); + wait_rst(); + } +} + +int Esp8266::connect(const char *ap, const char *pswd) { + char buf[100]; + int n = 0; + const char *noip = "+CIFSR:STAIP,\"0.0.0.0\""; + + if (strcmp(ap, query("AT+CWJAP?")) != 0) { + sprintf(buf, "AT+SWJAP=\"%s\",\"%s\"", ap, pswd); + cmd_data(buf); + } + + while (cmd_data("AT+CIFSR", buf, sizeof(buf)) && n++ < 10) { + if (memcmp(buf, noip, strlen(noip)) != 0) + return 1; + wait(0.3); + } + return 0; +} + +int Esp8266::send(const char *host, int port, const char *tx, + void (*cb)(char *, int)) { + char buf[100]; + int r; + + ASSERT(cmd_data("AT+CIPMODE=0")); //none-transparent data xfer mode + //TODO + cmd_data("AT+CIPCLOSE"); + // AT+CIPSTART="TCP","www.baidu.com",80 + sprintf(buf, "AT+CIPSTART=\"TCP\",\"%s\",%d", host, port); + ASSERT(cmd_data(buf)); + sprintf(buf, "AT+CIPSEND=%d", strlen(tx)); + // AT+CIPSEND=4 + ASSERT(cmd_data(buf, NULL, 0, 5000, "OK\r\n", NULL)); +// _dbg = 2; + ASSERT(cmd_data(tx, NULL, 0, 5000, "SEND OK\r\n\r\n", "")); +// _dbg = 0; + _rcv_cnt = 0; + _rcv_exp = 0; + _rcv_start = 0; + _rcv_cb = cb; + _uart.attach(this, &Esp8266::ipd_rx, SerialBase::RxIrq); + return 1; +} + +//Esp8266::~Esp8266() { +// _uart.close(); +//} + +//"+IPD,xxx:" +void Esp8266::ipd_dect() { + int i; + DBG("testing IPD...\n"); + if (memcmp("+IPD,", _buf, 5) == 0) { + DBG("IPD found...\n"); + for (i = 5; i < _rcv_cnt; ++i) { + if (_buf[i] >= '0' && _buf[i] <= '9') + continue; + if (_buf[i] == ':') { + DBG("':' found...\n"); + _buf[i] = 0; + break; + } + } + if (i == _rcv_cnt) //not found + return; + _rcv_exp = atoi(&_buf[5]); + _rcv_start = i + 1; + log('['); + DBG("IPD:%d %d\n", _rcv_start, _rcv_exp); + } else if (memcmp(_buf, "CLOSED", 5) == 0) { + DBG("connection closed\n"); + if (_rcv_cb != NULL) + _rcv_cb(NULL, 0); //end of rcv + _rcv_cb = NULL; + //notify receiver + _uart.attach(NULL, SerialBase::RxIrq); + } +} + +void Esp8266::ipd_rx() { + char ch; + int i = 0; + while (_uart.readable()) { + ch = _uart.getc(); + log(ch); + if (_rcv_exp == 0 && (ch == '\r' || ch == '\n')) { + DBG("ignore leading blank"); + continue; + } + _buf[_rcv_cnt++] = ch; + i++; + if (_rcv_exp == 0) { + if (_rcv_cnt > 5 && _rcv_cnt <= 11) { // expecting "+IPD:xxx" or "CLOSED" + ipd_dect(); + } + if (_rcv_cnt>11 && _rcv_exp==0) { //failed to detect IPD + _uart.attach(NULL, SerialBase::RxIrq); + _buf[_rcv_cnt] = 0; + LOG("\nFailed to detect IPD: %s", _buf); + return; + } + } + if (_rcv_cnt >= (int) sizeof(_buf)) { + error("rx buffer overflow size\n"); + } + if (_rcv_exp > 0 && _rcv_exp + _rcv_start == _rcv_cnt) { //reach end of pkt + if (_rcv_cb != NULL) + _rcv_cb(&_buf[_rcv_start], _rcv_exp); //end of IPD + _rcv_exp = 0; + _rcv_cnt = 0; + _rcv_start = 0; + log(']'); + } + } + DBG(" %d %d\n", i, _rcv_cnt); +} + +} // namespace steeven