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:
michaeljkoster
Date:
Sun Nov 30 21:56:03 2014 +0000
Revision:
15:37a7a56a424f
Parent:
14:4d1128f72e00
Child:
16:3f0efaa57a12
reorganize

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"
samux 1:fb4494783863 21 #include <string>
samux 1:fb4494783863 22 #include <algorithm>
samux 1:fb4494783863 23
samux 1:fb4494783863 24 //Debug is disabled by default
screamer 10:131675c17372 25 #if (defined(DEBUG))
michaeljkoster 13:41098c907200 26 #define DBG(x, ...) std::printf("[ESP8266 : DBG]"x"\r\n", ##__VA_ARGS__);
michaeljkoster 13:41098c907200 27 #define WARN(x, ...) std::printf("[ESP8266 : WARN]"x"\r\n", ##__VA_ARGS__);
michaeljkoster 13:41098c907200 28 #define ERR(x, ...) std::printf("[ESP8266 : ERR]"x"\r\n", ##__VA_ARGS__);
samux 1:fb4494783863 29 #else
samux 1:fb4494783863 30 #define DBG(x, ...)
samux 1:fb4494783863 31 #define WARN(x, ...)
samux 1:fb4494783863 32 #define ERR(x, ...)
samux 1:fb4494783863 33 #endif
samux 1:fb4494783863 34
screamer 10:131675c17372 35 #if defined(DEBUG)
michaeljkoster 13:41098c907200 36 #define INFO(x, ...) printf("[ESP8266 : INFO]"x"\r\n", ##__VA_ARGS__);
samux 1:fb4494783863 37 #else
samux 1:fb4494783863 38 #define INFO(x, ...)
samux 1:fb4494783863 39 #endif
samux 1:fb4494783863 40
samux 1:fb4494783863 41 #define MAX_TRY_JOIN 3
samux 1:fb4494783863 42
michaeljkoster 12:c5f0eac67a8a 43 extern Serial pc;
michaeljkoster 12:c5f0eac67a8a 44
michaeljkoster 13:41098c907200 45 ESP8266 * ESP8266::inst;
samux 1:fb4494783863 46
michaeljkoster 13:41098c907200 47 ESP8266::ESP8266( PinName tx, PinName rx, PinName _reset, const char * ssid, const char * phrase ):
michaeljkoster 13:41098c907200 48 wifi(tx, rx), reset_pin(_reset), buf_ESP8266(256)
samux 1:fb4494783863 49 {
samux 1:fb4494783863 50 memset(&state, 0, sizeof(state));
samux 1:fb4494783863 51
samux 1:fb4494783863 52 // change all ' ' in '$' in the ssid and the passphrase
samux 1:fb4494783863 53 strcpy(this->ssid, ssid);
samux 1:fb4494783863 54 for (int i = 0; i < strlen(ssid); i++) {
samux 1:fb4494783863 55 if (this->ssid[i] == ' ')
samux 1:fb4494783863 56 this->ssid[i] = '$';
samux 1:fb4494783863 57 }
samux 1:fb4494783863 58 strcpy(this->phrase, phrase);
samux 1:fb4494783863 59 for (int i = 0; i < strlen(phrase); i++) {
samux 1:fb4494783863 60 if (this->phrase[i] == ' ')
samux 1:fb4494783863 61 this->phrase[i] = '$';
samux 1:fb4494783863 62 }
samux 1:fb4494783863 63
samux 1:fb4494783863 64 inst = this;
samux 1:fb4494783863 65 attach_rx(false);
samux 1:fb4494783863 66 }
samux 1:fb4494783863 67
michaeljkoster 13:41098c907200 68 bool ESP8266::join()
samux 1:fb4494783863 69 {
samux 1:fb4494783863 70
samux 1:fb4494783863 71 for (int i= 0; i < MAX_TRY_JOIN; i++) {
samux 2:8e54830d0df7 72
samux 1:fb4494783863 73 //join the network
samux 1:fb4494783863 74 state.associated = true;
michaeljkoster 13:41098c907200 75 INFO("\r\nssid: %s\r\nphrase: %s\r\nsecurity: %s\r\n\r\n", this->ssid, this->phrase);
samux 1:fb4494783863 76 return true;
samux 1:fb4494783863 77 }
samux 1:fb4494783863 78 return false;
samux 1:fb4494783863 79 }
samux 1:fb4494783863 80
michaeljkoster 13:41098c907200 81 bool ESP8266::connect()
samux 1:fb4494783863 82 {
michaeljkoster 13:41098c907200 83 return join();
samux 1:fb4494783863 84 }
samux 1:fb4494783863 85
michaeljkoster 15:37a7a56a424f 86 bool ESP8266::is_connected()
michaeljkoster 15:37a7a56a424f 87 {
michaeljkoster 15:37a7a56a424f 88 return true;
michaeljkoster 15:37a7a56a424f 89 }
michaeljkoster 15:37a7a56a424f 90
michaeljkoster 15:37a7a56a424f 91 bool ESP8266::close()
michaeljkoster 15:37a7a56a424f 92 {
michaeljkoster 15:37a7a56a424f 93 return true;
michaeljkoster 15:37a7a56a424f 94 }
michaeljkoster 15:37a7a56a424f 95
michaeljkoster 15:37a7a56a424f 96 bool ESP8266::disconnect()
michaeljkoster 15:37a7a56a424f 97 {
michaeljkoster 15:37a7a56a424f 98 // if already disconnected, return
michaeljkoster 15:37a7a56a424f 99 if (!state.associated)
michaeljkoster 15:37a7a56a424f 100 return true;
michaeljkoster 15:37a7a56a424f 101 // send command to quit AP
michaeljkoster 15:37a7a56a424f 102 //
michaeljkoster 15:37a7a56a424f 103 state.associated = false;
michaeljkoster 15:37a7a56a424f 104 return true;
michaeljkoster 15:37a7a56a424f 105 }
michaeljkoster 15:37a7a56a424f 106
michaeljkoster 15:37a7a56a424f 107 char* ESP8266::getIPAddress()
michaeljkoster 15:37a7a56a424f 108 {
michaeljkoster 15:37a7a56a424f 109 return ipString;
michaeljkoster 15:37a7a56a424f 110 }
michaeljkoster 15:37a7a56a424f 111
michaeljkoster 13:41098c907200 112 bool ESP8266::gethostbyname(const char * host, char * ip)
samux 1:fb4494783863 113 {
samux 1:fb4494783863 114 string h = host;
samux 1:fb4494783863 115 int nb_digits = 0;
samux 1:fb4494783863 116
samux 1:fb4494783863 117 // no dns needed
samux 1:fb4494783863 118 int pos = h.find(".");
samux 1:fb4494783863 119 if (pos != string::npos) {
samux 1:fb4494783863 120 string sub = h.substr(0, h.find("."));
samux 1:fb4494783863 121 nb_digits = atoi(sub.c_str());
samux 1:fb4494783863 122 }
samux 1:fb4494783863 123 //printf("substrL %s\r\n", sub.c_str());
samux 1:fb4494783863 124 if (count(h.begin(), h.end(), '.') == 3 && nb_digits > 0) {
samux 1:fb4494783863 125 strcpy(ip, host);
michaeljkoster 13:41098c907200 126 return true;
samux 1:fb4494783863 127 }
samux 1:fb4494783863 128 else {
michaeljkoster 13:41098c907200 129 // dns needed, not currently available
michaeljkoster 13:41098c907200 130 return false;
michaeljkoster 13:41098c907200 131 }
michaeljkoster 13:41098c907200 132 }
samux 1:fb4494783863 133
michaeljkoster 13:41098c907200 134 void ESP8266::reset()
samux 1:fb4494783863 135 {
samux 1:fb4494783863 136 reset_pin = 0;
samux 1:fb4494783863 137 wait(0.2);
samux 1:fb4494783863 138 reset_pin = 1;
samux 1:fb4494783863 139 wait(0.2);
samux 1:fb4494783863 140 }
samux 1:fb4494783863 141
michaeljkoster 13:41098c907200 142 bool ESP8266::reboot()
samux 3:9aa05e19c62e 143 {
samux 3:9aa05e19c62e 144 return true;
samux 3:9aa05e19c62e 145 }
samux 3:9aa05e19c62e 146
michaeljkoster 15:37a7a56a424f 147 void ESP8266::handler_rx(void)
samux 1:fb4494783863 148 {
michaeljkoster 15:37a7a56a424f 149 //read characters
michaeljkoster 15:37a7a56a424f 150 while (wifi.readable())
michaeljkoster 15:37a7a56a424f 151 buf_ESP8266.queue(wifi.getc());
michaeljkoster 15:37a7a56a424f 152 }
michaeljkoster 15:37a7a56a424f 153
michaeljkoster 15:37a7a56a424f 154 void ESP8266::attach_rx(bool callback)
michaeljkoster 15:37a7a56a424f 155 {
michaeljkoster 15:37a7a56a424f 156 if (!callback)
michaeljkoster 15:37a7a56a424f 157 wifi.attach(NULL);
michaeljkoster 15:37a7a56a424f 158 else
michaeljkoster 15:37a7a56a424f 159 wifi.attach(this, &ESP8266::handler_rx);
samux 1:fb4494783863 160 }
samux 1:fb4494783863 161
michaeljkoster 13:41098c907200 162 int ESP8266::readable()
samux 1:fb4494783863 163 {
michaeljkoster 13:41098c907200 164 return buf_ESP8266.available();
samux 1:fb4494783863 165 }
samux 1:fb4494783863 166
michaeljkoster 13:41098c907200 167 int ESP8266::writeable()
samux 1:fb4494783863 168 {
samux 1:fb4494783863 169 return wifi.writeable();
samux 1:fb4494783863 170 }
samux 1:fb4494783863 171
michaeljkoster 13:41098c907200 172 char ESP8266::getc()
samux 1:fb4494783863 173 {
michaeljkoster 14:4d1128f72e00 174 char c=0;
michaeljkoster 13:41098c907200 175 while (!buf_ESP8266.available());
michaeljkoster 13:41098c907200 176 buf_ESP8266.dequeue(&c);
samux 1:fb4494783863 177 return c;
samux 1:fb4494783863 178 }
samux 1:fb4494783863 179
michaeljkoster 15:37a7a56a424f 180 int ESP8266::putc(char c)
samux 1:fb4494783863 181 {
michaeljkoster 15:37a7a56a424f 182 while (!wifi.writeable());
michaeljkoster 15:37a7a56a424f 183 return wifi.putc(c);
samux 1:fb4494783863 184 }
samux 1:fb4494783863 185
michaeljkoster 15:37a7a56a424f 186 void ESP8266::flush()
samux 1:fb4494783863 187 {
michaeljkoster 15:37a7a56a424f 188 buf_ESP8266.flush();
samux 1:fb4494783863 189 }
samux 1:fb4494783863 190
michaeljkoster 15:37a7a56a424f 191 bool ESP8266::sendCommand(const char * cmd, const char * ack, char * res, int timeout)
michaeljkoster 15:37a7a56a424f 192 {
michaeljkoster 15:37a7a56a424f 193 return true;
michaeljkoster 15:37a7a56a424f 194 }
samux 1:fb4494783863 195
michaeljkoster 13:41098c907200 196 int ESP8266::send(const char * str, int len, const char * ACK, char * res, int timeout)
samux 1:fb4494783863 197 {
samux 1:fb4494783863 198 char read;
samux 1:fb4494783863 199 size_t found = string::npos;
samux 1:fb4494783863 200 string checking;
samux 1:fb4494783863 201 Timer tmr;
samux 1:fb4494783863 202 int result = 0;
samux 1:fb4494783863 203
samux 1:fb4494783863 204 DBG("will send: %s\r\n",str);
samux 1:fb4494783863 205
samux 1:fb4494783863 206 attach_rx(false);
samux 1:fb4494783863 207
samux 1:fb4494783863 208 //We flush the buffer
samux 1:fb4494783863 209 while (wifi.readable())
samux 1:fb4494783863 210 wifi.getc();
samux 1:fb4494783863 211
samux 1:fb4494783863 212 if (!ACK || !strcmp(ACK, "NO")) {
samux 1:fb4494783863 213 for (int i = 0; i < len; i++)
samux 1:fb4494783863 214 result = (putc(str[i]) == str[i]) ? result + 1 : result;
samux 1:fb4494783863 215 } else {
samux 1:fb4494783863 216 //We flush the buffer
samux 1:fb4494783863 217 while (wifi.readable())
samux 1:fb4494783863 218 wifi.getc();
samux 1:fb4494783863 219
samux 1:fb4494783863 220 tmr.start();
samux 1:fb4494783863 221 for (int i = 0; i < len; i++)
samux 1:fb4494783863 222 result = (putc(str[i]) == str[i]) ? result + 1 : result;
samux 1:fb4494783863 223
samux 1:fb4494783863 224 while (1) {
samux 1:fb4494783863 225 if (tmr.read_ms() > timeout) {
samux 1:fb4494783863 226 //We flush the buffer
samux 1:fb4494783863 227 while (wifi.readable())
samux 1:fb4494783863 228 wifi.getc();
samux 1:fb4494783863 229
samux 1:fb4494783863 230 DBG("check: %s\r\n", checking.c_str());
samux 1:fb4494783863 231
samux 1:fb4494783863 232 attach_rx(true);
samux 1:fb4494783863 233 return -1;
samux 1:fb4494783863 234 } else if (wifi.readable()) {
samux 1:fb4494783863 235 read = wifi.getc();
samux 1:fb4494783863 236 if ( read != '\r' && read != '\n') {
samux 1:fb4494783863 237 checking += read;
samux 1:fb4494783863 238 found = checking.find(ACK);
samux 1:fb4494783863 239 if (found != string::npos) {
samux 1:fb4494783863 240 wait(0.01);
samux 1:fb4494783863 241
samux 1:fb4494783863 242 //We flush the buffer
samux 1:fb4494783863 243 while (wifi.readable())
samux 1:fb4494783863 244 wifi.getc();
samux 1:fb4494783863 245
samux 1:fb4494783863 246 break;
samux 1:fb4494783863 247 }
samux 1:fb4494783863 248 }
samux 1:fb4494783863 249 }
samux 1:fb4494783863 250 }
samux 1:fb4494783863 251 DBG("check: %s\r\n", checking.c_str());
samux 1:fb4494783863 252
samux 1:fb4494783863 253 attach_rx(true);
samux 1:fb4494783863 254 return result;
samux 1:fb4494783863 255 }
samux 1:fb4494783863 256
samux 1:fb4494783863 257 //the user wants the result from the command (ACK == NULL, res != NULL)
samux 1:fb4494783863 258 if ( res != NULL) {
samux 1:fb4494783863 259 int i = 0;
samux 1:fb4494783863 260 Timer timeout;
samux 1:fb4494783863 261 timeout.start();
samux 1:fb4494783863 262 tmr.reset();
samux 1:fb4494783863 263 while (1) {
samux 1:fb4494783863 264 if (timeout.read() > 2) {
samux 1:fb4494783863 265 if (i == 0) {
samux 1:fb4494783863 266 res = NULL;
samux 1:fb4494783863 267 break;
samux 1:fb4494783863 268 }
samux 1:fb4494783863 269 res[i] = '\0';
samux 1:fb4494783863 270 DBG("user str 1: %s\r\n", res);
samux 1:fb4494783863 271
samux 1:fb4494783863 272 break;
samux 1:fb4494783863 273 } else {
samux 1:fb4494783863 274 if (tmr.read_ms() > 300) {
samux 1:fb4494783863 275 res[i] = '\0';
samux 1:fb4494783863 276 DBG("user str: %s\r\n", res);
samux 1:fb4494783863 277
samux 1:fb4494783863 278 break;
samux 1:fb4494783863 279 }
samux 1:fb4494783863 280 if (wifi.readable()) {
samux 1:fb4494783863 281 tmr.start();
samux 1:fb4494783863 282 read = wifi.getc();
samux 1:fb4494783863 283
samux 1:fb4494783863 284 // we drop \r and \n
samux 1:fb4494783863 285 if ( read != '\r' && read != '\n') {
samux 1:fb4494783863 286 res[i++] = read;
samux 1:fb4494783863 287 }
samux 1:fb4494783863 288 }
samux 1:fb4494783863 289 }
samux 1:fb4494783863 290 }
samux 1:fb4494783863 291 DBG("user str: %s\r\n", res);
samux 1:fb4494783863 292 }
samux 1:fb4494783863 293
samux 1:fb4494783863 294 //We flush the buffer
samux 1:fb4494783863 295 while (wifi.readable())
samux 1:fb4494783863 296 wifi.getc();
samux 1:fb4494783863 297
samux 1:fb4494783863 298 attach_rx(true);
samux 1:fb4494783863 299 DBG("result: %d\r\n", result)
samux 1:fb4494783863 300 return result;
michaeljkoster 15:37a7a56a424f 301 }