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:
mbedAustin
Date:
Wed Jun 03 18:36:02 2015 +0000
Revision:
45:c180905b5b79
Parent:
43:2e326d95fe2c
Parent:
44:3a7b6083210b
Child:
46:913d07795182
merging in fixes from various members across various branches together.

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