ESP8266 uart wifi module via AT command
Esp8266.cpp
- Committer:
- steeven
- Date:
- 2015-05-03
- Revision:
- 0:ee86ca9e494d
File content as of revision 0:ee86ca9e494d:
#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