ESP8266 uart wifi module via AT command
Fork of ESP8266 by
Esp8266.h
- Committer:
- ninad
- Date:
- 2016-11-15
- Revision:
- 2:dcd2bd05e1f7
- Parent:
- 1:32714c2fb1a9
File content as of revision 2:dcd2bd05e1f7:
#ifndef ESP8266_H_ #define ESP8266_H_ #include "mbed.h" #include "BufferedSerial.h" #define WIFI_TIME_OUT 5000 #define _DBG 1 #if _DBG==1 #define DBG(msg...) do{if(_logger && _dbg) _logger->printf(msg);}while(0) #define LOG(msg...) do{if(_logger) _logger->printf(msg);}while(0) #else #define DBG(msg...) #define LOG(msg...) #endif #define ASSERT(eval,msg...) if((r=eval)<=0) { LOG("%s():%d result: %d\n", __FUNCTION__, __LINE__, r); return r;} namespace steeven { /** Esp8266 WiFi serial module. * Warnning: * CH_PD pin has to connect VCC to boot from internal flash! * Command has to end with "\r\n" * If you can't get full AT output, set console same baudrate or higher, or set wifi baudrate low!!! * DO NOT print console if you want get a long result from internet. * Some bad data at beginning because the baudrate changed to 74880 * \r: 0xd \n: 0xa */ class Esp8266 { public: /** * * @param pin LED pin with PWM support * @param time Time for the brightness transition * @param hold Time for holding the brightness before next transition. * Effective for loop mode. */ Esp8266(PinName tx, PinName rx, PinName ch_pd, PinName rst, int baudrate = 115200) : _ch_pd(ch_pd), _rst(rst), _uart(tx, rx) { _uart.baud(baudrate); // _uart.attach(this, &Esp8266::on_rx, SerialBase::RxIrq); _timer.start(); _timeout_ms = WIFI_TIME_OUT; _ch_pd = 0; //uart mode _rst = 0; //reset } void init(); void wait_rst(); // 1: client, 2: AP, 3: mixed void switchClientMode(int mode); int connect(const char *ap, const char *pswd); int send(const char *host, int port, const char *tx, void (*cb)(char *, int) = NULL); void set_log(BufferedSerial* logger, int dbg) { _logger = logger; _dbg = dbg; } void log(char ch) { if (_logger) { _logger->putc(ch); if (_dbg > 1) { _logger->printf("[%x]", ch); } } } void dbg(char ch) { if (_logger == NULL || _dbg == 0) return; _logger->putc(ch); } void dbg(const char *msg) { if (_logger == NULL || _dbg == 0) return; _logger->puts(msg); } void dbg(const char * type, const char *msg) { if (_logger == NULL || _dbg == 0) return; _logger->printf("::wifi:: %s: %s\n", type, msg); } void clear() { while (_uart.readable()) { log(_uart.getc()); } } /* * query result of a command, command must end with '?' * >>>AT+CWMODE? * <<<+CWMODE:3 * <<<OK * cmd CWMODE, result is 3. */ char* query(const char *cmd) { int r; int len = strlen(cmd) - 3; r = cmd_data(cmd, _buf, sizeof(_buf)); if (r < 0) { dbg("query", "failed"); return NULL; } dbg("query result", _buf); if (r < len + 2) { // has to be: +CMD:xxx dbg("query", "invalid result length"); return NULL; } if (memcmp(cmd + 2, _buf, len) != 0) { //check: +CMD dbg("query", "length not match"); return NULL; } if (_buf[len] != ':') { dbg("query", "\":\" not found"); return NULL; } return _buf + len + 1; } int query_int(const char *cmd) { return atoi(query(cmd)); } int query_match(const char *cmd, const char *r) { return strcmp(query(cmd), r); } /** * Read data until match or reach max size * return * size of data * -3: timeout * -1: get error pattern */ int read_until(char *buf, int max, const char *p_ok = "OK\r\n", const char *p_error = "ERROR\r\n") { int i = 0, i_ok = 0, i_err = 0; char ch; int ok_size = strlen(p_ok); int err_size = strlen(p_error); while (1) { while (_uart.readable()) { ch = _uart.getc(); if (buf) buf[i] = ch; log(ch); i++; //check ok pattern if (p_ok) { if (p_ok[i_ok] != ch) { if (i_ok > 0 && _logger && _dbg > 0) _logger->putc('*'); i_ok = 0; } if (p_ok[i_ok] == ch) { i_ok++; if (i_ok > 0) if (_logger && _dbg > 1) _logger->putc('_'); if (i_ok == ok_size) { //found ok pattern if (buf) buf[i - ok_size] = 0; dbg("match", "done\n"); return i - ok_size; } } } //check error pattern if (p_error) { if (p_error[i_err] != ch) i_err = 0; if (p_error[i_err] == ch) { i_err++; if (i_err == err_size) { //match error if (buf) buf[i - err_size] = 0; dbg("match", "error\n"); return -1; } } } if (buf) { if (i >= max) { dbg("buffer", "overflow\n"); // buf[i-1] = 0; return i; } } else { // Just continue check ok/error } } if (_timer.read_ms() > _timeout_ms) { dbg("cmd", "timeout\n"); return -3; } } } int cmd_send(const char* cmd, const char *echo = NULL) { int r = 0; _uart.attach(NULL, SerialBase::RxIrq); _uart.puts(cmd); _uart.puts("\r\n"); dbg("cmd", "sent"); //check echo if (echo == NULL) echo = cmd; if (echo && strlen(echo) > 0) { r = read_until(NULL, 0, echo, NULL); if (r < 0) { dbg("cmd", "no echo"); return r; } r = read_until(NULL, 0, "\r\r\n", NULL); if (r < 0) { dbg("cmd", "no echo end"); return r; } } dbg("cmd", "sent"); return r; } /** every command has to end with "\r\n" * * >>>cmd * <<<cmd * <<<data * <<<OK/ERROR * <<< * * return size of result * 0: ok * -1: if error * -2: if buffer overflow * -3: timeout * others: size of content */ int cmd_data(const char *cmd, char* ret = NULL, int size = 0, int timeout_ms = WIFI_TIME_OUT, const char *end = "OK\r\n", const char *echo = NULL) { int r = 0; _timer.reset(); _timeout_ms = timeout_ms; dbg("cmd", cmd); clear(); dbg("cmd", "cleared"); if (cmd) { if ((r = cmd_send(cmd, echo)) < 0) { dbg("cmd", "send failed"); return r; } } if (end != NULL) { /* check OK or ERROR */ dbg("cmd", "matching end..."); if ((r = read_until(ret, size, end)) < 0) dbg("cmd", "check end failed"); return r; } clear(); dbg("cmd", "cleared"); dbg("cmd", "complete"); return r; } void ipd_rx(); // virtual ~Esp8266(); BufferedSerial *_logger; int _dbg; protected: void ipd_dect(); DigitalOut _ch_pd; //ESP8266 CH_PD pin DigitalOut _rst; //ESP8266 reset pin Serial _uart; char _buf[1600]; Timer _timer; int _timeout_ms; int _rcv_start; //"+IPD,xxx:" int _rcv_cnt; // total buffer used int _rcv_exp; // expected size void (*_rcv_cb)(char *buf, int len); } ; } #endif /* ESP8266_H_ */