ESP8266 Socket Library. AT Thinker firmware.

Dependents:   ESP8266_MQTT_HelloWorld ESP8266_IFTTT_Test ECE_4180_Lab_4 websocketmbed ... more

Fork of ESP8266Interface by ESP8266

This repository has been superceded

This project has moved to https://developer.mbed.org/teams/ESP8266/code/esp8266-driver/

This library works with the AT Thinker firmware.

Note

This library is currently in Beta. It is not feature complete and has some bugs, proceed with caution! Fixes and patches are welcome and appreciated!

Currently the ESP8266Interface Library has the following Abilities:

Working

  • TCP Client
  • UDP Client
  • Transparent mode (single connection of 1 type at a time)
  • Station Mode (connects to AP)

To be implemented

  • TCP Server
  • UDP Server
  • Multi Connection Mode (able to have up to 5 sockets at a time)
  • AP Mode (Make ESP Chip act like access point)
  • DNS Support (currently websites must be looked up by IP)
  • Error Recovery

Nice but not necessary

  • colorized text for ESP AT Commands in Command line (easier to differentiate from other text)
Committer:
sarahmarshy
Date:
Wed Jun 10 15:47:33 2015 +0000
Revision:
48:03fd9333670d
Parent:
47:1f4dd0e91837
ESP8266 was changing ssid spaces to "$". Unecessary. Removed this feature.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 1:fb4494783863 1 /* Copyright (C) 2012 mbed.org, MIT License
samux 1:fb4494783863 2 *
samux 1:fb4494783863 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
samux 1:fb4494783863 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
samux 1:fb4494783863 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
samux 1:fb4494783863 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
samux 1:fb4494783863 7 * furnished to do so, subject to the following conditions:
samux 1:fb4494783863 8 *
samux 1:fb4494783863 9 * The above copyright notice and this permission notice shall be included in all copies or
samux 1:fb4494783863 10 * substantial portions of the Software.
samux 1:fb4494783863 11 *
samux 1:fb4494783863 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
samux 1:fb4494783863 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
samux 1:fb4494783863 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
samux 1:fb4494783863 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
samux 1:fb4494783863 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
samux 1:fb4494783863 17 */
samux 1:fb4494783863 18
samux 1:fb4494783863 19 #include "mbed.h"
michaeljkoster 13:41098c907200 20 #include "ESP8266.h"
michaeljkoster 16:3f0efaa57a12 21 #include "Endpoint.h"
samux 1:fb4494783863 22 #include <string>
samux 1:fb4494783863 23 #include <algorithm>
samux 1:fb4494783863 24
samux 1:fb4494783863 25 //Debug is disabled by default
sarahmarshy 46:913d07795182 26 #if 0
mbedAustin 42:3f62103a4f3c 27 #define DBG(x, ...) printf("[ESP8266 : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
mbedAustin 42:3f62103a4f3c 28 #define WARN(x, ...) printf("[ESP8266 : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
mbedAustin 42:3f62103a4f3c 29 #define ERR(x, ...) printf("[ESP8266 : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
samux 1:fb4494783863 30 #else
sarahmarshy 46:913d07795182 31 #define DBG(x, ...) //wait_us(10);
sarahmarshy 46:913d07795182 32 #define WARN(x, ...) //wait_us(10);
samux 1:fb4494783863 33 #define ERR(x, ...)
samux 1:fb4494783863 34 #endif
samux 1:fb4494783863 35
mbedAustin 47:1f4dd0e91837 36 #if 0
mbedAustin 42:3f62103a4f3c 37 #define INFO(x, ...) printf("[ESP8266 : INFO]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
samux 1:fb4494783863 38 #else
samux 1:fb4494783863 39 #define INFO(x, ...)
samux 1:fb4494783863 40 #endif
samux 1:fb4494783863 41
mbedAustin 30:c035696b9397 42 #define ESP_MAX_TRY_JOIN 3
mbedAustin 30:c035696b9397 43 #define ESP_MAXID 4 // the largest possible ID Value (max num of sockets possible)
samux 1:fb4494783863 44
michaeljkoster 13:41098c907200 45 ESP8266 * ESP8266::inst;
mbedAustin 29:939372104145 46 char* ip = NULL;
samux 1:fb4494783863 47
sam_grove 40:0a83315aea0a 48 ESP8266::ESP8266(PinName tx, PinName rx, PinName reset, const char *ssid, const char *phrase, uint32_t baud) :
sam_grove 40:0a83315aea0a 49 wifi(tx, rx), reset_pin(reset), buf_ESP8266(ESP_MBUFFE_MAX)
samux 1:fb4494783863 50 {
mbedAustin 36:e1545c6c2cb3 51 INFO("Initializing ESP8266 object");
samux 1:fb4494783863 52 memset(&state, 0, sizeof(state));
samux 1:fb4494783863 53
sarahmarshy 48:03fd9333670d 54
samux 1:fb4494783863 55 strcpy(this->ssid, ssid);
samux 1:fb4494783863 56 strcpy(this->phrase, phrase);
samux 1:fb4494783863 57 inst = this;
samux 1:fb4494783863 58 attach_rx(false);
mbedAustin 28:91e65e22e63a 59
mbedAustin 28:91e65e22e63a 60 wifi.baud(baud); // initial baud rate of the ESP8266
mbedAustin 28:91e65e22e63a 61
michaeljkoster 22:c4360e61486a 62 state.associated = false;
michaeljkoster 22:c4360e61486a 63 state.cmdMode = false;
samux 1:fb4494783863 64 }
samux 1:fb4494783863 65
michaeljkoster 13:41098c907200 66 bool ESP8266::join()
samux 1:fb4494783863 67 {
michaeljkoster 23:de9221771e96 68 sendCommand( "AT+CWMODE=1", "change", NULL, 1000);
michaeljkoster 16:3f0efaa57a12 69 string cmd="AT+CWJAP=\""+(string)this->ssid+"\",\""+(string)this->phrase+"\"";
mbedAustin 28:91e65e22e63a 70 if( sendCommand( cmd.c_str(), "OK", NULL, 10000) ) {
michaeljkoster 16:3f0efaa57a12 71 // successfully joined the network
samux 1:fb4494783863 72 state.associated = true;
mbedAustin 37:6887e61cf674 73 INFO("ssid: %s, phrase: %s", this->ssid, this->phrase);
samux 1:fb4494783863 74 return true;
samux 1:fb4494783863 75 }
samux 1:fb4494783863 76 return false;
samux 1:fb4494783863 77 }
samux 1:fb4494783863 78
michaeljkoster 13:41098c907200 79 bool ESP8266::connect()
samux 1:fb4494783863 80 {
mbedAustin 28:91e65e22e63a 81 sendCommand("AT+CWDHCP=1,1","OK",NULL,1000); // DHCP Enabled in Station Mode
mbedAustin 28:91e65e22e63a 82 return ESP8266::join();
samux 1:fb4494783863 83 }
samux 1:fb4494783863 84
michaeljkoster 15:37a7a56a424f 85 bool ESP8266::is_connected()
michaeljkoster 15:37a7a56a424f 86 {
michaeljkoster 15:37a7a56a424f 87 return true;
michaeljkoster 15:37a7a56a424f 88 }
michaeljkoster 15:37a7a56a424f 89
mbedAustin 30:c035696b9397 90 bool ESP8266::start(bool type,char* ip, int port, int id)
mbedAustin 30:c035696b9397 91 {
mbedAustin 30:c035696b9397 92 // Error Check
mbedAustin 30:c035696b9397 93 if(id > ESP_MAXID) {
mbedAustin 30:c035696b9397 94 ERR("startUDPMulti: max id is: %d, id given is %d",ESP_MAXID,id);
mbedAustin 30:c035696b9397 95 return false;
mbedAustin 30:c035696b9397 96 }
mbedAustin 30:c035696b9397 97 // Single Connection Mode
mbedAustin 30:c035696b9397 98 if(id < 0) {
mbedAustin 30:c035696b9397 99 DBG("Start Single Connection Mode");
mbedAustin 30:c035696b9397 100 char portstr[5];
mbedAustin 30:c035696b9397 101 char idstr[2];
mbedAustin 30:c035696b9397 102 bool check [3] = {0};
mbedAustin 30:c035696b9397 103 sprintf(idstr,"%d",id);
mbedAustin 30:c035696b9397 104 sprintf(portstr, "%d", port);
mbedAustin 30:c035696b9397 105 switch(type) {
mbedAustin 30:c035696b9397 106 case ESP_UDP_TYPE : //UDP
mbedAustin 32:cf071dc33972 107 check[0] = sendCommand(( "AT+CIPSTART=\"UDP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
mbedAustin 30:c035696b9397 108 break;
mbedAustin 30:c035696b9397 109 case ESP_TCP_TYPE : //TCP
mbedAustin 32:cf071dc33972 110 check[0] = sendCommand(( "AT+CIPSTART=\"TCP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
mbedAustin 30:c035696b9397 111 break;
mbedAustin 30:c035696b9397 112 default:
mbedAustin 30:c035696b9397 113 ERR("Default hit for starting connection, this shouldnt be possible!!");
mbedAustin 30:c035696b9397 114 break;
mbedAustin 30:c035696b9397 115 }
mbedAustin 30:c035696b9397 116 check[1] = sendCommand("AT+CIPMODE=1", "OK", NULL, 1000);// go into transparent mode
mbedAustin 30:c035696b9397 117 check[2] = sendCommand("AT+CIPSEND", ">", NULL, 1000);// go into transparent mode
mbedAustin 30:c035696b9397 118 // check that all commands were sucessful
mbedAustin 32:cf071dc33972 119 if(check[0] and check[1] and check[2]) {
mbedAustin 30:c035696b9397 120 state.cmdMode = false;
mbedAustin 30:c035696b9397 121 return true;
mbedAustin 30:c035696b9397 122 } else {
mbedAustin 36:e1545c6c2cb3 123 ERR("startUDPTransparent Failed for ip:%s, port:%d",ip,port);
mbedAustin 30:c035696b9397 124 return false;
mbedAustin 30:c035696b9397 125 }
mbedAustin 30:c035696b9397 126 }
mbedAustin 30:c035696b9397 127 // Multi Connection Mode
mbedAustin 30:c035696b9397 128 else {
mbedAustin 30:c035696b9397 129 //TODO: impliment Multi Connection Mode
mbedAustin 30:c035696b9397 130 ERR("Not currently Supported!");
mbedAustin 30:c035696b9397 131 return false;
mbedAustin 32:cf071dc33972 132
mbedAustin 32:cf071dc33972 133 // DBG("Start Multi Connection Mode");
mbedAustin 32:cf071dc33972 134 // char portstr[5];
mbedAustin 32:cf071dc33972 135 // char idstr[2];
mbedAustin 32:cf071dc33972 136 // bool check [3] = {0};
mbedAustin 32:cf071dc33972 137 // sprintf(idstr,"%d",id);
mbedAustin 32:cf071dc33972 138 // sprintf(portstr, "%d", port);
mbedAustin 32:cf071dc33972 139 // switch(type) {
mbedAustin 32:cf071dc33972 140 // case ESP_UDP_TYPE : //UDP
mbedAustin 32:cf071dc33972 141 // check[0] = sendCommand(( "AT+CIPSTART=" + (string) idstr + ",\"UDP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
mbedAustin 32:cf071dc33972 142 // break;
mbedAustin 32:cf071dc33972 143 // case ESP_TCP_TYPE : //TCP
mbedAustin 32:cf071dc33972 144 // check[0] = sendCommand(( "AT+CIPSTART=" + (string) idstr + ",\"TCP\",\"" + (string) ip + "\"," + (string) portstr ).c_str(), "OK", NULL, 10000);
mbedAustin 32:cf071dc33972 145 // break;
mbedAustin 32:cf071dc33972 146 // default:
mbedAustin 32:cf071dc33972 147 // ERR("Default hit for starting connection, this shouldnt be possible!!");
mbedAustin 32:cf071dc33972 148 // break;
mbedAustin 32:cf071dc33972 149 // }
mbedAustin 30:c035696b9397 150 }
mbedAustin 30:c035696b9397 151 }
mbedAustin 30:c035696b9397 152
sarahmarshy 44:3a7b6083210b 153 bool ESP8266::startUDP(char* ip, int port, int id, int length)
mbedAustin 28:91e65e22e63a 154 {
michaeljkoster 17:d11fa4c3ac65 155 char portstr[5];
sarahmarshy 44:3a7b6083210b 156 char idstr[1];
sarahmarshy 44:3a7b6083210b 157 char lenstr[2];
sarahmarshy 44:3a7b6083210b 158
michaeljkoster 16:3f0efaa57a12 159 sprintf(portstr, "%d", port);
sarahmarshy 44:3a7b6083210b 160 sprintf(idstr, "%d", id);
sarahmarshy 44:3a7b6083210b 161 sprintf(lenstr, "%d", length);
sarahmarshy 44:3a7b6083210b 162
sarahmarshy 44:3a7b6083210b 163 sendCommand("AT+CIPMUX=1", "OK", NULL, 1000);
sarahmarshy 44:3a7b6083210b 164 sendCommand(( "AT+CIPSTART=" + string(idstr) + ",\"UDP\",\"" + (string) ip + "\"," + (string) portstr + ",1112,0").c_str(), "OK", NULL, 10000);
sarahmarshy 44:3a7b6083210b 165 sendCommand(("AT+CIPSEND=" + (string)idstr + "," + (string)lenstr).c_str(), ">", NULL, 1000);// go into transparent mode
mbedAustin 34:7ccda5d68a00 166 DBG("Data Mode\r\n");
michaeljkoster 22:c4360e61486a 167 state.cmdMode = false;
mbedAustin 28:91e65e22e63a 168
michaeljkoster 16:3f0efaa57a12 169 return true;
michaeljkoster 16:3f0efaa57a12 170 }
michaeljkoster 16:3f0efaa57a12 171
sarahmarshy 44:3a7b6083210b 172 bool ESP8266::startTCPServer(int port)
sarahmarshy 44:3a7b6083210b 173 {
sarahmarshy 44:3a7b6083210b 174 bool command_results[3];
sarahmarshy 44:3a7b6083210b 175 command_results[0]=sendCommand("AT+CWMODE=3", "OK", NULL, 1000);
sarahmarshy 44:3a7b6083210b 176 command_results[1]=sendCommand("AT+CIPMUX=1", "OK", NULL, 1000);
sarahmarshy 44:3a7b6083210b 177 if(port == 333){
sarahmarshy 44:3a7b6083210b 178 command_results[2]=sendCommand("AT+CIPSERVER=1", "OK", NULL, 1000);
sarahmarshy 44:3a7b6083210b 179 }
sarahmarshy 44:3a7b6083210b 180 else{
sarahmarshy 44:3a7b6083210b 181 char portstr[5];
sarahmarshy 44:3a7b6083210b 182 sprintf(portstr, "%d", port);
sarahmarshy 44:3a7b6083210b 183 command_results[2]=sendCommand(("AT+CIPSERVER=1," + (string)portstr).c_str(), "OK", NULL, 1000);
sarahmarshy 44:3a7b6083210b 184 }
sarahmarshy 44:3a7b6083210b 185 //sendCommand("AT+CIFSR", "OK", NULL, 1000);
sarahmarshy 44:3a7b6083210b 186 DBG("Data Mode\r\n");
sarahmarshy 44:3a7b6083210b 187 state.cmdMode = false;
sarahmarshy 44:3a7b6083210b 188 if (command_results[0] and command_results[1] and command_results[2]){
sarahmarshy 44:3a7b6083210b 189 return true;
sarahmarshy 44:3a7b6083210b 190 }
sarahmarshy 44:3a7b6083210b 191 else{
sarahmarshy 44:3a7b6083210b 192 return false;
sarahmarshy 44:3a7b6083210b 193 }
sarahmarshy 44:3a7b6083210b 194 }
sarahmarshy 44:3a7b6083210b 195
michaeljkoster 15:37a7a56a424f 196 bool ESP8266::close()
michaeljkoster 15:37a7a56a424f 197 {
sam_grove 40:0a83315aea0a 198 wait(0.1f);
michaeljkoster 17:d11fa4c3ac65 199 send("+++",3);
sam_grove 40:0a83315aea0a 200 wait(1.0f);
michaeljkoster 22:c4360e61486a 201 state.cmdMode = true;
michaeljkoster 16:3f0efaa57a12 202 sendCommand("AT+CIPCLOSE","OK", NULL, 10000);
michaeljkoster 15:37a7a56a424f 203 return true;
michaeljkoster 15:37a7a56a424f 204 }
michaeljkoster 15:37a7a56a424f 205
michaeljkoster 15:37a7a56a424f 206 bool ESP8266::disconnect()
michaeljkoster 15:37a7a56a424f 207 {
michaeljkoster 15:37a7a56a424f 208 // if already disconnected, return
michaeljkoster 15:37a7a56a424f 209 if (!state.associated)
michaeljkoster 15:37a7a56a424f 210 return true;
michaeljkoster 15:37a7a56a424f 211 // send command to quit AP
mbedAustin 28:91e65e22e63a 212 sendCommand("AT+CWQAP", "OK", NULL, 10000);
michaeljkoster 15:37a7a56a424f 213 state.associated = false;
michaeljkoster 15:37a7a56a424f 214 return true;
michaeljkoster 15:37a7a56a424f 215 }
michaeljkoster 15:37a7a56a424f 216
mbedAustin 28:91e65e22e63a 217 /*
mbedAustin 28:91e65e22e63a 218 Assuming Returned data looks like this:
mbedAustin 28:91e65e22e63a 219 +CIFSR:STAIP,"192.168.11.2"
mbedAustin 28:91e65e22e63a 220 +CIFSR:STAMAC,"18:fe:34:9f:3a:f5"
mbedAustin 28:91e65e22e63a 221 grabbing IP from first set of quotation marks
mbedAustin 28:91e65e22e63a 222 */
michaeljkoster 15:37a7a56a424f 223 char* ESP8266::getIPAddress()
michaeljkoster 15:37a7a56a424f 224 {
mbedAustin 28:91e65e22e63a 225 char result[30] = {0};
mbedAustin 28:91e65e22e63a 226 int check = 0;
mbedAustin 28:91e65e22e63a 227 check = sendCommand("AT+CIFSR", NULL, result, 1000);
mbedAustin 29:939372104145 228 //pc.printf("\r\nReceivedInfo for IP Command is: %s\r\n",result);
mbedAustin 29:939372104145 229 ip = ipString;
mbedAustin 29:939372104145 230 if(check) {
mbedAustin 28:91e65e22e63a 231 // Success
mbedAustin 28:91e65e22e63a 232 string resultString(result);
mbedAustin 28:91e65e22e63a 233 uint8_t pos1 = 0, pos2 = 0;
mbedAustin 28:91e65e22e63a 234 //uint8_t pos3 = 0, pos4 = 0;
mbedAustin 28:91e65e22e63a 235 pos1 = resultString.find("+CIFSR:STAIP");
mbedAustin 28:91e65e22e63a 236 pos1 = resultString.find('"',pos1);
mbedAustin 28:91e65e22e63a 237 pos2 = resultString.find('"',pos1+1);
mbedAustin 28:91e65e22e63a 238 //pos3 = resultString.find('"',pos2+1); //would find mac address
mbedAustin 28:91e65e22e63a 239 //pos4 = resultString.find('"',pos3+1);
mbedAustin 28:91e65e22e63a 240 strncpy(ipString,resultString.substr(pos1,pos2).c_str(),sizeof(ipString));
mbedAustin 28:91e65e22e63a 241 ipString[pos2 - pos1 +1] = 0; // null terminate string correctly.
mbedAustin 42:3f62103a4f3c 242 INFO("IP: %s",ipString);
mbedAustin 29:939372104145 243 ip = ipString;
mbedAustin 29:939372104145 244
mbedAustin 29:939372104145 245 } else {
mbedAustin 28:91e65e22e63a 246 // Failure
mbedAustin 41:264902b160ea 247 ERR("getIPAddress() failed");
mbedAustin 29:939372104145 248 ip = NULL;
mbedAustin 28:91e65e22e63a 249 }
mbedAustin 29:939372104145 250 return ip;
michaeljkoster 15:37a7a56a424f 251 }
michaeljkoster 15:37a7a56a424f 252
michaeljkoster 13:41098c907200 253 bool ESP8266::gethostbyname(const char * host, char * ip)
samux 1:fb4494783863 254 {
samux 1:fb4494783863 255 string h = host;
samux 1:fb4494783863 256 int nb_digits = 0;
samux 1:fb4494783863 257
samux 1:fb4494783863 258 // no dns needed
samux 1:fb4494783863 259 int pos = h.find(".");
samux 1:fb4494783863 260 if (pos != string::npos) {
samux 1:fb4494783863 261 string sub = h.substr(0, h.find("."));
samux 1:fb4494783863 262 nb_digits = atoi(sub.c_str());
samux 1:fb4494783863 263 }
samux 1:fb4494783863 264 //printf("substrL %s\r\n", sub.c_str());
samux 1:fb4494783863 265 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) {
samux 1:fb4494783863 266 strcpy(ip, host);
michaeljkoster 13:41098c907200 267 return true;
mbedAustin 28:91e65e22e63a 268 } else {
michaeljkoster 13:41098c907200 269 // dns needed, not currently available
mbedAustin 30:c035696b9397 270 ERR("gethostbyname(): DNS Not currently available, only use IP Addresses!");
michaeljkoster 13:41098c907200 271 return false;
michaeljkoster 13:41098c907200 272 }
michaeljkoster 13:41098c907200 273 }
samux 1:fb4494783863 274
michaeljkoster 13:41098c907200 275 void ESP8266::reset()
samux 1:fb4494783863 276 {
samux 1:fb4494783863 277 reset_pin = 0;
sam_grove 40:0a83315aea0a 278 wait_us(20);
samux 1:fb4494783863 279 reset_pin = 1;
sam_grove 40:0a83315aea0a 280 //wait(1);
sarahmarshy 46:913d07795182 281 //reset_pin = !reset_pin
michaeljkoster 24:03585a13ff3b 282 //send("+++",3);
sarahmarshy 46:913d07795182 283 wait(1);
michaeljkoster 24:03585a13ff3b 284 state.cmdMode = true;
michaeljkoster 24:03585a13ff3b 285 sendCommand("AT", "OK", NULL, 1000);
mbedAustin 28:91e65e22e63a 286 sendCommand("AT+RST", "ready", NULL, 10000);
michaeljkoster 24:03585a13ff3b 287 state.associated = false;
michaeljkoster 24:03585a13ff3b 288
samux 1:fb4494783863 289 }
samux 1:fb4494783863 290
michaeljkoster 13:41098c907200 291 bool ESP8266::reboot()
samux 3:9aa05e19c62e 292 {
michaeljkoster 16:3f0efaa57a12 293 reset();
samux 3:9aa05e19c62e 294 return true;
samux 3:9aa05e19c62e 295 }
samux 3:9aa05e19c62e 296
michaeljkoster 15:37a7a56a424f 297 void ESP8266::handler_rx(void)
samux 1:fb4494783863 298 {
michaeljkoster 15:37a7a56a424f 299 //read characters
michaeljkoster 16:3f0efaa57a12 300 char c;
mbedAustin 28:91e65e22e63a 301 while (wifi.readable()) {
michaeljkoster 16:3f0efaa57a12 302 c=wifi.getc();
michaeljkoster 16:3f0efaa57a12 303 buf_ESP8266.queue(c);
michaeljkoster 26:0d5bcb3903e2 304 //if (state.cmdMode) pc.printf("%c",c); //debug echo, needs fast serial console to prevent UART overruns
michaeljkoster 16:3f0efaa57a12 305 }
michaeljkoster 15:37a7a56a424f 306 }
michaeljkoster 15:37a7a56a424f 307
michaeljkoster 15:37a7a56a424f 308 void ESP8266::attach_rx(bool callback)
michaeljkoster 15:37a7a56a424f 309 {
sam_grove 40:0a83315aea0a 310 if (!callback) {
michaeljkoster 15:37a7a56a424f 311 wifi.attach(NULL);
sam_grove 40:0a83315aea0a 312 }
sam_grove 40:0a83315aea0a 313 else {
michaeljkoster 15:37a7a56a424f 314 wifi.attach(this, &ESP8266::handler_rx);
sam_grove 40:0a83315aea0a 315 }
samux 1:fb4494783863 316 }
samux 1:fb4494783863 317
michaeljkoster 13:41098c907200 318 int ESP8266::readable()
samux 1:fb4494783863 319 {
michaeljkoster 13:41098c907200 320 return buf_ESP8266.available();
samux 1:fb4494783863 321 }
samux 1:fb4494783863 322
michaeljkoster 13:41098c907200 323 int ESP8266::writeable()
samux 1:fb4494783863 324 {
samux 1:fb4494783863 325 return wifi.writeable();
samux 1:fb4494783863 326 }
samux 1:fb4494783863 327
michaeljkoster 13:41098c907200 328 char ESP8266::getc()
samux 1:fb4494783863 329 {
michaeljkoster 14:4d1128f72e00 330 char c=0;
michaeljkoster 13:41098c907200 331 while (!buf_ESP8266.available());
michaeljkoster 13:41098c907200 332 buf_ESP8266.dequeue(&c);
samux 1:fb4494783863 333 return c;
samux 1:fb4494783863 334 }
samux 1:fb4494783863 335
michaeljkoster 15:37a7a56a424f 336 int ESP8266::putc(char c)
samux 1:fb4494783863 337 {
michaeljkoster 20:d764237405c2 338 while (!wifi.writeable() || wifi.readable()); //wait for echoed command characters to be read first
michaeljkoster 15:37a7a56a424f 339 return wifi.putc(c);
samux 1:fb4494783863 340 }
samux 1:fb4494783863 341
michaeljkoster 15:37a7a56a424f 342 void ESP8266::flush()
samux 1:fb4494783863 343 {
michaeljkoster 15:37a7a56a424f 344 buf_ESP8266.flush();
samux 1:fb4494783863 345 }
samux 1:fb4494783863 346
michaeljkoster 16:3f0efaa57a12 347 int ESP8266::send(const char * buf, int len)
michaeljkoster 15:37a7a56a424f 348 {
mbedAustin 32:cf071dc33972 349 //TODO: need to add handler for data > 2048B, this is the max packet size of the ESP8266.
mbedAustin 43:2e326d95fe2c 350 if(len >= 2048){
mbedAustin 43:2e326d95fe2c 351 WARN("send buffer >= 2048B, need to chunk this up to be less.");
mbedAustin 43:2e326d95fe2c 352 }
michaeljkoster 16:3f0efaa57a12 353 const char* bufptr=buf;
mbedAustin 28:91e65e22e63a 354 for(int i=0; i<len; i++) {
michaeljkoster 17:d11fa4c3ac65 355 putc((int)*bufptr++);
michaeljkoster 18:60422852e99c 356 }
michaeljkoster 19:fb8d5bff2076 357 return len;
michaeljkoster 15:37a7a56a424f 358 }
samux 1:fb4494783863 359
michaeljkoster 16:3f0efaa57a12 360 bool ESP8266::sendCommand(const char * cmd, const char * ACK, char * res, int timeout)
samux 1:fb4494783863 361 {
samux 1:fb4494783863 362 char read;
samux 1:fb4494783863 363 size_t found = string::npos;
sam_grove 40:0a83315aea0a 364 string checking = "";
samux 1:fb4494783863 365 Timer tmr;
samux 1:fb4494783863 366 int result = 0;
samux 1:fb4494783863 367
mbedAustin 42:3f62103a4f3c 368 DBG("sendCmd:\t %s",cmd);
samux 1:fb4494783863 369
michaeljkoster 17:d11fa4c3ac65 370 attach_rx(true);
samux 1:fb4494783863 371
samux 1:fb4494783863 372 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 373 while (readable())
michaeljkoster 17:d11fa4c3ac65 374 getc();
mbedAustin 28:91e65e22e63a 375
samux 1:fb4494783863 376 if (!ACK || !strcmp(ACK, "NO")) {
mbedAustin 28:91e65e22e63a 377 for (int i = 0; i < strlen(cmd); i++) {
michaeljkoster 16:3f0efaa57a12 378 result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result;
sam_grove 40:0a83315aea0a 379 wait(0.005f); // prevents stuck recieve ready (?) need to let echoed character get read first
michaeljkoster 16:3f0efaa57a12 380 }
michaeljkoster 16:3f0efaa57a12 381 putc(13); //CR
sam_grove 40:0a83315aea0a 382 wait(0.005f); // wait for echo
michaeljkoster 16:3f0efaa57a12 383 putc(10); //LF
michaeljkoster 16:3f0efaa57a12 384
samux 1:fb4494783863 385 } else {
samux 1:fb4494783863 386 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 387 while (readable())
michaeljkoster 17:d11fa4c3ac65 388 getc();
samux 1:fb4494783863 389
samux 1:fb4494783863 390 tmr.start();
mbedAustin 28:91e65e22e63a 391 for (int i = 0; i < strlen(cmd); i++) {
michaeljkoster 16:3f0efaa57a12 392 result = (putc(cmd[i]) == cmd[i]) ? result + 1 : result;
michaeljkoster 20:d764237405c2 393 wait(.005); // wait for echo
michaeljkoster 16:3f0efaa57a12 394 }
michaeljkoster 16:3f0efaa57a12 395 putc(13); //CR
sam_grove 40:0a83315aea0a 396 wait(0.005f); // wait for echo
michaeljkoster 16:3f0efaa57a12 397 putc(10); //LF
samux 1:fb4494783863 398
samux 1:fb4494783863 399 while (1) {
samux 1:fb4494783863 400 if (tmr.read_ms() > timeout) {
samux 1:fb4494783863 401 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 402 while (readable())
michaeljkoster 17:d11fa4c3ac65 403 getc();
samux 1:fb4494783863 404
mbedAustin 42:3f62103a4f3c 405 DBG("check:\t %s", checking.c_str());
samux 1:fb4494783863 406
samux 1:fb4494783863 407 attach_rx(true);
samux 1:fb4494783863 408 return -1;
michaeljkoster 17:d11fa4c3ac65 409 } else if (readable()) {
michaeljkoster 17:d11fa4c3ac65 410 read = getc();
sam_grove 40:0a83315aea0a 411 //printf("%c",read); //debug echo
samux 1:fb4494783863 412 if ( read != '\r' && read != '\n') {
samux 1:fb4494783863 413 checking += read;
samux 1:fb4494783863 414 found = checking.find(ACK);
samux 1:fb4494783863 415 if (found != string::npos) {
sam_grove 40:0a83315aea0a 416 wait(0.01f);
samux 1:fb4494783863 417
samux 1:fb4494783863 418 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 419 while (readable())
michaeljkoster 26:0d5bcb3903e2 420 read = getc();
sam_grove 40:0a83315aea0a 421 //printf("%c",read); //debug echo
samux 1:fb4494783863 422 break;
samux 1:fb4494783863 423 }
samux 1:fb4494783863 424 }
samux 1:fb4494783863 425 }
samux 1:fb4494783863 426 }
mbedAustin 36:e1545c6c2cb3 427 DBG("check: %s", checking.c_str());
samux 1:fb4494783863 428
samux 1:fb4494783863 429 attach_rx(true);
samux 1:fb4494783863 430 return result;
samux 1:fb4494783863 431 }
samux 1:fb4494783863 432
samux 1:fb4494783863 433 //the user wants the result from the command (ACK == NULL, res != NULL)
sarahmarshy 46:913d07795182 434 if (res != NULL) {
samux 1:fb4494783863 435 int i = 0;
samux 1:fb4494783863 436 Timer timeout;
samux 1:fb4494783863 437 timeout.start();
samux 1:fb4494783863 438 tmr.reset();
samux 1:fb4494783863 439 while (1) {
samux 1:fb4494783863 440 if (timeout.read() > 2) {
samux 1:fb4494783863 441 if (i == 0) {
samux 1:fb4494783863 442 res = NULL;
samux 1:fb4494783863 443 break;
samux 1:fb4494783863 444 }
samux 1:fb4494783863 445 res[i] = '\0';
mbedAustin 36:e1545c6c2cb3 446 DBG("user str 1: %s", res);
samux 1:fb4494783863 447
samux 1:fb4494783863 448 break;
samux 1:fb4494783863 449 } else {
samux 1:fb4494783863 450 if (tmr.read_ms() > 300) {
samux 1:fb4494783863 451 res[i] = '\0';
mbedAustin 36:e1545c6c2cb3 452 DBG("user str: %s", res);
samux 1:fb4494783863 453
samux 1:fb4494783863 454 break;
samux 1:fb4494783863 455 }
michaeljkoster 17:d11fa4c3ac65 456 if (readable()) {
samux 1:fb4494783863 457 tmr.start();
michaeljkoster 17:d11fa4c3ac65 458 read = getc();
samux 1:fb4494783863 459
samux 1:fb4494783863 460 // we drop \r and \n
samux 1:fb4494783863 461 if ( read != '\r' && read != '\n') {
samux 1:fb4494783863 462 res[i++] = read;
samux 1:fb4494783863 463 }
samux 1:fb4494783863 464 }
samux 1:fb4494783863 465 }
samux 1:fb4494783863 466 }
mbedAustin 36:e1545c6c2cb3 467 DBG("user str: %s", res);
samux 1:fb4494783863 468 }
samux 1:fb4494783863 469
samux 1:fb4494783863 470 //We flush the buffer
michaeljkoster 17:d11fa4c3ac65 471 while (readable())
michaeljkoster 17:d11fa4c3ac65 472 getc();
samux 1:fb4494783863 473
samux 1:fb4494783863 474 attach_rx(true);
mbedAustin 36:e1545c6c2cb3 475 DBG("result: %d", result)
samux 1:fb4494783863 476 return result;
michaeljkoster 15:37a7a56a424f 477 }