├── .gitignore ├── LICENSE ├── README.md ├── SerialESP8266wifi.cpp ├── SerialESP8266wifi.h ├── examples ├── SerialESP8266_library_test │ └── SerialESP8266_library_test.ino └── SerialESP8266_tcp_cli │ └── SerialESP8266_tcp_cli.ino └── library.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ekstrand 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SerialESP8266wifi 2 | A simple ESP8266 Arduino library with built in re-connect functionality. 3 | * The ESP8266 is a dirtcheap wifimodule. I got mine for about 2.50 US including shipping at Aliexpress. Read about it here: https://nurdspace.nl/ESP8266 4 | * An AT command reference can be found here: https://github.com/espressif/esp8266_at/wiki/AT_Description 5 | * Contact me if you have ideas for changes or new features, found a bug or just want to buy a beer at jonas[AT]inspirativ[DOT]se 6 | 7 | ## Memory footprint and more 8 | * Tested on an Arduino Nano v3 ATMega 328, Arduino IDE 1.60, ESP8266 module with firmware version 0.9.2.4 9 | * approx 3.5kB of program storage 10 | * approx 285 bytes or RAM 11 | 12 | 13 | ## Install 14 | * Download the library as a zip from https://github.com/ekstrand/SerialESP8266wifi/archive/master.zip 15 | * Unzip and place in ARDUINO_HOME/libraries/ directory as SerialESP8266wifi 16 | * Restart the Arduino IDE 17 | * In your sketch do a `#include ` 18 | * To set up a simple server for testing, I like to use SocketTest http://sourceforge.net/projects/sockettest/ 19 | 20 | ## Constructor 21 | 22 | **SerialESP8266wifi(Stream serialIn, Stream serialOut, byte resetPin)** 23 | * **serialIn** this object is used to read from the ESP8266, you can use either hardware or software serial 24 | * **serialOut** this object is used to write to the ESP8266, you can use either hardware or software serial 25 | * **resetPin** this pin will be pulled low then high to reset the ESP8266. It is assumed that a the CH_PD pin is connected the this pin. See pin out and more at: http://www.electrodragon.com/w/ESP8266#Module_Pin_Description 26 | * **Example:** ```SerialESP8266wifi wifi(swSerial, swSerial, 10);``` 27 | 28 | **SerialESP8266wifi(Stream serialIn, Stream serialOut, byte resetPin, Stream debugSerial)** 29 | * **serialIn** this object is used to read from the ESP8266, you can use either hardware or software serial 30 | * **serialOut** this object is used to write to the ESP8266, you can use either hardware or software serial 31 | * **resetPin** this pin will be pulled low then high to reset the ESP8266. It is assumed that a the CH_PD pin is connected the this pin. See pin out and more at: http://www.electrodragon.com/w/ 32 | ESP8266#Module_Pin_Description 33 | * **debugSerial** enables wifi debug and local echo to Serial (could be hw or sw) 34 | * **Example:** ```SerialESP8266wifi wifi(swSerial, swSerial, 10, Serial);``` 35 | 36 | 37 | ## Starting the module 38 | **boolean begin()** calling this method will do a hw reset on the ESP8266 and set basic parameters 39 | * **return** will return a true or false depending if the module was properly initiated 40 | * **Example:** `boolean esp8266started = wifi.begin();` 41 | 42 | ## Connecting to an access point 43 | **boolean connectToAP(char * ssid, char* password)** tells the ESP8266 to connect to an accesspoint 44 | * **ssid** the ssid (station name) to be used. Note that this method uses char arrays as input. See http://arduino.cc/en/Reference/StringToCharArray for how to convert an arduino string object to a char array (max 15 chars) 45 | * **password** the access point password wpa/wpa2 is assumed (max 15 chars) 46 | * **return** will return a true if a valid IP was received within the time limit (15 seconds) 47 | * **Example:** `boolean apConnected = wifi.connectToAP("myaccesspoint", "password123");` 48 | 49 | **boolean isConnectedToAP()** checks if the module is connected with a valid IP 50 | * **return** will return a true if the module has an valid IP address 51 | * **Example:** `boolean apConnected = wifi.isConnectedToAP();` 52 | 53 | ## Connecting to a server 54 | **boolean connectToServer(char* ip, char* port)** tells the ESP8266 to open a connection to a server 55 | * **ip** the IP-address of the server to connect to 56 | * **port** the port number to be used 57 | * **return** true if connection is established within 5 seconds 58 | * **Example:** `boolean serverConnected = wifi.connectToServer("192.168.5.123", "2121");` 59 | 60 | **boolean isConnectedToServer()** checks if a server is connected 61 | * **return** will return a true if we are connected to a server 62 | * **Example:** `boolean serverConnected = wifi.isConnectedToServer();` 63 | 64 | **setTransportToTCP() AND setTransportToUDP()** tells the ESP8266 which transport to use when connecting to a server. Default is TCP. 65 | 66 | ## Disconnecting from a server 67 | **disconnectFromServer()** tells the ESP8266 to close the server connection 68 | * **Example:** `wifi.disconnectFromServer();` 69 | 70 | ## Sending a message 71 | **boolean send(char channel, char * message)** sends a message - alias for send(char channel, char * message, true) 72 | * **channel** Set to **SERVER** if you want to send to server. If we are the server, the value can be between '1'-'3' 73 | * **message** a character array, max 25 characters long. 74 | * **return** true if the message was sent 75 | * **Example:** `boolean sendOk = wifi.send(SERVER, "Hello World!");` 76 | 77 | **boolean send(char channel, char * message, boolean sendNow)** sends or queues a message for later sending 78 | * **channel** Set to **SERVER** if you want to send to server. If we are the server, the value can be between '1'-'3' 79 | * **message** a character array, max 25 characters long. 80 | * **sendNow** if false, the message is appended to a buffer, if true the message is sent right away 81 | * **return** true if the message was sent 82 | * **Example:** 83 | ``` 84 | wifi.send(SERVER, "You", false); 85 | wifi.send(SERVER, " are ", false); 86 | wifi.send(SERVER, "fantastic!", true); // ie wifi.send(SERVER, "fantastic!"); 87 | ``` 88 | **endSendWithNewline(bool endSendWithNewline)** by default all messages are sent with newline and carrage return (println), you can disable this 89 | * **endSendWithNewline** sent messages with print instead of println 90 | * **Example:** `wifi.endSendWithNewline(false);` 91 | 92 | ## Checking Client Connections 93 | **boolean checkConnections(&connections)** - Updates pre-initialised pointer to 94 | WifiConnection \*connections. 95 | * **return** true if client is connected 96 | * Updated pointer is array of 3 connections: 97 | * **boolean connected** true if connected. 98 | * **char channel** channel number, can be passed to `send`. 99 | * **Example:** 100 | ``` 101 | WifiConnection *connections; 102 | 103 | wifi.checkConnections(&connections); 104 | for (int i = 0; i < MAX_CONNECTIONS; i++) { 105 | if (connections[i].connected) { 106 | // See if there is a message 107 | WifiMessage msg = wifi.getIncomingMessage(); 108 | // Check message is there 109 | if (msg.hasData) { 110 | processCommand(msg); 111 | } 112 | } 113 | } 114 | ``` 115 | 116 | ## Check Connection 117 | **boolean isConnection(void)** - Returns true if client is connected, 118 | otherwise false. Use as above without WifiConnection pointer if not 119 | bothered about multi-client. 120 | 121 | ## Get Incoming Message From Connected Client 122 | **WifiMessage getIncomingMessage(void)** - checks serial buffer for messages. 123 | Return is WifiMessage type as below. See example Check Client Connection 124 | example for usage. 125 | 126 | ## Receiving messages 127 | **WifiMessage listenForIncomingMessage(int timeoutMillis)** will listen for new messages up to timeoutMillis milliseconds. Call this method as often as possible and with as large timeoutMillis as possible to be able to catch as many messages as possible.. 128 | * **timeoutMillis** the maximum number of milliseconds to look for a new incoming message 129 | * **return** WifiMessage contains: 130 | * **boolean hasData** true if a message was received 131 | * **char channel** tells you if the message was received from the server (channel == SERVER) or another source 132 | * **char * message** the message as a character array (up to the first 25 characters) 133 | * **Example:** 134 | ``` 135 | void loop(){ 136 | WifiMessage in = wifi.listenForIncomingMessage(6000); 137 | if (in.hasData) { 138 | Serial.print("Incoming message:"); 139 | Serial.println(in.message); 140 | if(in.channel == SERVER) 141 | Serial.println("From server"); 142 | else{ 143 | Serial.print("From channel:"); 144 | Serial.println(in.channel); 145 | } 146 | } 147 | // Do other stuff 148 | } 149 | ``` 150 | 151 | ## Local access point and local server 152 | **boolean startLocalAPAndServer(char* ssid, char* password, char* channel, char* port)** will create an local access point and start a local server 153 | * **ssid** the name for your access point, max 15 characters 154 | * **password** the password for your access point, max 15 characters 155 | * **channel** the channel for your access point 156 | * **port** the port for your local server, TCP only 157 | * **return** true if the local access point and server was configured and started 158 | * **Example:** `boolean localAPAndServerStarted = wifi.startLocalAPAndServer("my_ap", "secret_pwd", "5", "2121");` 159 | 160 | **boolean stopLocalAPAndServer()** disable the accesspoint (the server will not be stopped, since a restart is needed) 161 | * **return** true if the local access point was stopped 162 | * **Example:** `boolean localAPAndServerStopped = wifi.stopLocalAPAndServer();` 163 | 164 | **boolean isLocalAPAndServerRunning()** check if local access point and server is running 165 | * **return** true if the local access point and local server is running 166 | * **Example:** `boolean localAPAndServerRunning = wifi.isLocalAPAndServerRunning();` 167 | 168 | ## Re-connect functionality 169 | Everytime send(...) and listenForIncomingMessage(..) is called a watchdog checks that the configured access point, server and local access point and server is still running, if not they will be restarted or re-connected. The same thing happens if the ESP8266 should reset. 170 | Note: It is really only the send method that can detect a lost connection to the server. To be sure you are connected, do a send once in a while.. 171 | 172 | ## Avanced configuration 173 | In SerialESP8266wifi.h you can change some stuff: 174 | * **HW_RESET_RETRIES 3** - is the maximum number of times begin() will try to start the ESP8266 module 175 | * **SERVER_CONNECT_RETRIES_BEFORE_HW_RESET 30** - is the nr of time the watchdog will try to establish connection to a server before a hardware reset of the ESP8266 is performed 176 | * The maximum number of characters for incoming and outgoing messages can be changes by editing: 177 | * char msgOut[26]; 178 | * char msgIn[26]; 179 | * If the limit for ssid and password length does not suite you, please change: 180 | * char _ssid[16]; 181 | * char _password[16]; 182 | * char _localAPSSID[16]; 183 | * char _localAPPassword[16]; 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /SerialESP8266wifi.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Serialesp8266wifi.cpp 3 | // 4 | // 5 | // Created by Jonas Ekstrand on 2015-02-20. 6 | // 7 | // 8 | 9 | #include "SerialESP8266wifi.h" 10 | #include "Arduino.h" 11 | 12 | // Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734 13 | #ifdef PROGMEM 14 | #undef PROGMEM 15 | #define PROGMEM __attribute__((section(".progmem.data"))) 16 | #endif 17 | 18 | const char OK[] PROGMEM = "OK"; 19 | const char FAIL[] PROGMEM = "FAIL"; 20 | const char ERROR[] PROGMEM = "ERROR"; 21 | const char NO_CHANGE[] PROGMEM = "no change"; 22 | 23 | const char SEND_OK[] PROGMEM = "SEND OK"; 24 | const char LINK_IS_NOT[] PROGMEM = "link is not"; 25 | const char PROMPT[] PROGMEM = ">"; 26 | const char BUSY[] PROGMEM = "busy"; 27 | const char LINKED[] PROGMEM = "Linked"; 28 | const char ALREADY[] PROGMEM = "ALREAY";//yes typo in firmware.. 29 | const char READY[] PROGMEM = "ready"; 30 | const char NO_IP[] PROGMEM = "0.0.0.0"; 31 | 32 | const char CIPSEND[] PROGMEM = "AT+CIPSEND="; 33 | const char CIPSERVERSTART[] PROGMEM = "AT+CIPSERVER=1,"; 34 | const char CIPSERVERSTOP[] PROGMEM = "AT+CIPSERVER=0"; 35 | const char CIPSTART[] PROGMEM = "AT+CIPSTART=4,\""; 36 | const char CIPCLOSE[] PROGMEM = "AT+CIPCLOSE=4"; 37 | const char TCP[] PROGMEM = "TCP"; 38 | const char UDP[] PROGMEM = "UDP"; 39 | 40 | const char CWJAP[] PROGMEM = "AT+CWJAP=\""; 41 | 42 | const char CWMODE_1[] PROGMEM = "AT+CWMODE=1"; 43 | const char CWMODE_3[] PROGMEM = "AT+CWMODE=3"; 44 | const char CWMODE_CHECK[] PROGMEM = "AT+CWMODE?"; 45 | const char CWMODE_OK[] PROGMEM = "+CWMODE:1"; 46 | 47 | const char CIFSR[] PROGMEM = "AT+CIFSR"; 48 | const char CIPMUX_1[] PROGMEM = "AT+CIPMUX=1"; 49 | 50 | const char ATE0[] PROGMEM = "ATE0"; 51 | const char ATE1[] PROGMEM = "ATE1"; 52 | 53 | const char CWSAP[] PROGMEM = "AT+CWSAP=\""; 54 | 55 | const char IPD[] PROGMEM = "IPD,"; 56 | const char CONNECT[] PROGMEM = "CONNECT"; 57 | const char CLOSED[] PROGMEM = "CLOSED"; 58 | 59 | const char COMMA[] PROGMEM = ","; 60 | const char COMMA_1[] PROGMEM = "\","; 61 | const char COMMA_2[] PROGMEM = "\",\""; 62 | const char THREE_COMMA[] PROGMEM = ",3"; 63 | const char DOUBLE_QUOTE[] PROGMEM = "\""; 64 | const char EOL[] PROGMEM = "\n"; 65 | 66 | const char STAIP[] PROGMEM = "STAIP,\""; 67 | const char STAMAC[] PROGMEM = "STAMAC,\""; 68 | 69 | SerialESP8266wifi::SerialESP8266wifi(Stream &serialIn, Stream &serialOut, byte resetPin) { 70 | _serialIn = &serialIn; 71 | _serialOut = &serialOut; 72 | _resetPin = resetPin; 73 | 74 | pinMode(_resetPin, OUTPUT); 75 | digitalWrite(_resetPin, LOW);//Start with radio off 76 | 77 | flags.connectToServerUsingTCP = true; 78 | flags.endSendWithNewline = true; 79 | flags.started = false; 80 | flags.localServerConfigured = false; 81 | flags.localApConfigured = false; 82 | flags.apConfigured = false; 83 | flags.serverConfigured = false; 84 | 85 | flags.debug = false; 86 | flags.echoOnOff = false; 87 | 88 | for (int i = 0; i < MAX_CONNECTIONS; i++) { 89 | _connections[i].channel = i + 0x30; // index to ASCII 90 | _connections[i].connected = false; 91 | } 92 | } 93 | 94 | SerialESP8266wifi::SerialESP8266wifi(Stream &serialIn, Stream &serialOut, byte resetPin, Stream &dbgSerial) { 95 | _serialIn = &serialIn; 96 | _serialOut = &serialOut; 97 | _resetPin = resetPin; 98 | 99 | pinMode(_resetPin, OUTPUT); 100 | digitalWrite(_resetPin, LOW);//Start with radio off 101 | 102 | flags.connectToServerUsingTCP = true; 103 | flags.endSendWithNewline = true; 104 | flags.started = false; 105 | flags.localServerConfigured = false; 106 | flags.localApConfigured = false; 107 | flags.apConfigured = false; 108 | flags.serverConfigured = false; 109 | 110 | _dbgSerial = &dbgSerial; 111 | flags.debug = true; 112 | flags.echoOnOff = true; 113 | 114 | for (int i = 0; i < MAX_CONNECTIONS; i++) { 115 | _connections[i].channel = i + 0x30; // index to ASCII 116 | _connections[i].connected = false; 117 | } 118 | } 119 | 120 | void niceDelay(int duration){ 121 | unsigned long startMillis = millis(); 122 | while(millis() - startMillis < duration){ 123 | sqrt(4700); 124 | } 125 | } 126 | 127 | void SerialESP8266wifi::endSendWithNewline(bool endSendWithNewline){ 128 | flags.endSendWithNewline = endSendWithNewline; 129 | } 130 | 131 | bool SerialESP8266wifi::begin() { 132 | msgOut[0] = '\0'; 133 | msgIn[0] = '\0'; 134 | flags.connectedToServer = false; 135 | flags.localServerConfigured = false; 136 | flags.localApConfigured = false; 137 | serverRetries = 0; 138 | 139 | //Do a HW reset 140 | bool statusOk = false; 141 | byte i; 142 | for(i =0; i 0; 171 | return flags.started; 172 | } 173 | 174 | bool SerialESP8266wifi::isStarted(){ 175 | return flags.started; 176 | } 177 | 178 | bool SerialESP8266wifi::restart() { 179 | return begin() 180 | && (!flags.localApConfigured || startLocalAp()) 181 | && (!flags.localServerConfigured || startLocalServer()) 182 | && (!flags.apConfigured || connectToAP()) 183 | && (!flags.serverConfigured || connectToServer()); 184 | } 185 | 186 | bool SerialESP8266wifi::connectToAP(String& ssid, String& password) { 187 | return connectToAP(ssid.c_str(), password.c_str()); 188 | } 189 | 190 | bool SerialESP8266wifi::connectToAP(const char* ssid, const char* password){//TODO make timeout config or parameter?? 191 | strncpy(_ssid, ssid, sizeof _ssid); 192 | strncpy(_password, password, sizeof _password); 193 | flags.apConfigured = true; 194 | return connectToAP(); 195 | } 196 | 197 | bool SerialESP8266wifi::connectToAP(){ 198 | writeCommand(CWJAP); 199 | _serialOut -> print(_ssid); 200 | writeCommand(COMMA_2); 201 | _serialOut -> print(_password); 202 | writeCommand(DOUBLE_QUOTE, EOL); 203 | 204 | readCommand(15000, OK, FAIL); 205 | return isConnectedToAP(); 206 | } 207 | 208 | bool SerialESP8266wifi::isConnectedToAP(){ 209 | writeCommand(CIFSR, EOL); 210 | byte code = readCommand(350, NO_IP, ERROR); 211 | readCommand(10, OK); //cleanup 212 | return (code == 0); 213 | } 214 | 215 | char* SerialESP8266wifi::getIP(){ 216 | msgIn[0] = '\0'; 217 | writeCommand(CIFSR, EOL); 218 | byte code = readCommand(1000, STAIP, ERROR); 219 | if (code == 1) { 220 | // found staip 221 | readBuffer(&msgIn[0], sizeof(msgIn) - 1, '"'); 222 | readCommand(10, OK, ERROR); 223 | return &msgIn[0]; 224 | } 225 | readCommand(1000, OK, ERROR); 226 | return &msgIn[0]; 227 | } 228 | 229 | char* SerialESP8266wifi::getMAC(){ 230 | msgIn[0] = '\0'; 231 | writeCommand(CIFSR, EOL); 232 | byte code = readCommand(1000, STAMAC, ERROR); 233 | if (code == 1) { 234 | // found stamac 235 | readBuffer(&msgIn[0], sizeof(msgIn) - 1, '"'); 236 | readCommand(10, OK, ERROR); 237 | return &msgIn[0]; 238 | } 239 | readCommand(1000, OK, ERROR); 240 | return &msgIn[0]; 241 | } 242 | 243 | void SerialESP8266wifi::setTransportToUDP(){ 244 | flags.connectToServerUsingTCP = false; 245 | } 246 | 247 | void SerialESP8266wifi::setTransportToTCP(){ 248 | flags.connectToServerUsingTCP = true; 249 | } 250 | 251 | bool SerialESP8266wifi::connectToServer(String& ip, String& port) { 252 | return connectToServer(ip.c_str(), port.c_str()); 253 | } 254 | 255 | bool SerialESP8266wifi::connectToServer(const char* ip, const char* port){//TODO make timeout config or parameter?? 256 | strncpy(_ip, ip, sizeof _ip); 257 | strncpy(_port, port, sizeof _port); 258 | flags.serverConfigured = true; 259 | return connectToServer(); 260 | } 261 | 262 | 263 | bool SerialESP8266wifi::connectToServer(){ 264 | writeCommand(CIPSTART); 265 | if (flags.connectToServerUsingTCP) 266 | writeCommand(TCP); 267 | else 268 | writeCommand(UDP); 269 | writeCommand(COMMA_2); 270 | _serialOut -> print(_ip); 271 | writeCommand(COMMA_1); 272 | _serialOut -> println(_port); 273 | 274 | flags.connectedToServer = (readCommand(10000, LINKED, ALREADY) > 0); 275 | 276 | if(flags.connectedToServer) 277 | serverRetries = 0; 278 | return flags.connectedToServer; 279 | } 280 | 281 | 282 | void SerialESP8266wifi::disconnectFromServer(){ 283 | flags.connectedToServer = false; 284 | flags.serverConfigured = false;//disable reconnect 285 | writeCommand(CIPCLOSE); 286 | readCommand(2000, OK); //fire and forget in this case.. 287 | } 288 | 289 | 290 | bool SerialESP8266wifi::isConnectedToServer(){ 291 | if(flags.connectedToServer) 292 | serverRetries = 0; 293 | return flags.connectedToServer; 294 | } 295 | 296 | bool SerialESP8266wifi::startLocalAPAndServer(const char* ssid, const char* password, const char* channel, const char* port){ 297 | strncpy(_localAPSSID, ssid, sizeof _localAPSSID); 298 | strncpy(_localAPPassword, password, sizeof _localAPPassword); 299 | strncpy(_localAPChannel, channel, sizeof _localAPChannel); 300 | strncpy(_localServerPort, port, sizeof _localServerPort); 301 | 302 | flags.localApConfigured = true; 303 | flags.localServerConfigured = true; 304 | return startLocalAp() && startLocalServer(); 305 | } 306 | 307 | bool SerialESP8266wifi::startLocalAP(const char* ssid, const char* password, const char* channel){ 308 | strncpy(_localAPSSID, ssid, sizeof _localAPSSID); 309 | strncpy(_localAPPassword, password, sizeof _localAPPassword); 310 | strncpy(_localAPChannel, channel, sizeof _localAPChannel); 311 | 312 | flags.localApConfigured = true; 313 | return startLocalAp(); 314 | } 315 | 316 | bool SerialESP8266wifi::startLocalServer(const char* port) { 317 | strncpy(_localServerPort, port, sizeof _localServerPort); 318 | flags.localServerConfigured = true; 319 | return startLocalServer(); 320 | } 321 | 322 | bool SerialESP8266wifi::startLocalServer(){ 323 | // Start local server 324 | writeCommand(CIPSERVERSTART); 325 | _serialOut -> println(_localServerPort); 326 | 327 | flags.localServerRunning = (readCommand(2000, OK, NO_CHANGE) > 0); 328 | return flags.localServerRunning; 329 | } 330 | 331 | bool SerialESP8266wifi::startLocalAp(){ 332 | // Start local ap mode (eg both local ap and ap) 333 | writeCommand(CWMODE_3, EOL); 334 | if (!readCommand(2000, OK, NO_CHANGE)) 335 | return false; 336 | 337 | // Configure the soft ap 338 | writeCommand(CWSAP); 339 | _serialOut -> print(_localAPSSID); 340 | writeCommand(COMMA_2); 341 | _serialOut -> print(_localAPPassword); 342 | writeCommand(COMMA_1); 343 | _serialOut -> print(_localAPChannel); 344 | writeCommand(THREE_COMMA, EOL); 345 | 346 | flags.localApRunning = (readCommand(5000, OK, ERROR) == 1); 347 | return flags.localApRunning; 348 | } 349 | 350 | bool SerialESP8266wifi::stopLocalServer(){ 351 | writeCommand(CIPSERVERSTOP, EOL); 352 | boolean stopped = (readCommand(2000, OK, NO_CHANGE) > 0); 353 | flags.localServerRunning = !stopped; 354 | flags.localServerConfigured = false; //to prevent autostart 355 | return stopped; 356 | } 357 | 358 | bool SerialESP8266wifi::stopLocalAP(){ 359 | writeCommand(CWMODE_1, EOL); 360 | 361 | boolean stopped = (readCommand(2000, OK, NO_CHANGE) > 0); 362 | flags.localApRunning = !stopped; 363 | flags.localApConfigured = false; //to prevent autostart 364 | return stopped; 365 | } 366 | 367 | bool SerialESP8266wifi::stopLocalAPAndServer(){ 368 | return stopLocalAP() && stopLocalServer(); 369 | } 370 | 371 | bool SerialESP8266wifi::isLocalAPAndServerRunning(){ 372 | return flags.localApRunning & flags.localServerRunning; 373 | } 374 | 375 | // Performs a connect retry (or hardware reset) if not connected 376 | bool SerialESP8266wifi::watchdog() { 377 | if (serverRetries >= SERVER_CONNECT_RETRIES_BEFORE_HW_RESET) { 378 | // give up, do a hardware reset 379 | return restart(); 380 | } 381 | if (flags.serverConfigured && !flags.connectedToServer) { 382 | serverRetries++; 383 | if (flags.apConfigured && !isConnectedToAP()) { 384 | if (!connectToAP()) { 385 | // wait a bit longer, then check again 386 | niceDelay(2000); 387 | if (!isConnectedToAP()) { 388 | return restart(); 389 | } 390 | } 391 | } 392 | return connectToServer(); 393 | } 394 | return true; 395 | } 396 | 397 | /* 398 | * Send string (if channel is connected of course) 399 | */ 400 | bool SerialESP8266wifi::send(char channel, String& message, bool sendNow) { 401 | return send(channel, message.c_str(), sendNow); 402 | } 403 | 404 | bool SerialESP8266wifi::send(char channel, const char * message, bool sendNow){ 405 | watchdog(); 406 | byte avail = sizeof(msgOut) - strlen(msgOut) - 1; 407 | strncat(msgOut, message, avail); 408 | if (!sendNow) 409 | return true; 410 | byte length = strlen(msgOut); 411 | 412 | if(flags.endSendWithNewline) 413 | length += 2; 414 | 415 | writeCommand(CIPSEND); 416 | _serialOut -> print(channel); 417 | writeCommand(COMMA); 418 | _serialOut -> println(length); 419 | byte prompt = readCommand(1000, PROMPT, LINK_IS_NOT); 420 | if (prompt != 2) { 421 | if(flags.endSendWithNewline) 422 | _serialOut -> println(msgOut); 423 | else 424 | _serialOut -> print(msgOut); 425 | byte sendStatus = readCommand(5000, SEND_OK, BUSY); 426 | if (sendStatus == 1) { 427 | msgOut[0] = '\0'; 428 | if(channel == SERVER) 429 | flags.connectedToServer = true; 430 | return true; 431 | } 432 | } 433 | //else 434 | if(channel == SERVER) 435 | flags.connectedToServer = false; 436 | else 437 | _connections[channel-0x30].connected = false; 438 | msgOut[0] = '\0'; 439 | return false; 440 | } 441 | 442 | // Checks to see if there is a client connection 443 | bool SerialESP8266wifi::isConnection(void) { 444 | WifiConnection *connections; 445 | 446 | // return the first channel, assume single connection use 447 | return checkConnections(&connections); 448 | } 449 | 450 | // Updates private connections struct and make passed pointer point to data 451 | bool SerialESP8266wifi::checkConnections(WifiConnection **pConnections) { 452 | watchdog(); 453 | // setup buffers on stack & copy data from PROGMEM pointers 454 | char buf1[16] = {'\0'}; 455 | char buf2[16] = {'\0'}; 456 | char buf3[16] = {'\0'}; 457 | strcpy_P(buf1, CONNECT); 458 | strcpy_P(buf2, READY); 459 | strcpy_P(buf3, CLOSED); 460 | byte len1 = strlen(buf1); 461 | byte len2 = strlen(buf2); 462 | byte len3 = strlen(buf3); 463 | byte pos = 0; 464 | byte pos1 = 0; 465 | byte pos2 = 0; 466 | byte pos3 = 0; 467 | byte ret = 0; 468 | char ch = '-'; 469 | 470 | // unload buffer and check match 471 | while (_serialIn->available()) { 472 | char c = readChar(); 473 | // skip white space 474 | if (c != ' ') { 475 | // get out of here if theres a message 476 | if (c == '+') 477 | break; 478 | // first char is channel 479 | if (pos == 0) 480 | ch = c; 481 | pos++; 482 | pos1 = (c == buf1[pos1]) ? pos1 + 1 : 0; 483 | pos2 = (c == buf2[pos2]) ? pos2 + 1 : 0; 484 | pos3 = (c == buf3[pos3]) ? pos3 + 1 : 0; 485 | if (len1 > 0 && pos1 == len1) { 486 | ret = 1; 487 | break; 488 | } 489 | if (len2 > 0 && pos2 == len2) { 490 | ret = 2; 491 | break; 492 | } 493 | if (len3 > 0 && pos3 == len3) { 494 | ret = 3; 495 | break; 496 | } 497 | } 498 | } 499 | 500 | if (ret == 2) 501 | restart(); 502 | 503 | // new connection 504 | if (ret == 1) { 505 | _connections[ch-0x30].connected = true; 506 | *pConnections = _connections; 507 | if (ch == SERVER) 508 | flags.connectedToServer = true; 509 | return 1; 510 | } 511 | 512 | // channel disconnected 513 | if (ret == 3) { 514 | _connections[ch-0x30].connected = false; 515 | *pConnections = _connections; 516 | if (ch == SERVER) 517 | flags.connectedToServer = false; 518 | return 0; 519 | } 520 | 521 | // nothing has changed return single connection status 522 | *pConnections = _connections; 523 | return _connections[0].connected; 524 | } 525 | 526 | WifiMessage SerialESP8266wifi::listenForIncomingMessage(int timeout){ 527 | watchdog(); 528 | char buf[16] = {'\0'}; 529 | msgIn[0] = '\0'; 530 | 531 | static WifiMessage msg; 532 | 533 | msg.hasData = false; 534 | msg.channel = '-'; 535 | msg.message = msgIn; 536 | 537 | //TODO listen for unlink etc... 538 | byte msgOrRestart = readCommand(timeout, IPD, READY); 539 | 540 | //Detected a esp8266 restart 541 | if (msgOrRestart == 2){ 542 | restart(); 543 | return msg; 544 | } 545 | //Message received.. 546 | else if (msgOrRestart == 1) { 547 | char channel = readChar(); 548 | if (channel == SERVER) 549 | flags.connectedToServer = true; 550 | readChar(); // removing comma 551 | readBuffer(&buf[0], sizeof(buf) - 1, ':'); // read char count 552 | readChar(); // removing ':' delim 553 | byte length = atoi(buf); 554 | readBuffer(&msgIn[0], min(length, sizeof(msgIn) - 1)); 555 | msg.hasData = true; 556 | msg.channel = channel; 557 | msg.message = msgIn; 558 | readCommand(10, OK); // cleanup after rx 559 | } 560 | return msg; 561 | } 562 | 563 | WifiMessage SerialESP8266wifi::getIncomingMessage(void) { 564 | watchdog(); 565 | char buf[16] = {'\0'}; 566 | msgIn[0] = '\0'; 567 | 568 | static WifiMessage msg; 569 | 570 | msg.hasData = false; 571 | msg.channel = '-'; 572 | msg.message = msgIn; 573 | 574 | // See if a message has come in (block 1s otherwise misses?) 575 | byte msgOrRestart = readCommand(10, IPD, READY); 576 | 577 | //Detected a esp8266 restart 578 | if (msgOrRestart == 2){ 579 | restart(); 580 | return msg; 581 | } 582 | //Message received.. 583 | else if (msgOrRestart == 1) { 584 | char channel = readChar(); 585 | if (channel == SERVER) 586 | flags.connectedToServer = true; 587 | readChar(); // removing comma 588 | readBuffer(&buf[0], sizeof(buf) - 1, ':'); // read char count 589 | readChar(); // removing ':' delim 590 | byte length = atoi(buf); 591 | readBuffer(&msgIn[0], min(length, sizeof(msgIn) - 1)); 592 | msg.hasData = true; 593 | msg.channel = channel; 594 | msg.message = msgIn; 595 | readCommand(10, OK); // cleanup after rx 596 | } 597 | return msg; 598 | } 599 | 600 | // Writes commands (from PROGMEM) to serial output 601 | void SerialESP8266wifi::writeCommand(const char* text1 = NULL, const char* text2) { 602 | char buf[16] = {'\0'}; 603 | strcpy_P(buf, (char *) text1); 604 | _serialOut->print(buf); 605 | if (text2 == EOL) { 606 | _serialOut->println(); 607 | } else if (text2 != NULL) { 608 | strcpy_P(buf, (char *) text2); 609 | _serialOut->print(buf); 610 | } 611 | } 612 | 613 | // Reads from serial input until a expected string is found (or until timeout) 614 | // NOTE: strings are stored in PROGMEM (auto-copied by this method) 615 | byte SerialESP8266wifi::readCommand(int timeout, const char* text1, const char* text2) { 616 | // setup buffers on stack & copy data from PROGMEM pointers 617 | char buf1[16] = {'\0'}; 618 | char buf2[16] = {'\0'}; 619 | if (text1 != NULL) 620 | strcpy_P(buf1, (char *) text1); 621 | if (text2 != NULL) 622 | strcpy_P(buf2, (char *) text2); 623 | byte len1 = strlen(buf1); 624 | byte len2 = strlen(buf2); 625 | byte pos1 = 0; 626 | byte pos2 = 0; 627 | 628 | // read chars until first match or timeout 629 | unsigned long stop = millis() + timeout; 630 | do { 631 | while (_serialIn->available()) { 632 | char c = readChar(); 633 | pos1 = (c == buf1[pos1]) ? pos1 + 1 : 0; 634 | pos2 = (c == buf2[pos2]) ? pos2 + 1 : 0; 635 | if (len1 > 0 && pos1 == len1) 636 | return 1; 637 | if (len2 > 0 && pos2 == len2) 638 | return 2; 639 | } 640 | niceDelay(10); 641 | } while (millis() < stop); 642 | return 0; 643 | } 644 | 645 | // Unload buffer without delay 646 | /*byte ESP8266wifiESP8266wifi::readCommand(const char* text1, const char* text2) { 647 | // setup buffers on stack & copy data from PROGMEM pointers 648 | char buf1[16] = {'\0'}; 649 | char buf2[16] = {'\0'}; 650 | if (text1 != NULL) 651 | strcpy_P(buf1, (char *) text1); 652 | if (text2 != NULL) 653 | strcpy_P(buf2, (char *) text2); 654 | byte len1 = strlen(buf1); 655 | byte len2 = strlen(buf2); 656 | byte pos1 = 0; 657 | byte pos2 = 0; 658 | 659 | // read chars until first match or timeout 660 | while (_serialIn->available()) { 661 | char c = readChar(); 662 | pos1 = (c == buf1[pos1]) ? pos1 + 1 : 0; 663 | pos2 = (c == buf2[pos2]) ? pos2 + 1 : 0; 664 | if (len1 > 0 && pos1 == len1) 665 | return 1; 666 | if (len2 > 0 && pos2 == len2) 667 | return 2; 668 | } 669 | return 0; 670 | }*/ 671 | 672 | // Reads count chars to a buffer, or until delim char is found 673 | byte SerialESP8266wifi::readBuffer(char* buf, byte count, char delim) { 674 | byte pos = 0; 675 | char c; 676 | while (_serialIn->available() && pos < count) { 677 | c = readChar(); 678 | if (c == delim) 679 | break; 680 | buf[pos++] = c; 681 | } 682 | buf[pos] = '\0'; 683 | return pos; 684 | } 685 | 686 | // Reads a single char from serial input (with debug printout if configured) 687 | char SerialESP8266wifi::readChar() { 688 | char c = _serialIn->read(); 689 | if (flags.debug) 690 | _dbgSerial->print(c); 691 | else 692 | sqrt(12345);//delayMicroseconds(50); // don't know why 693 | return c; 694 | } 695 | -------------------------------------------------------------------------------- /SerialESP8266wifi.h: -------------------------------------------------------------------------------- 1 | // 2 | // SerialESP8266wifi.h 3 | // 4 | // 5 | // Created by Jonas Ekstrand on 2015-02-20. 6 | // ESP8266 AT cmd ref from https://github.com/espressif/esp8266_at/wiki/CIPSERVER 7 | // 8 | // 9 | 10 | #ifndef SerialESP8266wifi_h 11 | #define SerialESP8266wifi_h 12 | 13 | #define HW_RESET_RETRIES 3 14 | #define SERVER_CONNECT_RETRIES_BEFORE_HW_RESET 3 15 | 16 | #if defined(ARDUINO) && ARDUINO >= 100 17 | #include "Arduino.h" 18 | #else 19 | #include "WProgram.h" 20 | #endif 21 | 22 | #include 23 | 24 | #if defined(SerialESP8266) 25 | #include 26 | #else 27 | #include 28 | #endif 29 | 30 | #include "HardwareSerial.h" 31 | 32 | #define SERVER '4' 33 | #define MAX_CONNECTIONS 3 34 | 35 | #define MSG_BUFFER_MAX 128 36 | 37 | struct WifiMessage{ 38 | public: 39 | bool hasData:1; 40 | char channel; 41 | char * message; 42 | }; 43 | 44 | struct WifiConnection{ 45 | public: 46 | char channel; 47 | bool connected:1; 48 | }; 49 | 50 | struct Flags // 1 byte value (on a system where 8 bits is a byte 51 | { 52 | bool started:1, 53 | echoOnOff:1, 54 | debug:1, 55 | serverConfigured:1, // true if a connection to a remote server is configured 56 | connectedToServer:1, // true if a connection to a remote server is established 57 | apConfigured:1, // true if the module is configured as a client station 58 | localApConfigured:1, 59 | localServerConfigured:1, 60 | localApRunning:1, 61 | localServerRunning:1, 62 | endSendWithNewline:1, 63 | connectToServerUsingTCP:1; 64 | }; 65 | 66 | class SerialESP8266wifi 67 | { 68 | 69 | public: 70 | /* 71 | * Will pull resetPin low then high to reset esp8266, connect this pin to CHPD pin 72 | */ 73 | SerialESP8266wifi(Stream &serialIn, Stream &serialOut, byte resetPin); 74 | 75 | 76 | /* 77 | * Will pull resetPin low then high to reset esp8266, connect this pin to CHPD pin 78 | */ 79 | SerialESP8266wifi(Stream &serialIn, Stream &serialOut, byte resetPin, Stream &dbgSerial); 80 | 81 | /* 82 | * Will do hw reset and set inital configuration, will try this HW_RESET_RETRIES times. 83 | */ 84 | bool begin(); // reset and set echo and other stuff 85 | 86 | bool isStarted(); 87 | 88 | /* 89 | * Connect to AP using wpa encryption 90 | * (reconnect logic is applied, if conn lost or not established, or esp8266 restarted) 91 | */ 92 | bool connectToAP(String& ssid, String& password); 93 | bool connectToAP(const char* ssid, const char* password); 94 | bool isConnectedToAP(); 95 | char* getIP(); 96 | char* getMAC(); 97 | 98 | /* 99 | * Evaluate the connection and perform reconnects if needed. Eventually perform reset and restart. 100 | * 101 | */ 102 | bool watchdog(); 103 | 104 | /* 105 | * Connecting with TCP to server 106 | * (reconnect logic is applied, if conn lost or not established, or esp8266 restarted) 107 | */ 108 | 109 | void setTransportToUDP(); 110 | //Default.. 111 | void setTransportToTCP(); 112 | bool connectToServer(String& ip, String& port); 113 | bool connectToServer(const char* ip, const char* port); 114 | void disconnectFromServer(); 115 | bool isConnectedToServer(); 116 | 117 | /* 118 | * Starting local AP and local TCP-server 119 | * (reconnect logic is applied, if conn lost or not established, or esp8266 restarted) 120 | */ 121 | bool startLocalAPAndServer(const char* ssid, const char* password, const char* channel,const char* port); 122 | bool startLocalAP(const char* ssid, const char* password, const char* channel); 123 | bool startLocalServer(const char* port); 124 | bool stopLocalAPAndServer(); 125 | bool stopLocalAP(); 126 | bool stopLocalServer(); 127 | bool isLocalAPAndServerRunning(); 128 | 129 | 130 | /* 131 | * Send string (if channel is connected of course) 132 | */ 133 | bool send(char channel, String& message, bool sendNow = true); 134 | bool send(char channel, const char * message, bool sendNow = true); 135 | 136 | /* 137 | * Default is true. 138 | */ 139 | void endSendWithNewline(bool endSendWithNewline); 140 | 141 | /* 142 | * Scan for incoming message, do this as often and as long as you can (use as sleep in loop) 143 | */ 144 | WifiMessage listenForIncomingMessage(int timeoutMillis); 145 | WifiMessage getIncomingMessage(void); 146 | bool isConnection(void); 147 | bool checkConnections(WifiConnection **pConnections); 148 | 149 | private: 150 | Stream* _serialIn; 151 | Stream* _serialOut; 152 | byte _resetPin; 153 | 154 | Flags flags; 155 | 156 | bool connectToServer(); 157 | char _ip[16]; 158 | char _port[6]; 159 | 160 | bool connectToAP(); 161 | char _ssid[16]; 162 | char _password[16]; 163 | 164 | bool startLocalAp(); 165 | bool startLocalServer(); 166 | char _localAPSSID[16]; 167 | char _localAPPassword[16]; 168 | char _localAPChannel[3]; 169 | char _localServerPort[6]; 170 | WifiConnection _connections[MAX_CONNECTIONS]; 171 | 172 | bool restart(); 173 | 174 | byte serverRetries; 175 | 176 | 177 | char msgOut[MSG_BUFFER_MAX];//buffer for send method 178 | char msgIn[MSG_BUFFER_MAX]; //buffer for listen method = limit of incoming message.. 179 | 180 | void writeCommand(const char* text1, const char* text2 = NULL); 181 | byte readCommand(int timeout, const char* text1 = NULL, const char* text2 = NULL); 182 | //byte readCommand(const char* text1, const char* text2); 183 | byte readBuffer(char* buf, byte count, char delim = '\0'); 184 | char readChar(); 185 | Stream* _dbgSerial; 186 | }; 187 | 188 | #endif 189 | -------------------------------------------------------------------------------- /examples/SerialESP8266_library_test/SerialESP8266_library_test.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define sw_serial_rx_pin 4 // Connect this pin to TX on the esp8266 5 | #define sw_serial_tx_pin 6 // Connect this pin to RX on the esp8266 6 | #define esp8266_reset_pin 5 // Connect this pin to CH_PD on the esp8266, not reset. (let reset be unconnected) 7 | 8 | SoftwareSerial swSerial(sw_serial_rx_pin, sw_serial_tx_pin); 9 | 10 | // the last parameter sets the local echo option for the ESP8266 module.. 11 | SerialESP8266wifi wifi(swSerial, swSerial, esp8266_reset_pin, Serial);//adding Serial enabled local echo and wifi debug 12 | 13 | String inputString; 14 | boolean stringComplete = false; 15 | unsigned long nextPing = 0; 16 | 17 | void setup() { 18 | inputString.reserve(20); 19 | swSerial.begin(9600); 20 | Serial.begin(9600); 21 | while (!Serial) 22 | ; 23 | Serial.println("Starting wifi"); 24 | 25 | wifi.setTransportToTCP();// this is also default 26 | // wifi.setTransportToUDP();//Will use UDP when connecting to server, default is TCP 27 | 28 | wifi.endSendWithNewline(true); // Will end all transmissions with a newline and carrage return ie println.. default is true 29 | 30 | wifi.begin(); 31 | 32 | //Turn on local ap and server (TCP) 33 | wifi.startLocalAPAndServer("MY_CONFIG_AP", "password", "5", "2121"); 34 | 35 | wifi.connectToAP("wifissid", "wifipass"); 36 | wifi.connectToServer("192.168.0.28", "2121"); 37 | wifi.send(SERVER, "ESP8266 test app started"); 38 | } 39 | 40 | void loop() { 41 | 42 | //Make sure the esp8266 is started.. 43 | if (!wifi.isStarted()) 44 | wifi.begin(); 45 | 46 | //Send what you typed in the arduino console to the server 47 | static char buf[20]; 48 | if (stringComplete) { 49 | inputString.toCharArray(buf, sizeof buf); 50 | wifi.send(SERVER, buf); 51 | inputString = ""; 52 | stringComplete = false; 53 | } 54 | 55 | //Send a ping once in a while.. 56 | if (millis() > nextPing) { 57 | wifi.send(SERVER, "Ping ping.."); 58 | nextPing = millis() + 10000; 59 | } 60 | 61 | //Listen for incoming messages and echo back, will wait until a message is received, or max 6000ms.. 62 | WifiMessage in = wifi.listenForIncomingMessage(6000); 63 | if (in.hasData) { 64 | if (in.channel == SERVER) 65 | Serial.println("Message from the server:"); 66 | else 67 | Serial.println("Message a local client:"); 68 | Serial.println(in.message); 69 | //Echo back; 70 | wifi.send(in.channel, "Echo:", false); 71 | wifi.send(in.channel, in.message); 72 | nextPing = millis() + 10000; 73 | } 74 | 75 | //If you want do disconnect from the server use: 76 | // wifi.disconnectFromServer(); 77 | 78 | } 79 | 80 | //Listen for serial input from the console 81 | void serialEvent() { 82 | while (Serial.available()) { 83 | char inChar = (char)Serial.read(); 84 | inputString += inChar; 85 | if (inChar == '\n') { 86 | stringComplete = true; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /examples/SerialESP8266_tcp_cli/SerialESP8266_tcp_cli.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* TCP server/client example, that manages client connections, checks for messages 5 | * when client is connected and parses commands. Connect to the ESP8266 IP using 6 | * a TCP client such as telnet, eg: telnet 192.168.0.X 2121 7 | * 8 | * ESP8266 should be AT firmware based on 1.5 SDK or later 9 | * 10 | * 2016 - J.Whittington - engineer.john-whittington.co.uk 11 | */ 12 | 13 | #define sw_serial_rx_pin 4 // Connect this pin to TX on the esp8266 14 | #define sw_serial_tx_pin 6 // Connect this pin to RX on the esp8266 15 | #define esp8266_reset_pin 5 // Connect this pin to CH_PD on the esp8266, not reset. (let reset be unconnected) 16 | 17 | #define SERVER_PORT "2121" 18 | #define SSID "YourSSID" 19 | #define PASSWORD "YourPassword" 20 | 21 | SoftwareSerial swSerial(sw_serial_rx_pin, sw_serial_tx_pin); 22 | 23 | // the last parameter sets the local echo option for the ESP8266 module.. 24 | SerialESP8266wifi wifi(Serial, Serial, esp8266_reset_pin, swSerial); 25 | 26 | void processCommand(WifiMessage msg); 27 | 28 | uint8_t wifi_started = false; 29 | 30 | // TCP Commands 31 | const char RST[] PROGMEM = "RST"; 32 | const char IDN[] PROGMEM = "*IDN?"; 33 | 34 | void setup() { 35 | 36 | // start debug serial 37 | swSerial.begin(9600); 38 | // start HW serial for ESP8266 (change baud depending on firmware) 39 | Serial.begin(115200); 40 | while (!Serial) 41 | ; 42 | Serial.println("Starting wifi"); 43 | 44 | swSerial.println("Starting wifi"); 45 | wifi.setTransportToTCP();// this is also default 46 | wifi.endSendWithNewline(false); // Will end all transmissions with a newline and carrage return ie println.. default is true 47 | 48 | wifi_started = wifi.begin(); 49 | if (wifi_started) { 50 | wifi.connectToAP(SSID, PASSWORD); 51 | wifi.startLocalServer(SERVER_PORT); 52 | } else { 53 | // ESP8266 isn't working.. 54 | } 55 | } 56 | 57 | void loop() { 58 | 59 | static WifiConnection *connections; 60 | 61 | // check connections if the ESP8266 is there 62 | if (wifi_started) 63 | wifi.checkConnections(&connections); 64 | 65 | // check for messages if there is a connection 66 | for (int i = 0; i < MAX_CONNECTIONS; i++) { 67 | if (connections[i].connected) { 68 | // See if there is a message 69 | WifiMessage msg = wifi.getIncomingMessage(); 70 | // Check message is there 71 | if (msg.hasData) { 72 | // process the command 73 | processCommand(msg); 74 | } 75 | } 76 | } 77 | } 78 | 79 | void processCommand(WifiMessage msg) { 80 | // return buffer 81 | char espBuf[MSG_BUFFER_MAX]; 82 | // scanf holders 83 | int set; 84 | char str[16]; 85 | 86 | // Get command and setting 87 | sscanf(msg.message,"%15s %d",str,&set); 88 | /* swSerial.print(str);*/ 89 | /* swSerial.println(set);*/ 90 | 91 | if ( !strcmp_P(str,IDN) ) { 92 | wifi.send(msg.channel,"ESP8266wifi Example"); 93 | } 94 | // Reset system by temp enable watchdog 95 | else if ( !strcmp_P(str,RST) ) { 96 | wifi.send(msg.channel,"SYSTEM RESET..."); 97 | // soft reset by reseting PC 98 | asm volatile (" jmp 0"); 99 | } 100 | // Unknown command 101 | else { 102 | wifi.send(msg.channel,"ERR"); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SerialESP8266wifi", 3 | "keywords": "wifi, wi-fi, http, web, server, client", 4 | "description": "ESP8266 Arduino library with built in reconnect functionality", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/ekstrand/ESP8266wifi.git" 9 | }, 10 | "frameworks": "arduino", 11 | "platforms": "atmelavr" 12 | } 13 | --------------------------------------------------------------------------------