├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── examples ├── ESP8266_GPIO_Blink │ └── ESP8266_GPIO_Blink.ino ├── ESP8266_Phant │ └── ESP8266_Phant.ino ├── ESP8266_Phant_Library │ └── ESP8266_Phant_Library.ino ├── ESP8266_Ping │ └── ESP8266_Ping.ino ├── ESP8266_Serial_Passthrough │ └── ESP8266_Serial_Passthrough.ino └── ESP8266_Shield_Demo │ └── ESP8266_Shield_Demo.ino ├── extras ├── 4A-ESP8266 AT Instrction Set_EN_V0.23b1.pdf └── 4B-ESP8266 AT Command Examples_EN_V0.4.pdf ├── keywords.txt ├── library.properties └── src ├── SparkFunESP8266Client.cpp ├── SparkFunESP8266Client.h ├── SparkFunESP8266Server.cpp ├── SparkFunESP8266Server.h ├── SparkFunESP8266WiFi.cpp ├── SparkFunESP8266WiFi.h └── util └── ESP8266_AT.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | #Eagle Backup files 6 | *.s#? 7 | *.b#? 8 | *.l#? 9 | 10 | # Folder config file 11 | Desktop.ini 12 | 13 | # Recycle Bin used on file shares 14 | $RECYCLE.BIN/ 15 | 16 | # Windows Installer files 17 | *.cab 18 | *.msi 19 | *.msm 20 | *.msp 21 | 22 | # ========================= 23 | # Operating System Files 24 | # ========================= 25 | 26 | # OSX 27 | # ========================= 28 | 29 | .DS_Store 30 | .AppleDouble 31 | .LSOverride 32 | 33 | # Icon must ends with two \r. 34 | Icon 35 | 36 | # Thumbnails 37 | ._* 38 | 39 | # Files that might appear on external disk 40 | .Spotlight-V100 41 | .Trashes 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 SparkFun Electronics 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 | SparkFun ESP8266 AT Arduino Library 2 | ======================================== 3 | 4 | ![SparkFun ESP8266 WiFi Shield](https://cdn.sparkfun.com//assets/parts/1/0/5/3/8/13287-01.jpg) 5 | 6 | [*SparkFun ESP8266 WiFi Shield (WRL-13287)*](https://www.sparkfun.com/products/13287) 7 | 8 | An Arduino library for the SparkFun ESP8266 WiFi Shield. This library makes it easy to connect to WiFi networks, and also implements TCP/IP client and server. 9 | 10 | Repository Contents 11 | ------------------- 12 | 13 | * **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE. 14 | * **/extras** - Additional documentation for the user. These files are ignored by the IDE. 15 | * **/src** - Source files for the library (.cpp, .h). 16 | * **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE. 17 | * **library.properties** - General library properties for the Arduino package manager. 18 | 19 | Documentation 20 | -------------- 21 | 22 | * **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library. 23 | * **[Product Repository](https://github.com/sparkfun/ESP8266_WiFi_Shield)** - Main repository (including hardware files) for the ESP8266 WiFi Shield. 24 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/esp8266-wifi-shield-hookup-guide)** - Basic hookup guide for the ESP8266 WiFi Shield. 25 | 26 | Products that use this Library 27 | --------------------------------- 28 | 29 | * [SparkFun ESP8266 WiFi Shield (WRL-13287)](https://www.sparkfun.com/products/13287) - An Arduino shield featuring the ESP8266 WiFi SoC. 30 | 31 | Version History 32 | --------------- 33 | 34 | License Information 35 | ------------------- 36 | 37 | This product is _**open source**_! 38 | 39 | Please review the LICENSE.md file for license information. 40 | 41 | If you have any questions or concerns on licensing, please contact support@sparkfun.com. 42 | 43 | The **code** is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! 44 | 45 | Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release any derivative under the same license. 46 | 47 | Distributed as-is; no warranty is given. 48 | 49 | - Your friends at SparkFun. 50 | -------------------------------------------------------------------------------- /examples/ESP8266_GPIO_Blink/ESP8266_GPIO_Blink.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | ESP8266_GPIO_Blink.h 3 | SparkFun ESP8266 AT library - GPIO Blink Demo 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: July 16, 2015 6 | https://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | This example uses the ESP8266 GPIO commands to control the 9 | ESP8266's onboard LED, attached to pin 5. 10 | 11 | Note: Once pin 5 is set to a mode with pinMode, it will not 12 | show the WiFi state. Resetting the ESP8266 with either 13 | esp8266.reset() or cycling power, will set the pin 5 LED back 14 | to a STAT indicator. 15 | 16 | The ESP8266 WiFi Shield GPIO API includes: 17 | - esp8266.pinMode([pin], [mode]) 18 | - esp8266.digitalWrite([pin], [state]) 19 | - [state] esp8266.digitalRead([pin]) 20 | 21 | [pin] can be any of 0, 2, 4, 5, 12, 13, 14, 15, 16 (XPD). 22 | [mode] can be INPUT, OUTPUT, or INPUT_PULLUP 23 | [state] can be HIGH or LOW 24 | 25 | Development environment specifics: 26 | IDE: Arduino 1.6.5 27 | Hardware Platform: Arduino Uno 28 | ESP8266 WiFi Shield Version: 1.0 29 | 30 | This code is released under the MIT license. 31 | 32 | Distributed as-is; no warranty is given. 33 | ************************************************************/ 34 | 35 | #include 36 | #include 37 | 38 | void setup() 39 | { 40 | Serial.begin(9600); 41 | // Initialize the ESP8266 shield, make sure it's present: 42 | while (esp8266.begin() != true) 43 | { 44 | Serial.print("Error connecting to ESP8266."); 45 | delay(1000); 46 | } 47 | // Set pin 5 (STAT LED) to OUTPUT: 48 | esp8266.pinMode(5, OUTPUT); 49 | } 50 | 51 | void loop() 52 | { 53 | esp8266.digitalWrite(5, HIGH); 54 | delay(500); 55 | esp8266.digitalWrite(5, LOW); 56 | delay(500); 57 | } 58 | -------------------------------------------------------------------------------- /examples/ESP8266_Phant/ESP8266_Phant.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | ESP8266_Phant.ino 3 | SparkFun ESP8266 AT library - Phant Posting Example 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: July 16, 2015 6 | https://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | This example demonstrates how to use the TCP client 9 | functionality of the SparkFun ESP8266 WiFi library to post 10 | sensor readings to a Phant stream on 11 | https://data.sparkfun.com 12 | 13 | This sketch is set up to post to a publicly available stream 14 | https://data.sparkfun.com/streams/DJjNowwjgxFR9ogvr45Q 15 | Please don't abuse it! But feel free to post a few times to 16 | verify the sketch works. If it fails, check the HTTP response 17 | to make sure the post rate hasn't been exceeded. 18 | 19 | Development environment specifics: 20 | IDE: Arduino 1.6.5 21 | Hardware Platform: Arduino Uno 22 | ESP8266 WiFi Shield Version: 1.0 23 | 24 | This code is beerware; if you see me (or any other SparkFun 25 | employee) at the local, and you've found our code helpful, 26 | please buy us a round! 27 | 28 | Distributed as-is; no warranty is given. 29 | ************************************************************/ 30 | // The SparkFunESP8266WiFi library uses SoftwareSerial 31 | // to communicate with the ESP8266 module. Include that 32 | // library first: 33 | #include 34 | // Include the ESP8266 AT library: 35 | #include 36 | 37 | ////////////////////////////// 38 | // WiFi Network Definitions // 39 | ////////////////////////////// 40 | // Replace these two character strings with the name and 41 | // password of your WiFi network. 42 | const char mySSID[] = "PiFi"; 43 | const char myPSK[] = "sparkfun"; 44 | 45 | ///////////////////// 46 | // Phant Constants // 47 | ///////////////////// 48 | // Phant detsination server: 49 | const String phantServer = "data.sparkfun.com"; 50 | // Phant public key: 51 | const String publicKey = "DJjNowwjgxFR9ogvr45Q"; 52 | // Phant private key: 53 | const String privateKey = "P4eKwGGek5tJVz9Ar84n"; 54 | String httpHeader = "POST /input/" + publicKey + ".txt HTTP/1.1\n" + 55 | "Host: " + phantServer + "\n" + 56 | "Phant-Private-Key: " + privateKey + "\n" + 57 | "Connection: close\n" + 58 | "Content-Type: application/x-www-form-urlencoded\n"; 59 | 60 | void setup() 61 | { 62 | int status; 63 | Serial.begin(9600); 64 | 65 | // To turn the MG2639 shield on, and verify communication 66 | // always begin a sketch by calling cell.begin(). 67 | status = esp8266.begin(); 68 | if (status <= 0) 69 | { 70 | Serial.println(F("Unable to communicate with shield. Looping")); 71 | while(1) ; 72 | } 73 | 74 | esp8266.setMode(ESP8266_MODE_STA); // Set WiFi mode to station 75 | if (esp8266.status() <= 0) // If we're not already connected 76 | { 77 | if (esp8266.connect(mySSID, myPSK) < 0) 78 | { 79 | Serial.println(F("Error connecting")); 80 | while (1) ; 81 | } 82 | } 83 | 84 | // Get our assigned IP address and print it: 85 | Serial.print(F("My IP address is: ")); 86 | Serial.println(esp8266.localIP()); 87 | 88 | Serial.println(F("Press any key to post to Phant!")); 89 | } 90 | 91 | void loop() 92 | { 93 | // If a character has been received over serial: 94 | if (Serial.available()) 95 | { 96 | // !!! Make sure we haven't posted recently 97 | // Post to Phant! 98 | postToPhant(); 99 | // Then clear the serial buffer: 100 | while (Serial.available()) 101 | Serial.read(); 102 | } 103 | } 104 | 105 | void postToPhant() 106 | { 107 | // Create a client, and initiate a connection 108 | ESP8266Client client; 109 | 110 | if (client.connect(phantServer, 80) <= 0) 111 | { 112 | Serial.println(F("Failed to connect to server.")); 113 | return; 114 | } 115 | Serial.println(F("Connected.")); 116 | 117 | // Set up our Phant post parameters: 118 | String params; 119 | params += "analog0=" + String(analogRead(A0)) + "&"; 120 | params += "analog1=" + String(analogRead(A1)) + "&"; 121 | params += "analog2=" + String(analogRead(A2)) + "&"; 122 | params += "analog3=" + String(analogRead(A3)) + "&"; 123 | params += "analog4=" + String(analogRead(A4)) + "&"; 124 | params += "analog5=" + String(analogRead(A5)); 125 | 126 | Serial.println(F("Posting to Phant!")); 127 | 128 | client.print(httpHeader); 129 | client.print("Content-Length: "); client.println(params.length()); 130 | client.println(); 131 | client.print(params); 132 | 133 | // available() will return the number of characters 134 | // currently in the receive buffer. 135 | while (client.available()) 136 | Serial.write(client.read()); // read() gets the FIFO char 137 | 138 | // connected() is a boolean return value - 1 if the 139 | // connection is active, 0 if it's closed. 140 | if (client.connected()) 141 | client.stop(); // stop() closes a TCP connection. 142 | } -------------------------------------------------------------------------------- /examples/ESP8266_Phant_Library/ESP8266_Phant_Library.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | ESP8266_Phant_Library.h 3 | SparkFun ESP8266 AT library - Phant Posting Example 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: July 16, 2015 6 | https://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | This example demonstrates how to use the TCP client 9 | functionality of the SparkFun ESP8266 WiFi library to post 10 | sensor readings to a Phant stream on 11 | https://data.sparkfun.com 12 | 13 | This sketch is set up to post to a publicly available stream 14 | https://data.sparkfun.com/streams/DJjNowwjgxFR9ogvr45Q 15 | Please don't abuse it! But feel free to post a few times to 16 | verify the sketch works. If it fails, check the HTTP response 17 | to make sure the post rate hasn't been exceeded. 18 | 19 | This sketch also requires that the Phant Arduino library be 20 | installed. You can download it from the GitHub repository: 21 | https://github.com/sparkfun/phant-arduino 22 | 23 | Development environment specifics: 24 | IDE: Arduino 1.6.5 25 | Hardware Platform: Arduino Uno 26 | ESP8266 WiFi Shield Version: 1.0 27 | 28 | This code is beerware; if you see me (or any other SparkFun 29 | employee) at the local, and you've found our code helpful, 30 | please buy us a round! 31 | 32 | Distributed as-is; no warranty is given. 33 | ************************************************************/ 34 | // The SparkFunESP8266WiFi library uses SoftwareSerial 35 | // to communicate with the ESP8266 module. Include that 36 | // library first: 37 | #include 38 | // Include the ESP8266 AT library: 39 | #include 40 | // This example also requires the Phant Arduino library. 41 | // Download the library from our GitHub repo: 42 | // https://github.com/sparkfun/phant-arduino 43 | #include 44 | 45 | ////////////////////////////// 46 | // WiFi Network Definitions // 47 | ////////////////////////////// 48 | // Replace these two character strings with the name and 49 | // password of your WiFi network. 50 | //const char mySSID[] = "PiFi"; 51 | //const char myPSK[] = "sparkfun"; 52 | 53 | //IPAddress myIP; // IPAddress to store the local IP 54 | 55 | ///////////////////// 56 | // Phant Constants // 57 | ///////////////////// 58 | // Phant detsination server: 59 | const char phantServer[] = "data.sparkfun.com"; 60 | // Phant public key: 61 | const char publicKey[] = "DJjNowwjgxFR9ogvr45Q"; 62 | // Phant private key: 63 | const char privateKey[] = "P4eKwGGek5tJVz9Ar84n"; 64 | // Create a Phant object, which we'll use from here on: 65 | Phant phant(phantServer, publicKey, privateKey); 66 | 67 | void setup() 68 | { 69 | int status; 70 | Serial.begin(9600); 71 | 72 | // To turn the MG2639 shield on, and verify communication 73 | // always begin a sketch by calling cell.begin(). 74 | status = esp8266.begin(); 75 | if (status <= 0) 76 | { 77 | Serial.println(F("Unable to communicate with shield. Looping")); 78 | while(1) ; 79 | } 80 | /* 81 | esp8266.setMode(ESP8266_MODE_STA); // Set WiFi mode to station 82 | if (esp8266.status() <= 0) // If we're not already connected 83 | { 84 | if (esp8266.connect(mySSID, myPSK) < 0) 85 | { 86 | Serial.println(F("Error connecting")); 87 | while (1) ; 88 | } 89 | } 90 | 91 | // Get our assigned IP address and print it: 92 | Serial.print(F("My IP address is: ")); 93 | Serial.println(esp8266.localIP());*/ 94 | 95 | Serial.println(F("Press any key to post to Phant!")); 96 | } 97 | 98 | void loop() 99 | { 100 | /* 101 | // If data has been sent over a TCP link: 102 | if (.available()) 103 | { // Print it to the serial monitor: 104 | Serial.write(gprs.read()); 105 | }*/ 106 | // If a character has been received over serial: 107 | if (Serial.available()) 108 | { 109 | // !!! Make sure we haven't posted recently 110 | // Post to Phant! 111 | postToPhant(); 112 | // Then clear the serial buffer: 113 | while (Serial.available()) 114 | Serial.read(); 115 | } 116 | } 117 | 118 | void postToPhant() 119 | { 120 | // Create a client, and initiate a connection 121 | ESP8266Client client; 122 | 123 | if (client.connect(phantServer, 80) <= 0) 124 | { 125 | Serial.println(F("Failed to connect to server.")); 126 | return; 127 | } 128 | Serial.println(F("Connected.")); 129 | 130 | // Set up our Phant post using the Phant library. For 131 | // each field in the Phant stream we need to call 132 | // phant.add([field], value). 133 | // Value can be any data type, in this case we're only 134 | // using integers. 135 | phant.add(F("analog0"), analogRead(A0)); 136 | phant.add(F("analog1"), analogRead(A1)); 137 | phant.add(F("analog2"), analogRead(A2)); 138 | phant.add(F("analog3"), analogRead(A3)); 139 | phant.add(F("analog4"), analogRead(A4)); 140 | phant.add(F("analog5"), analogRead(A5)); 141 | // Storing fields in flash (F()) will save a good chunk 142 | // of RAM, which is very precious. 143 | 144 | Serial.println(F("Posting to Phant!")); 145 | // Encapsulate a phant.post() inside a gprs.print(). 146 | // phant.post() takes care of everything in the HTTP header 147 | // including newlines. 148 | client.print(phant.post()); 149 | 150 | // available() will return the number of characters 151 | // currently in the receive buffer. 152 | while (client.available()) 153 | Serial.write(client.read()); // read() gets the FIFO char 154 | 155 | // connected() is a boolean return value - 1 if the 156 | // connection is active, 0 if it's closed. 157 | if (client.connected()) 158 | client.stop(); // stop() closes a TCP connection. 159 | } 160 | -------------------------------------------------------------------------------- /examples/ESP8266_Ping/ESP8266_Ping.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | ESP8266_Ping.h 3 | SparkFun ESP8266 AT library - Ping Demo 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: July 16, 2015 6 | https://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | This example pings a destination server over and over and over. 9 | It'll print the response time (in ms) to the serial monitor. 10 | 11 | Development environment specifics: 12 | IDE: Arduino 1.6.5 13 | Hardware Platform: Arduino Uno 14 | ESP8266 WiFi Shield Version: 1.0 15 | 16 | This code is released under the MIT license. 17 | 18 | Distributed as-is; no warranty is given. 19 | ************************************************************/ 20 | 21 | #include 22 | #include 23 | 24 | // Replace these two character strings with the name and 25 | // password of your WiFi network. 26 | const char mySSID[] = "yourSSIDhere"; 27 | const char myPSK[] = "yourPWDhere"; 28 | 29 | char destServer[] = "sparkfun.com"; 30 | 31 | void setup() 32 | { 33 | Serial.begin(9600); 34 | while (esp8266.begin() != true) 35 | { 36 | Serial.print("Error connecting to ESP8266."); 37 | delay(1000); 38 | } 39 | 40 | if (esp8266.status() <= 0) 41 | { 42 | while (esp8266.connect(mySSID, myPSK) < 0) 43 | delay(1000); 44 | } 45 | delay(1000); 46 | Serial.print("Pinging "); 47 | Serial.println(destServer); 48 | } 49 | 50 | void loop() 51 | { 52 | Serial.println(esp8266.ping(destServer)); 53 | delay(1000); 54 | } -------------------------------------------------------------------------------- /examples/ESP8266_Serial_Passthrough/ESP8266_Serial_Passthrough.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | ESP8266_Serial_Passthrough.h 3 | SparkFun ESP8266 AT library - Serial Passthrough Utility 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: July 16, 2015 6 | https://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | This example sketch is a handy "serial passthrough". Anything 9 | sent to the Arduino serial port will be routed to the ESP8266 10 | software serial port, and vice-versa. 11 | 12 | If you use the Serial Monitor, make sure you SET THE LINE 13 | ENDING PULLDOWN to "Both NL & CR". 14 | 15 | Then try typing commands from the AT command set 16 | (https://cdn.sparkfun.com/assets/learn_tutorials/4/0/3/4A-ESP8266__AT_Instruction_Set__EN_v0.30.pdf) 17 | 18 | For example, to set the mode to STA, connect to a network, 19 | and check your IP address, type: 20 | AT+CWMODE=1 21 | AT+CWJAP="networkName","networkPassword" 22 | AT+CIFSR 23 | 24 | Development environment specifics: 25 | IDE: Arduino 1.6.5 26 | Hardware Platform: Arduino Uno 27 | ESP8266 WiFi Shield Version: 1.0 28 | 29 | This code is released under the MIT license. 30 | 31 | Distributed as-is; no warranty is given. 32 | ************************************************************/ 33 | #include 34 | #include 35 | 36 | void setup() 37 | { 38 | Serial.begin(9600); 39 | esp8266.begin(); 40 | } 41 | 42 | void loop() 43 | { 44 | serialPassthrough(); 45 | } 46 | 47 | void serialPassthrough() 48 | { 49 | while (Serial.available()) 50 | esp8266.write(Serial.read()); 51 | while (esp8266.available()) 52 | Serial.write(esp8266.read()); 53 | } 54 | -------------------------------------------------------------------------------- /examples/ESP8266_Shield_Demo/ESP8266_Shield_Demo.ino: -------------------------------------------------------------------------------- 1 | /************************************************************ 2 | ESP8266_Shield_Demo.h 3 | SparkFun ESP8266 AT library - Demo 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: July 16, 2015 6 | https://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | This example demonstrates the basics of the SparkFun ESP8266 9 | AT library. It'll show you how to connect to a WiFi network, 10 | get an IP address, connect over TCP to a server (as a client), 11 | and set up a TCP server of our own. 12 | 13 | Development environment specifics: 14 | IDE: Arduino 1.6.5 15 | Hardware Platform: Arduino Uno 16 | ESP8266 WiFi Shield Version: 1.0 17 | 18 | This code is released under the MIT license. 19 | 20 | Distributed as-is; no warranty is given. 21 | ************************************************************/ 22 | 23 | ////////////////////// 24 | // Library Includes // 25 | ////////////////////// 26 | // SoftwareSerial is required (even you don't intend on 27 | // using it). 28 | #include 29 | #include 30 | 31 | ////////////////////////////// 32 | // WiFi Network Definitions // 33 | ////////////////////////////// 34 | // Replace these two character strings with the name and 35 | // password of your WiFi network. 36 | const char mySSID[] = "yourSSIDhere"; 37 | const char myPSK[] = "yourPWDhere"; 38 | 39 | ////////////////////////////// 40 | // ESP8266Server definition // 41 | ////////////////////////////// 42 | // server object used towards the end of the demo. 43 | // (This is only global because it's called in both setup() 44 | // and loop()). 45 | ESP8266Server server = ESP8266Server(80); 46 | 47 | ////////////////// 48 | // HTTP Strings // 49 | ////////////////// 50 | const char destServer[] = "example.com"; 51 | const String htmlHeader = "HTTP/1.1 200 OK\r\n" 52 | "Content-Type: text/html\r\n" 53 | "Connection: close\r\n\r\n" 54 | "\r\n" 55 | "\r\n"; 56 | 57 | const String httpRequest = "GET / HTTP/1.1\n" 58 | "Host: example.com\n" 59 | "Connection: close\n\n"; 60 | 61 | // All functions called from setup() are defined below the 62 | // loop() function. They modularized to make it easier to 63 | // copy/paste into sketches of your own. 64 | void setup() 65 | { 66 | // Serial Monitor is used to control the demo and view 67 | // debug information. 68 | Serial.begin(9600); 69 | serialTrigger(F("Press any key to begin.")); 70 | 71 | // initializeESP8266() verifies communication with the WiFi 72 | // shield, and sets it up. 73 | initializeESP8266(); 74 | 75 | // connectESP8266() connects to the defined WiFi network. 76 | connectESP8266(); 77 | 78 | // displayConnectInfo prints the Shield's local IP 79 | // and the network it's connected to. 80 | displayConnectInfo(); 81 | 82 | serialTrigger(F("Press any key to connect client.")); 83 | clientDemo(); 84 | 85 | serialTrigger(F("Press any key to test server.")); 86 | serverSetup(); 87 | } 88 | 89 | void loop() 90 | { 91 | serverDemo(); 92 | } 93 | 94 | void initializeESP8266() 95 | { 96 | // esp8266.begin() verifies that the ESP8266 is operational 97 | // and sets it up for the rest of the sketch. 98 | // It returns either true or false -- indicating whether 99 | // communication was successul or not. 100 | // true 101 | int test = esp8266.begin(); 102 | if (test != true) 103 | { 104 | Serial.println(F("Error talking to ESP8266.")); 105 | errorLoop(test); 106 | } 107 | Serial.println(F("ESP8266 Shield Present")); 108 | } 109 | 110 | void connectESP8266() 111 | { 112 | // The ESP8266 can be set to one of three modes: 113 | // 1 - ESP8266_MODE_STA - Station only 114 | // 2 - ESP8266_MODE_AP - Access point only 115 | // 3 - ESP8266_MODE_STAAP - Station/AP combo 116 | // Use esp8266.getMode() to check which mode it's in: 117 | int retVal = esp8266.getMode(); 118 | if (retVal != ESP8266_MODE_STA) 119 | { // If it's not in station mode. 120 | // Use esp8266.setMode([mode]) to set it to a specified 121 | // mode. 122 | retVal = esp8266.setMode(ESP8266_MODE_STA); 123 | if (retVal < 0) 124 | { 125 | Serial.println(F("Error setting mode.")); 126 | errorLoop(retVal); 127 | } 128 | } 129 | Serial.println(F("Mode set to station")); 130 | 131 | // esp8266.status() indicates the ESP8266's WiFi connect 132 | // status. 133 | // A return value of 1 indicates the device is already 134 | // connected. 0 indicates disconnected. (Negative values 135 | // equate to communication errors.) 136 | retVal = esp8266.status(); 137 | if (retVal <= 0) 138 | { 139 | Serial.print(F("Connecting to ")); 140 | Serial.println(mySSID); 141 | // esp8266.connect([ssid], [psk]) connects the ESP8266 142 | // to a network. 143 | // On success the connect function returns a value >0 144 | // On fail, the function will either return: 145 | // -1: TIMEOUT - The library has a set 30s timeout 146 | // -3: FAIL - Couldn't connect to network. 147 | retVal = esp8266.connect(mySSID, myPSK); 148 | if (retVal < 0) 149 | { 150 | Serial.println(F("Error connecting")); 151 | errorLoop(retVal); 152 | } 153 | } 154 | } 155 | 156 | void displayConnectInfo() 157 | { 158 | char connectedSSID[24]; 159 | memset(connectedSSID, 0, 24); 160 | // esp8266.getAP() can be used to check which AP the 161 | // ESP8266 is connected to. It returns an error code. 162 | // The connected AP is returned by reference as a parameter. 163 | int retVal = esp8266.getAP(connectedSSID); 164 | if (retVal > 0) 165 | { 166 | Serial.print(F("Connected to: ")); 167 | Serial.println(connectedSSID); 168 | } 169 | 170 | // esp8266.localIP returns an IPAddress variable with the 171 | // ESP8266's current local IP address. 172 | IPAddress myIP = esp8266.localIP(); 173 | Serial.print(F("My IP: ")); Serial.println(myIP); 174 | } 175 | 176 | void clientDemo() 177 | { 178 | // To use the ESP8266 as a TCP client, use the 179 | // ESP8266Client class. First, create an object: 180 | ESP8266Client client; 181 | 182 | // ESP8266Client connect([server], [port]) is used to 183 | // connect to a server (const char * or IPAddress) on 184 | // a specified port. 185 | // Returns: 1 on success, 2 on already connected, 186 | // negative on fail (-1=TIMEOUT, -3=FAIL). 187 | int retVal = client.connect(destServer, 80); 188 | if (retVal <= 0) 189 | { 190 | Serial.println(F("Failed to connect to server.")); 191 | return; 192 | } 193 | 194 | // print and write can be used to send data to a connected 195 | // client connection. 196 | client.print(httpRequest); 197 | 198 | // available() will return the number of characters 199 | // currently in the receive buffer. 200 | while (client.available()) 201 | Serial.write(client.read()); // read() gets the FIFO char 202 | 203 | // connected() is a boolean return value - 1 if the 204 | // connection is active, 0 if it's closed. 205 | if (client.connected()) 206 | client.stop(); // stop() closes a TCP connection. 207 | } 208 | 209 | void serverSetup() 210 | { 211 | // begin initializes a ESP8266Server object. It will 212 | // start a server on the port specified in the object's 213 | // constructor (in global area) 214 | server.begin(); 215 | Serial.print(F("Server started! Go to ")); 216 | Serial.println(esp8266.localIP()); 217 | Serial.println(); 218 | } 219 | 220 | void serverDemo() 221 | { 222 | // available() is an ESP8266Server function which will 223 | // return an ESP8266Client object for printing and reading. 224 | // available() has one parameter -- a timeout value. This 225 | // is the number of milliseconds the function waits, 226 | // checking for a connection. 227 | ESP8266Client client = server.available(500); 228 | 229 | if (client) 230 | { 231 | Serial.println(F("Client Connected!")); 232 | // an http request ends with a blank line 233 | boolean currentLineIsBlank = true; 234 | while (client.connected()) 235 | { 236 | if (client.available()) 237 | { 238 | char c = client.read(); 239 | // if you've gotten to the end of the line (received a newline 240 | // character) and the line is blank, the http request has ended, 241 | // so you can send a reply 242 | if (c == '\n' && currentLineIsBlank) 243 | { 244 | Serial.println(F("Sending HTML page")); 245 | // send a standard http response header: 246 | client.print(htmlHeader); 247 | String htmlBody; 248 | // output the value of each analog input pin 249 | for (int a = 0; a < 6; a++) 250 | { 251 | htmlBody += "A"; 252 | htmlBody += String(a); 253 | htmlBody += ": "; 254 | htmlBody += String(analogRead(a)); 255 | htmlBody += "
\n"; 256 | } 257 | htmlBody += "\n"; 258 | client.print(htmlBody); 259 | break; 260 | } 261 | if (c == '\n') 262 | { 263 | // you're starting a new line 264 | currentLineIsBlank = true; 265 | } 266 | else if (c != '\r') 267 | { 268 | // you've gotten a character on the current line 269 | currentLineIsBlank = false; 270 | } 271 | } 272 | } 273 | // give the web browser time to receive the data 274 | delay(1); 275 | 276 | // close the connection: 277 | client.stop(); 278 | Serial.println(F("Client disconnected")); 279 | } 280 | 281 | } 282 | 283 | // errorLoop prints an error code, then loops forever. 284 | void errorLoop(int error) 285 | { 286 | Serial.print(F("Error: ")); Serial.println(error); 287 | Serial.println(F("Looping forever.")); 288 | for (;;) 289 | ; 290 | } 291 | 292 | // serialTrigger prints a message, then waits for something 293 | // to come in from the serial port. 294 | void serialTrigger(String message) 295 | { 296 | Serial.println(); 297 | Serial.println(message); 298 | Serial.println(); 299 | while (!Serial.available()) 300 | ; 301 | while (Serial.available()) 302 | Serial.read(); 303 | } -------------------------------------------------------------------------------- /extras/4A-ESP8266 AT Instrction Set_EN_V0.23b1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library/f52ddca7b6a75eccdebb2851c033485ffe414864/extras/4A-ESP8266 AT Instrction Set_EN_V0.23b1.pdf -------------------------------------------------------------------------------- /extras/4B-ESP8266 AT Command Examples_EN_V0.4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library/f52ddca7b6a75eccdebb2851c033485ffe414864/extras/4B-ESP8266 AT Command Examples_EN_V0.4.pdf -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ################################################################ 2 | # Syntax Coloring Map for SparkFun ESP8266 WiFi Shield Library # 3 | ################################################################ 4 | # Class 5 | ################################################################ 6 | 7 | esp8266 KEYWORD1 8 | ESP8266Class KEYWORD1 9 | ESP8266Client KEYWORD1 10 | ESP8266Server KEYWORD1 11 | 12 | ################################################################ 13 | # Methods and Functions 14 | ################################################################ 15 | 16 | begin KEYWORD2 17 | test KEYWORD2 18 | reset KEYWORD2 19 | getVersion KEYWORD2 20 | echo KEYWORD2 21 | setBaud KEYWORD2 22 | getMode KEYWORD2 23 | setMode KEYWORD2 24 | connect KEYWORD2 25 | getAP KEYWORD2 26 | disconnect KEYWORD2 27 | localIP KEYWORD2 28 | status KEYWORD2 29 | updateStatus KEYWORD2 30 | tcpConnect KEYWORD2 31 | tcpSend KEYWORD2 32 | close KEYWORD2 33 | setTransferMode KEYWORD2 34 | setMux KEYWORD2 35 | configureTCPServer KEYWORD2 36 | ping KEYWORD2 37 | 38 | ################################################################ 39 | # Constants 40 | ################################################################ 41 | 42 | USE_SOFTWARE_SERIAL LITERAL1 43 | ESP8266_SW_RX LITERAL1 44 | ESP8266_SW_TX LITERAL1 45 | ESP8266_CMD_BAD LITERAL1 46 | ESP8266_RSP_MEMORY_ERR LITERAL1 47 | ESP8266_RSP_FAIL LITERAL1 48 | ESP8266_RSP_UNKNOWN LITERAL1 49 | ESP8266_RSP_TIMEOUT LITERAL1 50 | ESP8266_RSP_SUCCESS LITERAL1 51 | ESP8266_MODE_STA LITERAL1 52 | ESP8266_MODE_AP LITERAL1 53 | ESP8266_MODE_STAAP LITERAL1 54 | ESP8266_ECN_OPEN LITERAL1 55 | ESP8266_ECN_WPA_PSK LITERAL1 56 | ESP8266_ECN_WPA2_PSK LITERAL1 57 | ESP8266_ECN_WPA_WPA2_PSK LITERAL1 58 | ESP8266_STATUS_GOTIP LITERAL1 59 | ESP8266_STATUS_CONNECTED LITERAL1 60 | ESP8266_STATUS_DISCONNECTED LITERAL1 61 | ESP8266_STATUS_NOWIFI LITERAL1 62 | ESP8266_SOFTWARE_SERIAL LITERAL1 63 | ESP8266_HARDWARE_SERIAL LITERAL1 64 | ESP8266_TCP LITERAL1 65 | ESP8266_UDP LITERAL1 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=SparkFun ESP8266 AT Library 2 | version=1.0.0 3 | author=SparkFun Electronics 4 | maintainer=Jim Lindblom 5 | sentence=Driver library for SparkFun's ESP8266 WiFi Shield. 6 | paragraph=Simple API to connect to WiFi, TCP, and other functions made available by the MG2639 Cellular Shield. 7 | category=Communication 8 | url=http://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 9 | architectures=* 10 | -------------------------------------------------------------------------------- /src/SparkFunESP8266Client.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | SparkFunESP8266Client.cpp 3 | ESP8266 WiFi Shield Library Client Source File 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: June 20, 2015 6 | http://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | !!! Description Here !!! 9 | 10 | Development environment specifics: 11 | IDE: Arduino 1.6.5 12 | Hardware Platform: Arduino Uno 13 | ESP8266 WiFi Shield Version: 1.0 14 | 15 | This code is beerware; if you see me (or any other SparkFun employee) at the 16 | local, and you've found our code helpful, please buy us a round! 17 | 18 | Distributed as-is; no warranty is given. 19 | ******************************************************************************/ 20 | 21 | #include "SparkFunESP8266WiFi.h" 22 | #include 23 | #include "util/ESP8266_AT.h" 24 | #include "SparkFunESP8266Client.h" 25 | 26 | ESP8266Client::ESP8266Client() 27 | { 28 | } 29 | 30 | ESP8266Client::ESP8266Client(uint8_t sock) 31 | { 32 | _socket = sock; 33 | } 34 | 35 | uint8_t ESP8266Client::status() 36 | { 37 | return esp8266.status(); 38 | } 39 | 40 | int ESP8266Client::connect(IPAddress ip, uint16_t port) 41 | { 42 | return connect(ip, port, 0); 43 | } 44 | 45 | int ESP8266Client::connect(const char *host, uint16_t port) 46 | { 47 | return connect(host, port, 0); 48 | } 49 | 50 | int ESP8266Client::connect(String host, uint16_t port, uint32_t keepAlive) 51 | { 52 | return connect(host.c_str(), port, keepAlive); 53 | } 54 | 55 | int ESP8266Client::connect(IPAddress ip, uint16_t port, uint32_t keepAlive) 56 | { 57 | char ipAddress[16]; 58 | sprintf(ipAddress, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); 59 | 60 | return connect((const char *)ipAddress, port, keepAlive); 61 | } 62 | 63 | int ESP8266Client::connect(const char* host, uint16_t port, uint32_t keepAlive) 64 | { 65 | _socket = getFirstSocket(); 66 | 67 | if (_socket != ESP8266_SOCK_NOT_AVAIL) 68 | { 69 | esp8266._state[_socket] = TAKEN; 70 | int16_t rsp = esp8266.tcpConnect(_socket, host, port, keepAlive); 71 | 72 | return rsp; 73 | } 74 | } 75 | 76 | size_t ESP8266Client::write(uint8_t c) 77 | { 78 | return write(&c, 1); 79 | } 80 | 81 | size_t ESP8266Client::write(const uint8_t *buf, size_t size) 82 | { 83 | return esp8266.tcpSend(_socket, buf, size); 84 | } 85 | 86 | int ESP8266Client::available() 87 | { 88 | int available = esp8266.available(); 89 | if (available == 0) 90 | { 91 | // Delay for the amount of time it'd take to receive one character 92 | delayMicroseconds((1 / esp8266._baud) * 10 * 1E6); 93 | // Check again just to be sure: 94 | available = esp8266.available(); 95 | } 96 | return esp8266.available(); 97 | } 98 | 99 | int ESP8266Client::read() 100 | { 101 | return esp8266.read(); 102 | } 103 | 104 | int ESP8266Client::read(uint8_t *buf, size_t size) 105 | { 106 | if (esp8266.available() < size) 107 | return 0; 108 | 109 | for (int i=0; i 0) 141 | return 1; 142 | else if (status() == ESP8266_STATUS_CONNECTED) 143 | return 1; 144 | 145 | return 0; 146 | } 147 | 148 | ESP8266Client::operator bool() 149 | { 150 | return connected(); 151 | } 152 | 153 | // Private Methods 154 | uint8_t ESP8266Client::getFirstSocket() 155 | { 156 | /* 157 | for (int i = 0; i < ESP8266_MAX_SOCK_NUM; i++) 158 | { 159 | if (esp8266._state[i] == AVAILABLE) 160 | { 161 | return i; 162 | } 163 | } 164 | return ESP8266_SOCK_NOT_AVAIL; 165 | */ 166 | esp8266.updateStatus(); 167 | for (int i = 0; i < ESP8266_MAX_SOCK_NUM; i++) 168 | { 169 | if (esp8266._status.ipstatus[i].linkID == 255) 170 | { 171 | return i; 172 | } 173 | } 174 | return ESP8266_SOCK_NOT_AVAIL; 175 | } 176 | -------------------------------------------------------------------------------- /src/SparkFunESP8266Client.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | SparkFunESP8266Client.h 3 | ESP8266 WiFi Shield Library Client Header File 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: June 20, 2015 6 | http://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | !!! Description Here !!! 9 | 10 | Development environment specifics: 11 | IDE: Arduino 1.6.5 12 | Hardware Platform: Arduino Uno 13 | ESP8266 WiFi Shield Version: 1.0 14 | 15 | This code is beerware; if you see me (or any other SparkFun employee) at the 16 | local, and you've found our code helpful, please buy us a round! 17 | 18 | Distributed as-is; no warranty is given. 19 | ******************************************************************************/ 20 | 21 | #ifndef _SPARKFUNESP8266CLIENT_H_ 22 | #define _SPARKFUNESP8266CLIENT_H_ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "Client.h" 28 | #include "SparkFunESP8266WiFi.h" 29 | 30 | class ESP8266Client : public Client { 31 | 32 | public: 33 | ESP8266Client(); 34 | ESP8266Client(uint8_t sock); 35 | 36 | uint8_t status(); 37 | 38 | virtual int connect(IPAddress ip, uint16_t port); 39 | virtual int connect(const char *host, uint16_t port); 40 | 41 | int connect(IPAddress ip, uint16_t port, uint32_t keepAlive); 42 | int connect(String host, uint16_t port, uint32_t keepAlive = 0); 43 | int connect(const char *host, uint16_t port, uint32_t keepAlive); 44 | 45 | virtual size_t write(uint8_t); 46 | virtual size_t write(const uint8_t *buf, size_t size); 47 | virtual int available(); 48 | virtual int read(); 49 | virtual int read(uint8_t *buf, size_t size); 50 | virtual int peek(); 51 | virtual void flush(); 52 | virtual void stop(); 53 | virtual uint8_t connected(); 54 | virtual operator bool(); 55 | 56 | friend class WiFiServer; 57 | 58 | using Print::write; 59 | 60 | private: 61 | static uint16_t _srcport; 62 | uint16_t _socket; 63 | bool ipMuxEn; 64 | 65 | 66 | uint8_t getFirstSocket(); 67 | }; 68 | 69 | #endif -------------------------------------------------------------------------------- /src/SparkFunESP8266Server.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | SparkFunESP8266Client.cpp 3 | ESP8266 WiFi Shield Library Client Source File 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: June 20, 2015 6 | http://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | !!! Description Here !!! 9 | 10 | Development environment specifics: 11 | IDE: Arduino 1.6.5 12 | Hardware Platform: Arduino Uno 13 | ESP8266 WiFi Shield Version: 1.0 14 | 15 | This code is beerware; if you see me (or any other SparkFun employee) at the 16 | local, and you've found our code helpful, please buy us a round! 17 | 18 | Distributed as-is; no warranty is given. 19 | ******************************************************************************/ 20 | 21 | #include "SparkFunESP8266WiFi.h" 22 | #include 23 | #include "util/ESP8266_AT.h" 24 | #include "SparkFunESP8266Server.h" 25 | 26 | ESP8266Server::ESP8266Server(uint16_t port) 27 | { 28 | _port = port; 29 | } 30 | 31 | void ESP8266Server::begin() 32 | { 33 | esp8266.configureTCPServer(_port, 1); 34 | } 35 | 36 | ESP8266Client ESP8266Server::available(uint8_t wait) 37 | { 38 | if (esp8266.readForResponse(",CONNECT", wait) > 0) 39 | { 40 | char * p = esp8266.searchBuffer(",CONNECT"); 41 | p -= 1; 42 | //p -= 1; // Move p back one character 43 | uint8_t sock = *p - 48; 44 | ESP8266Client client(sock); 45 | return client; 46 | } 47 | if (esp8266.updateStatus()) 48 | { 49 | for (int sock=0; sock 25 | #include 26 | #include 27 | #include "Server.h" 28 | #include "SparkFunESP8266WiFi.h" 29 | #include "SparkFunESP8266Client.h" 30 | 31 | class ESP8266Server : public Server 32 | { 33 | public: 34 | ESP8266Server(uint16_t); 35 | ESP8266Client available(uint8_t wait = 0); 36 | void begin(); 37 | virtual size_t write(uint8_t); 38 | virtual size_t write(const uint8_t *buf, size_t size); 39 | uint8_t status(); 40 | 41 | using Print::write; 42 | 43 | private: 44 | uint16_t _port; 45 | }; 46 | 47 | #endif -------------------------------------------------------------------------------- /src/SparkFunESP8266WiFi.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | SparkFunESP8266WiFi.cpp 3 | ESP8266 WiFi Shield Library Main Source File 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: June 20, 2015 6 | http://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | !!! Description Here !!! 9 | 10 | Development environment specifics: 11 | IDE: Arduino 1.6.5 12 | Hardware Platform: Arduino Uno 13 | ESP8266 WiFi Shield Version: 1.0 14 | 15 | This code is beerware; if you see me (or any other SparkFun employee) at the 16 | local, and you've found our code helpful, please buy us a round! 17 | 18 | Distributed as-is; no warranty is given. 19 | ******************************************************************************/ 20 | 21 | #include 22 | #include 23 | #include "util/ESP8266_AT.h" 24 | #include "SparkFunESP8266Client.h" 25 | 26 | #define ESP8266_DISABLE_ECHO 27 | 28 | //////////////////////// 29 | // Buffer Definitions // 30 | //////////////////////// 31 | #define ESP8266_RX_BUFFER_LEN 128 // Number of bytes in the serial receive buffer 32 | char esp8266RxBuffer[ESP8266_RX_BUFFER_LEN]; 33 | unsigned int bufferHead; // Holds position of latest byte placed in buffer. 34 | 35 | //////////////////// 36 | // Initialization // 37 | //////////////////// 38 | 39 | ESP8266Class::ESP8266Class() 40 | { 41 | for (int i=0; i 0) 84 | return true; 85 | 86 | return false; 87 | } 88 | 89 | bool ESP8266Class::reset() 90 | { 91 | sendCommand(ESP8266_RESET); // Send AT+RST 92 | 93 | if (readForResponse(RESPONSE_READY, COMMAND_RESET_TIMEOUT) > 0) 94 | return true; 95 | 96 | return false; 97 | } 98 | 99 | bool ESP8266Class::echo(bool enable) 100 | { 101 | if (enable) 102 | sendCommand(ESP8266_ECHO_ENABLE); 103 | else 104 | sendCommand(ESP8266_ECHO_DISABLE); 105 | 106 | if (readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT) > 0) 107 | return true; 108 | 109 | return false; 110 | } 111 | 112 | bool ESP8266Class::setBaud(unsigned long baud) 113 | { 114 | char parameters[16]; 115 | memset(parameters, 0, 16); 116 | // Constrain parameters: 117 | baud = constrain(baud, 110, 115200); 118 | 119 | // Put parameters into string 120 | sprintf(parameters, "%d,8,1,0,0", baud); 121 | 122 | // Send AT+UART=baud,databits,stopbits,parity,flowcontrol 123 | sendCommand(ESP8266_UART, ESP8266_CMD_SETUP, parameters); 124 | 125 | if (readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT) > 0) 126 | return true; 127 | 128 | return false; 129 | } 130 | 131 | int16_t ESP8266Class::getVersion(char * ATversion, char * SDKversion, char * compileTime) 132 | { 133 | sendCommand(ESP8266_VERSION); // Send AT+GMR 134 | // Example Response: AT version:0.30.0.0(Jul 3 2015 19:35:49)\r\n (43 chars) 135 | // SDK version:1.2.0\r\n (19 chars) 136 | // compile time:Jul 7 2015 18:34:26\r\n (36 chars) 137 | // OK\r\n 138 | // (~101 characters) 139 | // Look for "OK": 140 | int16_t rsp = (readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT) > 0); 141 | if (rsp > 0) 142 | { 143 | char *p, *q; 144 | // Look for "AT version" in the rxBuffer 145 | p = strstr(esp8266RxBuffer, "AT version:"); 146 | if (p == NULL) return ESP8266_RSP_UNKNOWN; 147 | p += strlen("AT version:"); 148 | q = strchr(p, '\r'); // Look for \r 149 | if (q == NULL) return ESP8266_RSP_UNKNOWN; 150 | strncpy(ATversion, p, q-p); 151 | 152 | // Look for "SDK version:" in the rxBuffer 153 | p = strstr(esp8266RxBuffer, "SDK version:"); 154 | if (p == NULL) return ESP8266_RSP_UNKNOWN; 155 | p += strlen("SDK version:"); 156 | q = strchr(p, '\r'); // Look for \r 157 | if (q == NULL) return ESP8266_RSP_UNKNOWN; 158 | strncpy(SDKversion, p, q-p); 159 | 160 | // Look for "compile time:" in the rxBuffer 161 | p = strstr(esp8266RxBuffer, "compile time:"); 162 | if (p == NULL) return ESP8266_RSP_UNKNOWN; 163 | p += strlen("compile time:"); 164 | q = strchr(p, '\r'); // Look for \r 165 | if (q == NULL) return ESP8266_RSP_UNKNOWN; 166 | strncpy(compileTime, p, q-p); 167 | } 168 | 169 | return rsp; 170 | } 171 | 172 | //////////////////// 173 | // WiFi Functions // 174 | //////////////////// 175 | 176 | // getMode() 177 | // Input: None 178 | // Output: 179 | // - Success: 1, 2, 3 (ESP8266_MODE_STA, ESP8266_MODE_AP, ESP8266_MODE_STAAP) 180 | // - Fail: <0 (esp8266_cmd_rsp) 181 | int16_t ESP8266Class::getMode() 182 | { 183 | sendCommand(ESP8266_WIFI_MODE, ESP8266_CMD_QUERY); 184 | 185 | // Example response: \r\nAT+CWMODE_CUR?\r+CWMODE_CUR:2\r\n\r\nOK\r\n 186 | // Look for the OK: 187 | int16_t rsp = readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 188 | if (rsp > 0) 189 | { 190 | // Then get the number after ':': 191 | char * p = strchr(esp8266RxBuffer, ':'); 192 | if (p != NULL) 193 | { 194 | char mode = *(p+1); 195 | if ((mode >= '1') && (mode <= '3')) 196 | return (mode - 48); // Convert ASCII to decimal 197 | } 198 | 199 | return ESP8266_RSP_UNKNOWN; 200 | } 201 | 202 | return rsp; 203 | } 204 | 205 | // setMode() 206 | // Input: 1, 2, 3 (ESP8266_MODE_STA, ESP8266_MODE_AP, ESP8266_MODE_STAAP) 207 | // Output: 208 | // - Success: >0 209 | // - Fail: <0 (esp8266_cmd_rsp) 210 | int16_t ESP8266Class::setMode(esp8266_wifi_mode mode) 211 | { 212 | char modeChar[2] = {0, 0}; 213 | sprintf(modeChar, "%d", mode); 214 | sendCommand(ESP8266_WIFI_MODE, ESP8266_CMD_SETUP, modeChar); 215 | 216 | return readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 217 | } 218 | 219 | int16_t ESP8266Class::connect(const char * ssid) 220 | { 221 | connect(ssid, ""); 222 | } 223 | 224 | // connect() 225 | // Input: ssid and pwd const char's 226 | // Output: 227 | // - Success: >0 228 | // - Fail: <0 (esp8266_cmd_rsp) 229 | int16_t ESP8266Class::connect(const char * ssid, const char * pwd) 230 | { 231 | _serial->print("AT"); 232 | _serial->print(ESP8266_CONNECT_AP); 233 | _serial->print("=\""); 234 | _serial->print(ssid); 235 | _serial->print("\""); 236 | if (pwd != NULL) 237 | { 238 | _serial->print(','); 239 | _serial->print("\""); 240 | _serial->print(pwd); 241 | _serial->print("\""); 242 | } 243 | _serial->print("\r\n"); 244 | 245 | return readForResponses(RESPONSE_OK, RESPONSE_FAIL, WIFI_CONNECT_TIMEOUT); 246 | } 247 | 248 | int16_t ESP8266Class::getAP(char * ssid) 249 | { 250 | sendCommand(ESP8266_CONNECT_AP, ESP8266_CMD_QUERY); // Send "AT+CWJAP?" 251 | 252 | int16_t rsp = readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 253 | // Example Responses: No AP\r\n\r\nOK\r\n 254 | // - or - 255 | // +CWJAP:"WiFiSSID","00:aa:bb:cc:dd:ee",6,-45\r\n\r\nOK\r\n 256 | if (rsp > 0) 257 | { 258 | // Look for "No AP" 259 | if (strstr(esp8266RxBuffer, "No AP") != NULL) 260 | return 0; 261 | 262 | // Look for "+CWJAP" 263 | char * p = strstr(esp8266RxBuffer, ESP8266_CONNECT_AP); 264 | if (p != NULL) 265 | { 266 | p += strlen(ESP8266_CONNECT_AP) + 2; 267 | char * q = strchr(p, '"'); 268 | if (q == NULL) return ESP8266_RSP_UNKNOWN; 269 | strncpy(ssid, p, q-p); // Copy string to temp char array: 270 | return 1; 271 | } 272 | } 273 | 274 | return rsp; 275 | } 276 | 277 | int16_t ESP8266Class::disconnect() 278 | { 279 | sendCommand(ESP8266_DISCONNECT); // Send AT+CWQAP 280 | // Example response: \r\n\r\nOK\r\nWIFI DISCONNECT\r\n 281 | // "WIFI DISCONNECT" comes up to 500ms _after_ OK. 282 | int16_t rsp = readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 283 | if (rsp > 0) 284 | { 285 | rsp = readForResponse("WIFI DISCONNECT", COMMAND_RESPONSE_TIMEOUT); 286 | if (rsp > 0) 287 | return rsp; 288 | return 1; 289 | } 290 | 291 | return rsp; 292 | } 293 | 294 | // status() 295 | // Input: none 296 | // Output: 297 | // - Success: 2, 3, 4, or 5 (ESP8266_STATUS_GOTIP, ESP8266_STATUS_CONNECTED, ESP8266_STATUS_DISCONNECTED, ESP8266_STATUS_NOWIFI) 298 | // - Fail: <0 (esp8266_cmd_rsp) 299 | int16_t ESP8266Class::status() 300 | { 301 | int16_t statusRet = updateStatus(); 302 | if (statusRet > 0) 303 | { 304 | switch (_status.stat) 305 | { 306 | case ESP8266_STATUS_GOTIP: // 3 307 | case ESP8266_STATUS_DISCONNECTED: // 4 - "Client" disconnected, not wifi 308 | return 1; 309 | break; 310 | case ESP8266_STATUS_CONNECTED: // Connected, but haven't gotten an IP 311 | case ESP8266_STATUS_NOWIFI: // No WiFi configured 312 | return 0; 313 | break; 314 | } 315 | } 316 | return statusRet; 317 | } 318 | 319 | int16_t ESP8266Class::updateStatus() 320 | { 321 | sendCommand(ESP8266_TCP_STATUS); // Send AT+CIPSTATUS\r\n 322 | // Example response: (connected as client) 323 | // STATUS:3\r\n 324 | // +CIPSTATUS:0,"TCP","93.184.216.34",80,0\r\n\r\nOK\r\n 325 | // - or - (clients connected to ESP8266 server) 326 | // STATUS:3\r\n 327 | // +CIPSTATUS:0,"TCP","192.168.0.100",54723,1\r\n 328 | // +CIPSTATUS:1,"TCP","192.168.0.101",54724,1\r\n\r\nOK\r\n 329 | int16_t rsp = readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 330 | if (rsp > 0) 331 | { 332 | char * p = searchBuffer("STATUS:"); 333 | if (p == NULL) 334 | return ESP8266_RSP_UNKNOWN; 335 | 336 | p += strlen("STATUS:"); 337 | _status.stat = (esp8266_connect_status)(*p - 48); 338 | 339 | for (int i=0; i= ESP8266_MAX_SOCK_NUM) 355 | return rsp; 356 | _status.ipstatus[linkId].linkID = linkId; 357 | 358 | // Find type (p pointing at linkID): 359 | p += 3; // Move p to either "T" or "U" 360 | if (*p == 'T') 361 | _status.ipstatus[linkId].type = ESP8266_TCP; 362 | else if (*p == 'U') 363 | _status.ipstatus[linkId].type = ESP8266_UDP; 364 | else 365 | _status.ipstatus[linkId].type = ESP8266_TYPE_UNDEFINED; 366 | 367 | // Find remoteIP (p pointing at first letter or type): 368 | p += 6; // Move p to first digit of first octet. 369 | for (uint8_t j = 0; j < 4; j++) 370 | { 371 | char tempOctet[4]; 372 | memset(tempOctet, 0, 4); // Clear tempOctet 373 | 374 | size_t octetLength = strspn(p, "0123456789"); // Find length of numerical string: 375 | 376 | strncpy(tempOctet, p, octetLength); // Copy string to temp char array: 377 | _status.ipstatus[linkId].remoteIP[j] = atoi(tempOctet); // Move the temp char into IP Address octet 378 | 379 | p += (octetLength + 1); // Increment p to next octet 380 | } 381 | 382 | // Find port (p pointing at ',' between IP and port: 383 | p += 1; // Move p to first digit of port 384 | char tempPort[6]; 385 | memset(tempPort, 0, 6); 386 | size_t portLen = strspn(p, "0123456789"); // Find length of numerical string: 387 | strncpy(tempPort, p, portLen); 388 | _status.ipstatus[linkId].port = atoi(tempPort); 389 | p += portLen + 1; 390 | 391 | // Find tetype (p pointing at tetype) 392 | if (*p == '0') 393 | _status.ipstatus[linkId].tetype = ESP8266_CLIENT; 394 | else if (*p == '1') 395 | _status.ipstatus[linkId].tetype = ESP8266_SERVER; 396 | } 397 | } 398 | } 399 | 400 | return rsp; 401 | } 402 | 403 | // localIP() 404 | // Input: none 405 | // Output: 406 | // - Success: Device's local IPAddress 407 | // - Fail: 0 408 | IPAddress ESP8266Class::localIP() 409 | { 410 | sendCommand(ESP8266_GET_LOCAL_IP); // Send AT+CIFSR\r\n 411 | // Example Response: +CIFSR:STAIP,"192.168.0.114"\r\n 412 | // +CIFSR:STAMAC,"18:fe:34:9d:b7:d9"\r\n 413 | // \r\n 414 | // OK\r\n 415 | // Look for the OK: 416 | int16_t rsp = readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 417 | if (rsp > 0) 418 | { 419 | // Look for "STAIP" in the rxBuffer 420 | char * p = strstr(esp8266RxBuffer, "STAIP"); 421 | if (p != NULL) 422 | { 423 | IPAddress returnIP; 424 | 425 | p += 7; // Move p seven places. (skip STAIP,") 426 | for (uint8_t i = 0; i < 4; i++) 427 | { 428 | char tempOctet[4]; 429 | memset(tempOctet, 0, 4); // Clear tempOctet 430 | 431 | size_t octetLength = strspn(p, "0123456789"); // Find length of numerical string: 432 | if (octetLength >= 4) // If it's too big, return an error 433 | return ESP8266_RSP_UNKNOWN; 434 | 435 | strncpy(tempOctet, p, octetLength); // Copy string to temp char array: 436 | returnIP[i] = atoi(tempOctet); // Move the temp char into IP Address octet 437 | 438 | p += (octetLength + 1); // Increment p to next octet 439 | } 440 | 441 | return returnIP; 442 | } 443 | } 444 | 445 | return rsp; 446 | } 447 | 448 | int16_t ESP8266Class::localMAC(char * mac) 449 | { 450 | sendCommand(ESP8266_GET_STA_MAC, ESP8266_CMD_QUERY); // Send "AT+CIPSTAMAC?" 451 | 452 | int16_t rsp = readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 453 | 454 | if (rsp > 0) 455 | { 456 | // Look for "+CIPSTAMAC" 457 | char * p = strstr(esp8266RxBuffer, ESP8266_GET_STA_MAC); 458 | if (p != NULL) 459 | { 460 | p += strlen(ESP8266_GET_STA_MAC) + 2; 461 | char * q = strchr(p, '"'); 462 | if (q == NULL) return ESP8266_RSP_UNKNOWN; 463 | strncpy(mac, p, q - p); // Copy string to temp char array: 464 | return 1; 465 | } 466 | } 467 | 468 | return rsp; 469 | } 470 | 471 | ///////////////////// 472 | // TCP/IP Commands // 473 | ///////////////////// 474 | 475 | int16_t ESP8266Class::tcpConnect(uint8_t linkID, const char * destination, uint16_t port, uint16_t keepAlive) 476 | { 477 | print("AT"); 478 | print(ESP8266_TCP_CONNECT); 479 | print('='); 480 | print(linkID); 481 | print(','); 482 | print("\"TCP\","); 483 | print("\""); 484 | print(destination); 485 | print("\","); 486 | print(port); 487 | if (keepAlive > 0) 488 | { 489 | print(','); 490 | // keepAlive is in units of 500 milliseconds. 491 | // Max is 7200 * 500 = 3600000 ms = 60 minutes. 492 | print(keepAlive / 500); 493 | } 494 | print("\r\n"); 495 | // Example good: CONNECT\r\n\r\nOK\r\n 496 | // Example bad: DNS Fail\r\n\r\nERROR\r\n 497 | // Example meh: ALREADY CONNECTED\r\n\r\nERROR\r\n 498 | int16_t rsp = readForResponses(RESPONSE_OK, RESPONSE_ERROR, CLIENT_CONNECT_TIMEOUT); 499 | 500 | if (rsp < 0) 501 | { 502 | // We may see "ERROR", but be "ALREADY CONNECTED". 503 | // Search for "ALREADY", and return success if we see it. 504 | char * p = searchBuffer("ALREADY"); 505 | if (p != NULL) 506 | return 2; 507 | // Otherwise the connection failed. Return the error code: 508 | return rsp; 509 | } 510 | // Return 1 on successful (new) connection 511 | return 1; 512 | } 513 | 514 | int16_t ESP8266Class::tcpSend(uint8_t linkID, const uint8_t *buf, size_t size) 515 | { 516 | if (size > 2048) 517 | return ESP8266_CMD_BAD; 518 | char params[8]; 519 | sprintf(params, "%d,%d", linkID, size); 520 | sendCommand(ESP8266_TCP_SEND, ESP8266_CMD_SETUP, params); 521 | 522 | int16_t rsp = readForResponses(RESPONSE_OK, RESPONSE_ERROR, COMMAND_RESPONSE_TIMEOUT); 523 | //if (rsp > 0) 524 | if (rsp != ESP8266_RSP_FAIL) 525 | { 526 | print((const char *)buf); 527 | 528 | rsp = readForResponse("SEND OK", COMMAND_RESPONSE_TIMEOUT); 529 | 530 | if (rsp > 0) 531 | return size; 532 | } 533 | 534 | return rsp; 535 | } 536 | 537 | int16_t ESP8266Class::close(uint8_t linkID) 538 | { 539 | char params[2]; 540 | sprintf(params, "%d", linkID); 541 | sendCommand(ESP8266_TCP_CLOSE, ESP8266_CMD_SETUP, params); 542 | 543 | // Eh, client virtual function doesn't have a return value. 544 | // We'll wait for the OK or timeout anyway. 545 | return readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 546 | } 547 | 548 | int16_t ESP8266Class::setTransferMode(uint8_t mode) 549 | { 550 | char params[2] = {0, 0}; 551 | params[0] = (mode > 0) ? '1' : '0'; 552 | sendCommand(ESP8266_TRANSMISSION_MODE, ESP8266_CMD_SETUP, params); 553 | 554 | return readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 555 | } 556 | 557 | int16_t ESP8266Class::setMux(uint8_t mux) 558 | { 559 | char params[2] = {0, 0}; 560 | params[0] = (mux > 0) ? '1' : '0'; 561 | sendCommand(ESP8266_TCP_MULTIPLE, ESP8266_CMD_SETUP, params); 562 | 563 | return readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 564 | } 565 | 566 | int16_t ESP8266Class::configureTCPServer(uint16_t port, uint8_t create) 567 | { 568 | char params[10]; 569 | if (create > 1) create = 1; 570 | sprintf(params, "%d,%d", create, port); 571 | sendCommand(ESP8266_SERVER_CONFIG, ESP8266_CMD_SETUP, params); 572 | 573 | return readForResponse(RESPONSE_OK, COMMAND_RESPONSE_TIMEOUT); 574 | } 575 | 576 | int16_t ESP8266Class::ping(IPAddress ip) 577 | { 578 | char ipStr[17]; 579 | sprintf(ipStr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); 580 | return ping(ipStr); 581 | } 582 | 583 | int16_t ESP8266Class::ping(char * server) 584 | { 585 | char params[strlen(server) + 3]; 586 | sprintf(params, "\"%s\"", server); 587 | // Send AT+Ping= 588 | sendCommand(ESP8266_PING, ESP8266_CMD_SETUP, params); 589 | // Example responses: 590 | // * Good response: +12\r\n\r\nOK\r\n 591 | // * Timeout response: +timeout\r\n\r\nERROR\r\n 592 | // * Error response (unreachable): ERROR\r\n\r\n 593 | int16_t rsp = readForResponses(RESPONSE_OK, RESPONSE_ERROR, COMMAND_PING_TIMEOUT); 594 | if (rsp > 0) 595 | { 596 | char * p = searchBuffer("+"); 597 | p += 1; // Move p forward 1 space 598 | char * q = strchr(p, '\r'); // Find the first \r 599 | if (q == NULL) 600 | return ESP8266_RSP_UNKNOWN; 601 | char tempRsp[10]; 602 | strncpy(tempRsp, p, q - p); 603 | return atoi(tempRsp); 604 | } 605 | else 606 | { 607 | if (searchBuffer("timeout") != NULL) 608 | return 0; 609 | } 610 | 611 | return rsp; 612 | } 613 | 614 | ////////////////////////// 615 | // Custom GPIO Commands // 616 | ////////////////////////// 617 | int16_t ESP8266Class::pinMode(uint8_t pin, uint8_t mode) 618 | { 619 | char params[5]; 620 | 621 | char modeC = 'i'; // Default mode to input 622 | if (mode == OUTPUT) 623 | modeC = 'o'; // o = OUTPUT 624 | else if (mode == INPUT_PULLUP) 625 | modeC = 'p'; // p = INPUT_PULLUP 626 | 627 | sprintf(params, "%d,%c", pin, modeC); 628 | sendCommand(ESP8266_PINMODE, ESP8266_CMD_SETUP, params); 629 | 630 | return readForResponses(RESPONSE_OK, RESPONSE_ERROR, COMMAND_RESPONSE_TIMEOUT); 631 | } 632 | 633 | int16_t ESP8266Class::digitalWrite(uint8_t pin, uint8_t state) 634 | { 635 | char params[5]; 636 | 637 | char stateC = 'l'; // Default state to LOW 638 | if (state == HIGH) 639 | stateC = 'h'; // h = HIGH 640 | 641 | sprintf(params, "%d,%c", pin, stateC); 642 | sendCommand(ESP8266_PINWRITE, ESP8266_CMD_SETUP, params); 643 | 644 | return readForResponses(RESPONSE_OK, RESPONSE_ERROR, COMMAND_RESPONSE_TIMEOUT); 645 | } 646 | 647 | int8_t ESP8266Class::digitalRead(uint8_t pin) 648 | { 649 | char params[3]; 650 | 651 | sprintf(params, "%d", pin); 652 | sendCommand(ESP8266_PINREAD, ESP8266_CMD_SETUP, params); // Send AT+PINREAD=n\r\n 653 | // Example response: 1\r\n\r\nOK\r\n 654 | if (readForResponses(RESPONSE_OK, RESPONSE_ERROR, COMMAND_RESPONSE_TIMEOUT) > 0) 655 | { 656 | if (strchr(esp8266RxBuffer, '0') != NULL) 657 | return LOW; 658 | else if (strchr(esp8266RxBuffer, '1') != NULL) 659 | return HIGH; 660 | } 661 | 662 | return -1; 663 | } 664 | 665 | ////////////////////////////// 666 | // Stream Virtual Functions // 667 | ////////////////////////////// 668 | 669 | size_t ESP8266Class::write(uint8_t c) 670 | { 671 | _serial->write(c); 672 | } 673 | 674 | int ESP8266Class::available() 675 | { 676 | return _serial->available(); 677 | } 678 | 679 | int ESP8266Class::read() 680 | { 681 | return _serial->read(); 682 | } 683 | 684 | int ESP8266Class::peek() 685 | { 686 | return _serial->peek(); 687 | } 688 | 689 | void ESP8266Class::flush() 690 | { 691 | _serial->flush(); 692 | } 693 | 694 | ////////////////////////////////////////////////// 695 | // Private, Low-Level, Ugly, Hardware Functions // 696 | ////////////////////////////////////////////////// 697 | 698 | void ESP8266Class::sendCommand(const char * cmd, enum esp8266_command_type type, const char * params) 699 | { 700 | _serial->print("AT"); 701 | _serial->print(cmd); 702 | if (type == ESP8266_CMD_QUERY) 703 | _serial->print('?'); 704 | else if (type == ESP8266_CMD_SETUP) 705 | { 706 | _serial->print("="); 707 | _serial->print(params); 708 | } 709 | _serial->print("\r\n"); 710 | } 711 | 712 | int16_t ESP8266Class::readForResponse(const char * rsp, unsigned int timeout) 713 | { 714 | unsigned long timeIn = millis(); // Timestamp coming into function 715 | unsigned int received = 0; // received keeps track of number of chars read 716 | 717 | clearBuffer(); // Clear the class receive buffer (esp8266RxBuffer) 718 | while (timeIn + timeout > millis()) // While we haven't timed out 719 | { 720 | if (_serial->available()) // If data is available on UART RX 721 | { 722 | received += readByteToBuffer(); 723 | if (searchBuffer(rsp)) // Search the buffer for goodRsp 724 | return received; // Return how number of chars read 725 | } 726 | } 727 | 728 | if (received > 0) // If we received any characters 729 | return ESP8266_RSP_UNKNOWN; // Return unkown response error code 730 | else // If we haven't received any characters 731 | return ESP8266_RSP_TIMEOUT; // Return the timeout error code 732 | } 733 | 734 | int16_t ESP8266Class::readForResponses(const char * pass, const char * fail, unsigned int timeout) 735 | { 736 | unsigned long timeIn = millis(); // Timestamp coming into function 737 | unsigned int received = 0; // received keeps track of number of chars read 738 | 739 | clearBuffer(); // Clear the class receive buffer (esp8266RxBuffer) 740 | while (timeIn + timeout > millis()) // While we haven't timed out 741 | { 742 | if (_serial->available()) // If data is available on UART RX 743 | { 744 | received += readByteToBuffer(); 745 | if (searchBuffer(pass)) // Search the buffer for goodRsp 746 | return received; // Return how number of chars read 747 | if (searchBuffer(fail)) 748 | return ESP8266_RSP_FAIL; 749 | } 750 | } 751 | 752 | if (received > 0) // If we received any characters 753 | return ESP8266_RSP_UNKNOWN; // Return unkown response error code 754 | else // If we haven't received any characters 755 | return ESP8266_RSP_TIMEOUT; // Return the timeout error code 756 | } 757 | 758 | ////////////////// 759 | // Buffer Stuff // 760 | ////////////////// 761 | void ESP8266Class::clearBuffer() 762 | { 763 | memset(esp8266RxBuffer, '\0', ESP8266_RX_BUFFER_LEN); 764 | bufferHead = 0; 765 | } 766 | 767 | unsigned int ESP8266Class::readByteToBuffer() 768 | { 769 | // Read the data in 770 | char c = _serial->read(); 771 | 772 | // Store the data in the buffer 773 | esp8266RxBuffer[bufferHead] = c; 774 | //! TODO: Don't care if we overflow. Should we? Set a flag or something? 775 | bufferHead = (bufferHead + 1) % ESP8266_RX_BUFFER_LEN; 776 | 777 | return 1; 778 | } 779 | 780 | char * ESP8266Class::searchBuffer(const char * test) 781 | { 782 | int bufferLen = strlen((const char *)esp8266RxBuffer); 783 | // If our buffer isn't full, just do an strstr 784 | if (bufferLen < ESP8266_RX_BUFFER_LEN) 785 | return strstr((const char *)esp8266RxBuffer, test); 786 | else 787 | { //! TODO 788 | // If the buffer is full, we need to search from the end of the 789 | // buffer back to the beginning. 790 | int testLen = strlen(test); 791 | for (int i=0; i 25 | #include 26 | #include 27 | #include "SparkFunESP8266Client.h" 28 | #include "SparkFunESP8266Server.h" 29 | 30 | ///////////////////// 31 | // Pin Definitions // 32 | ///////////////////// 33 | #define ESP8266_SW_RX 9 // ESP8266 UART0 RXI goes to Arduino pin 9 34 | #define ESP8266_SW_TX 8 // ESP8266 UART0 TXO goes to Arduino pin 8 35 | 36 | /////////////////////////////// 37 | // Command Response Timeouts // 38 | /////////////////////////////// 39 | #define COMMAND_RESPONSE_TIMEOUT 1000 40 | #define COMMAND_PING_TIMEOUT 3000 41 | #define WIFI_CONNECT_TIMEOUT 30000 42 | #define COMMAND_RESET_TIMEOUT 5000 43 | #define CLIENT_CONNECT_TIMEOUT 5000 44 | 45 | #define ESP8266_MAX_SOCK_NUM 5 46 | #define ESP8266_SOCK_NOT_AVAIL 255 47 | 48 | static SoftwareSerial swSerial(ESP8266_SW_TX, ESP8266_SW_RX); 49 | 50 | typedef enum esp8266_cmd_rsp { 51 | ESP8266_CMD_BAD = -5, 52 | ESP8266_RSP_MEMORY_ERR = -4, 53 | ESP8266_RSP_FAIL = -3, 54 | ESP8266_RSP_UNKNOWN = -2, 55 | ESP8266_RSP_TIMEOUT = -1, 56 | ESP8266_RSP_SUCCESS = 0 57 | }; 58 | 59 | typedef enum esp8266_wifi_mode { 60 | ESP8266_MODE_STA = 1, 61 | ESP8266_MODE_AP = 2, 62 | ESP8266_MODE_STAAP = 3 63 | }; 64 | 65 | typedef enum esp8266_command_type { 66 | ESP8266_CMD_QUERY, 67 | ESP8266_CMD_SETUP, 68 | ESP8266_CMD_EXECUTE 69 | }; 70 | 71 | typedef enum esp8266_encryption { 72 | ESP8266_ECN_OPEN, 73 | ESP8266_ECN_WPA_PSK, 74 | ESP8266_ECN_WPA2_PSK, 75 | ESP8266_ECN_WPA_WPA2_PSK 76 | }; 77 | 78 | typedef enum esp8266_connect_status { 79 | ESP8266_STATUS_GOTIP = 2, 80 | ESP8266_STATUS_CONNECTED = 3, 81 | ESP8266_STATUS_DISCONNECTED = 4, 82 | ESP8266_STATUS_NOWIFI = 5 83 | }; 84 | 85 | typedef enum esp8266_serial_port { 86 | ESP8266_SOFTWARE_SERIAL, 87 | ESP8266_HARDWARE_SERIAL 88 | }; 89 | 90 | typedef enum esp8266_socket_state { 91 | AVAILABLE = 0, 92 | TAKEN = 1, 93 | }; 94 | 95 | typedef enum esp8266_connection_type { 96 | ESP8266_TCP, 97 | ESP8266_UDP, 98 | ESP8266_TYPE_UNDEFINED 99 | }; 100 | 101 | typedef enum esp8266_tetype { 102 | ESP8266_CLIENT, 103 | ESP8266_SERVER 104 | }; 105 | 106 | struct esp8266_ipstatus 107 | { 108 | uint8_t linkID; 109 | esp8266_connection_type type; 110 | IPAddress remoteIP; 111 | uint16_t port; 112 | esp8266_tetype tetype; 113 | }; 114 | 115 | struct esp8266_status 116 | { 117 | esp8266_connect_status stat; 118 | esp8266_ipstatus ipstatus[ESP8266_MAX_SOCK_NUM]; 119 | }; 120 | 121 | class ESP8266Class : public Stream 122 | { 123 | public: 124 | ESP8266Class(); 125 | 126 | bool begin(unsigned long baudRate = 9600, esp8266_serial_port serialPort = ESP8266_SOFTWARE_SERIAL); 127 | 128 | /////////////////////// 129 | // Basic AT Commands // 130 | /////////////////////// 131 | bool test(); 132 | bool reset(); 133 | int16_t getVersion(char * ATversion, char * SDKversion, char * compileTime); 134 | bool echo(bool enable); 135 | bool setBaud(unsigned long baud); 136 | 137 | //////////////////// 138 | // WiFi Functions // 139 | //////////////////// 140 | int16_t getMode(); 141 | int16_t setMode(esp8266_wifi_mode mode); 142 | int16_t setMode(int8_t mode); 143 | int16_t connect(const char * ssid); 144 | int16_t connect(const char * ssid, const char * pwd); 145 | int16_t getAP(char * ssid); 146 | int16_t localMAC(char * mac); 147 | int16_t disconnect(); 148 | IPAddress localIP(); 149 | 150 | ///////////////////// 151 | // TCP/IP Commands // 152 | ///////////////////// 153 | int16_t status(); 154 | int16_t updateStatus(); 155 | int16_t tcpConnect(uint8_t linkID, const char * destination, uint16_t port, uint16_t keepAlive); 156 | int16_t tcpSend(uint8_t linkID, const uint8_t *buf, size_t size); 157 | int16_t close(uint8_t linkID); 158 | int16_t setTransferMode(uint8_t mode); 159 | int16_t setMux(uint8_t mux); 160 | int16_t configureTCPServer(uint16_t port, uint8_t create = 1); 161 | int16_t ping(IPAddress ip); 162 | int16_t ping(char * server); 163 | 164 | ////////////////////////// 165 | // Custom GPIO Commands // 166 | ////////////////////////// 167 | int16_t pinMode(uint8_t pin, uint8_t mode); 168 | int16_t digitalWrite(uint8_t pin, uint8_t state); 169 | int8_t digitalRead(uint8_t pin); 170 | 171 | /////////////////////////////////// 172 | // Virtual Functions from Stream // 173 | /////////////////////////////////// 174 | size_t write(uint8_t); 175 | int available(); 176 | int read(); 177 | int peek(); 178 | void flush(); 179 | 180 | friend class ESP8266Client; 181 | friend class ESP8266Server; 182 | 183 | int16_t _state[ESP8266_MAX_SOCK_NUM]; 184 | 185 | protected: 186 | Stream* _serial; 187 | unsigned long _baud; 188 | 189 | private: 190 | ////////////////////////// 191 | // Command Send/Receive // 192 | ////////////////////////// 193 | void sendCommand(const char * cmd, enum esp8266_command_type type = ESP8266_CMD_EXECUTE, const char * params = NULL); 194 | int16_t readForResponse(const char * rsp, unsigned int timeout); 195 | int16_t readForResponses(const char * pass, const char * fail, unsigned int timeout); 196 | 197 | ////////////////// 198 | // Buffer Stuff // 199 | ////////////////// 200 | /// clearBuffer() - Reset buffer pointer, set all values to 0 201 | void clearBuffer(); 202 | 203 | /// readByteToBuffer() - Read first byte from UART receive buffer 204 | /// and store it in rxBuffer. 205 | unsigned int readByteToBuffer(); 206 | 207 | /// searchBuffer([test]) - Search buffer for string [test] 208 | /// Success: Returns pointer to beginning of string 209 | /// Fail: returns NULL 210 | //! TODO: Fix this function so it searches circularly 211 | char * searchBuffer(const char * test); 212 | 213 | esp8266_status _status; 214 | 215 | uint8_t sync(); 216 | }; 217 | 218 | extern ESP8266Class esp8266; 219 | 220 | #endif 221 | -------------------------------------------------------------------------------- /src/util/ESP8266_AT.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | ESP8266_AT.h 3 | ESP8266 AT Command Definitions 4 | Jim Lindblom @ SparkFun Electronics 5 | Original Creation Date: June 20, 2015 6 | http://github.com/sparkfun/SparkFun_ESP8266_AT_Arduino_Library 7 | 8 | !!! Description Here !!! 9 | 10 | Development environment specifics: 11 | IDE: Arduino 1.6.5 12 | Hardware Platform: Arduino Uno 13 | ESP8266 WiFi Shield Version: 1.0 14 | 15 | This code is beerware; if you see me (or any other SparkFun employee) at the 16 | local, and you've found our code helpful, please buy us a round! 17 | 18 | Distributed as-is; no warranty is given. 19 | ******************************************************************************/ 20 | 21 | ////////////////////// 22 | // Common Responses // 23 | ////////////////////// 24 | const char RESPONSE_OK[] = "OK\r\n"; 25 | const char RESPONSE_ERROR[] = "ERROR\r\n"; 26 | const char RESPONSE_FAIL[] = "FAIL"; 27 | const char RESPONSE_READY[] = "READY!"; 28 | 29 | /////////////////////// 30 | // Basic AT Commands // 31 | /////////////////////// 32 | const char ESP8266_TEST[] = ""; // Test AT startup 33 | const char ESP8266_RESET[] = "+RST"; // Restart module 34 | const char ESP8266_VERSION[] = "+GMR"; // View version info 35 | //!const char ESP8266_SLEEP[] = "+GSLP"; // Enter deep-sleep mode 36 | const char ESP8266_ECHO_ENABLE[] = "E1"; // AT commands echo 37 | const char ESP8266_ECHO_DISABLE[] = "E0"; // AT commands echo 38 | //!const char ESP8266_RESTORE[] = "+RESTORE"; // Factory reset 39 | const char ESP8266_UART[] = "+UART"; // UART configuration 40 | 41 | //////////////////// 42 | // WiFi Functions // 43 | //////////////////// 44 | const char ESP8266_WIFI_MODE[] = "+CWMODE"; // WiFi mode (sta/AP/sta+AP) 45 | const char ESP8266_CONNECT_AP[] = "+CWJAP"; // Connect to AP 46 | //!const char ESP8266_LIST_AP[] = "+CWLAP"; // List available AP's 47 | const char ESP8266_DISCONNECT[] = "+CWQAP"; // Disconnect from AP 48 | //!const char ESP8266_AP_CONFIG[] = "+CWSAP"; // Set softAP configuration 49 | //!const char ESP8266_STATION_IP[] = "+CWLIF"; // List station IP's connected to softAP 50 | //!const char ESP8266_DHCP_EN[] = "+CWDHCP"; // Enable/disable DHCP 51 | //!const char ESP8266_AUTO_CONNECT[] = "+CWAUTOCONN"; // Connect to AP automatically 52 | //!const char ESP8266_SET_STA_MAC[] = "+CIPSTAMAC"; // Set MAC address of station 53 | const char ESP8266_GET_STA_MAC[] = "+CIPSTAMAC"; // Get MAC address of station 54 | //!const char ESP8266_SET_AP_MAC[] = "+CIPAPMAC"; // Set MAC address of softAP 55 | //!const char ESP8266_SET_STA_IP[] = "+CIPSTA"; // Set IP address of ESP8266 station 56 | //!const char ESP8266_SET_AP_IP[] = "+CIPAP"; // Set IP address of ESP8266 softAP 57 | 58 | ///////////////////// 59 | // TCP/IP Commands // 60 | ///////////////////// 61 | const char ESP8266_TCP_STATUS[] = "+CIPSTATUS"; // Get connection status 62 | const char ESP8266_TCP_CONNECT[] = "+CIPSTART"; // Establish TCP connection or register UDP port 63 | const char ESP8266_TCP_SEND[] = "+CIPSEND"; // Send Data 64 | const char ESP8266_TCP_CLOSE[] = "+CIPCLOSE"; // Close TCP/UDP connection 65 | const char ESP8266_GET_LOCAL_IP[] = "+CIFSR"; // Get local IP address 66 | const char ESP8266_TCP_MULTIPLE[] = "+CIPMUX"; // Set multiple connections mode 67 | const char ESP8266_SERVER_CONFIG[] = "+CIPSERVER"; // Configure as server 68 | const char ESP8266_TRANSMISSION_MODE[] = "+CIPMODE"; // Set transmission mode 69 | //!const char ESP8266_SET_SERVER_TIMEOUT[] = "+CIPSTO"; // Set timeout when ESP8266 runs as TCP server 70 | const char ESP8266_PING[] = "+PING"; // Function PING 71 | 72 | ////////////////////////// 73 | // Custom GPIO Commands // 74 | ////////////////////////// 75 | const char ESP8266_PINMODE[] = "+PINMODE"; // Set GPIO mode (input/output) 76 | const char ESP8266_PINWRITE[] = "+PINWRITE"; // Write GPIO (high/low) 77 | const char ESP8266_PINREAD[] = "+PINREAD"; // Read GPIO digital value 78 | --------------------------------------------------------------------------------