ESP8266 uart wifi module via AT command

Dependencies:   BufferedSerial

Dependents:   esb_gcc

Fork of ESP8266 by steeven lee

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