initial commit
This commit is contained in:
270
libraries/Adafruit_ESP8266/Adafruit_ESP8266.cpp
Normal file
270
libraries/Adafruit_ESP8266/Adafruit_ESP8266.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
/*------------------------------------------------------------------------
|
||||
An Arduino library for the ESP8266 WiFi-serial bridge
|
||||
|
||||
https://www.adafruit.com/product/2282
|
||||
|
||||
The ESP8266 is a 3.3V device. Safe operation with 5V devices (most
|
||||
Arduino boards) requires a logic-level shifter for TX and RX signals.
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried and Phil Burgess for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution.
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
#include "Adafruit_ESP8266.h"
|
||||
|
||||
// Constructor
|
||||
Adafruit_ESP8266::Adafruit_ESP8266(Stream *s, Stream *d, int8_t r) :
|
||||
stream(s), debug(d), reset_pin(r), host(NULL), writing(false) {
|
||||
setTimeouts();
|
||||
};
|
||||
|
||||
// Override various timings. Passing 0 for an item keeps current setting.
|
||||
void Adafruit_ESP8266::setTimeouts(
|
||||
uint32_t rcv, uint32_t rst, uint32_t con, uint32_t ipd) {
|
||||
if(rcv) {
|
||||
stream->setTimeout(rcv);
|
||||
receiveTimeout = rcv;
|
||||
}
|
||||
if(rst) resetTimeout = rst;
|
||||
if(con) connectTimeout = con;
|
||||
if(ipd) ipdTimeout = ipd;
|
||||
}
|
||||
|
||||
// Override boot marker string, or pass NULL to restore default.
|
||||
void Adafruit_ESP8266::setBootMarker(Fstr *s) {
|
||||
bootMarker = s ? s : defaultBootMarker;
|
||||
}
|
||||
|
||||
// Anything printed to the EPS8266 object will be split to both the WiFi
|
||||
// and debug streams. Saves having to print everything twice in debug code.
|
||||
size_t Adafruit_ESP8266::write(uint8_t c) {
|
||||
if(debug) {
|
||||
if(!writing) {
|
||||
debug->print(F("---> "));
|
||||
writing = true;
|
||||
}
|
||||
debug->write(c);
|
||||
}
|
||||
return stream->write(c);
|
||||
}
|
||||
|
||||
// Equivalent to Arduino Stream find() function, but with search string in
|
||||
// flash/PROGMEM rather than RAM-resident. Returns true if string found
|
||||
// (any further pending input remains in stream), false if timeout occurs.
|
||||
// Can optionally pass NULL (or no argument) to read/purge the OK+CR/LF
|
||||
// returned by most AT commands. The ipd flag indicates this call follows
|
||||
// a CIPSEND request and might be broken into multiple sections with +IPD
|
||||
// delimiters, which must be parsed and handled (as the search string may
|
||||
// cross these delimiters and/or contain \r or \n itself).
|
||||
boolean Adafruit_ESP8266::find(Fstr *str, boolean ipd) {
|
||||
uint8_t stringLength, matchedLength = 0;
|
||||
int c;
|
||||
boolean found = false;
|
||||
uint32_t t, save;
|
||||
uint16_t bytesToGo = 0;
|
||||
|
||||
if(ipd) { // IPD stream stalls really long occasionally, what gives?
|
||||
save = receiveTimeout;
|
||||
setTimeouts(ipdTimeout);
|
||||
}
|
||||
|
||||
if(str == NULL) str = F("OK\r\n");
|
||||
stringLength = strlen_P((Pchr *)str);
|
||||
|
||||
if(debug && writing) {
|
||||
debug->print(F("<--- '"));
|
||||
writing = false;
|
||||
}
|
||||
|
||||
for(t = millis();;) {
|
||||
if(ipd && !bytesToGo) { // Expecting next IPD marker?
|
||||
if(find(F("+IPD,"))) { // Find marker in stream
|
||||
for(;;) {
|
||||
if((c = stream->read()) > 0) { // Read subsequent chars...
|
||||
if(debug) debug->write(c);
|
||||
if(c == ':') break; // ...until delimiter.
|
||||
bytesToGo = (bytesToGo * 10) + (c - '0'); // Keep count
|
||||
t = millis(); // Timeout resets w/each byte received
|
||||
} else if(c < 0) { // No data on stream, check for timeout
|
||||
if((millis() - t) > receiveTimeout) goto bail;
|
||||
} else goto bail; // EOD on stream
|
||||
}
|
||||
} else break; // OK (EOD) or ERROR
|
||||
}
|
||||
|
||||
if((c = stream->read()) > 0) { // Character received?
|
||||
if(debug) debug->write(c); // Copy to debug stream
|
||||
bytesToGo--;
|
||||
if(c == pgm_read_byte((Pchr *)str +
|
||||
matchedLength)) { // Match next byte?
|
||||
if(++matchedLength == stringLength) { // Matched whole string?
|
||||
found = true; // Winner!
|
||||
break;
|
||||
}
|
||||
} else { // Character mismatch; reset match pointer+counter
|
||||
matchedLength = 0;
|
||||
}
|
||||
t = millis(); // Timeout resets w/each byte received
|
||||
} else if(c < 0) { // No data on stream, check for timeout
|
||||
if((millis() - t) > receiveTimeout) break; // You lose, good day sir
|
||||
} else break; // End-of-data on stream
|
||||
}
|
||||
|
||||
bail: // Sorry, dreaded goto. Because nested loops.
|
||||
if(debug) debug->println('\'');
|
||||
if(ipd) setTimeouts(save);
|
||||
return found;
|
||||
}
|
||||
|
||||
// Read from ESP8266 stream into RAM, up to a given size. Max number of
|
||||
// chars read is 1 less than this, so NUL can be appended on string.
|
||||
int Adafruit_ESP8266::readLine(char *buf, int bufSiz) {
|
||||
if(debug && writing) {
|
||||
debug->print(F("<--- '"));
|
||||
writing = false;
|
||||
}
|
||||
int bytesRead = stream->readBytesUntil('\r', buf, bufSiz-1);
|
||||
buf[bytesRead] = 0;
|
||||
if(debug) {
|
||||
debug->print(buf);
|
||||
debug->println('\'');
|
||||
}
|
||||
while(stream->read() != '\n'); // Discard thru newline
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
// ESP8266 is reset by momentarily connecting RST to GND. Level shifting is
|
||||
// not necessary provided you don't accidentally set the pin to HIGH output.
|
||||
// It's generally safe-ish as the default Arduino pin state is INPUT (w/no
|
||||
// pullup) -- setting to LOW provides an open-drain for reset.
|
||||
// Returns true if expected boot message is received (or if RST is unused),
|
||||
// false otherwise.
|
||||
boolean Adafruit_ESP8266::hardReset(void) {
|
||||
if(reset_pin < 0) return true;
|
||||
digitalWrite(reset_pin, LOW);
|
||||
pinMode(reset_pin, OUTPUT); // Open drain; reset -> GND
|
||||
delay(10); // Hold a moment
|
||||
pinMode(reset_pin, INPUT); // Back to high-impedance pin state
|
||||
return find(bootMarker); // Purge boot message from stream
|
||||
}
|
||||
|
||||
// Soft reset. Returns true if expected boot message received, else false.
|
||||
boolean Adafruit_ESP8266::softReset(void) {
|
||||
boolean found = false;
|
||||
uint32_t save = receiveTimeout; // Temporarily override recveive timeout,
|
||||
receiveTimeout = resetTimeout; // reset time is longer than normal I/O.
|
||||
println(F("AT+RST")); // Issue soft-reset command
|
||||
if(find(bootMarker)) { // Wait for boot message
|
||||
println(F("ATE0")); // Turn off echo
|
||||
found = find(); // OK?
|
||||
}
|
||||
receiveTimeout = save; // Restore normal receive timeout
|
||||
return found;
|
||||
}
|
||||
|
||||
// For interactive debugging...shuttle data between Serial Console <-> WiFi
|
||||
void Adafruit_ESP8266::debugLoop(void) {
|
||||
if(!debug) for(;;); // If no debug connection, nothing to do.
|
||||
|
||||
debug->println(F("\n========================"));
|
||||
for(;;) {
|
||||
if(debug->available()) stream->write(debug->read());
|
||||
if(stream->available()) debug->write(stream->read());
|
||||
}
|
||||
}
|
||||
|
||||
// Connect to WiFi access point. SSID and password are flash-resident
|
||||
// strings. May take several seconds to execute, this is normal.
|
||||
// Returns true on successful connection, false otherwise.
|
||||
boolean Adafruit_ESP8266::connectToAP(Fstr *ssid, Fstr *pass) {
|
||||
char buf[256];
|
||||
|
||||
println(F("AT+CWMODE=1")); // WiFi mode = Sta
|
||||
readLine(buf, sizeof(buf));
|
||||
if(!(strstr_P(buf, (Pchr *)F("OK")) ||
|
||||
strstr_P(buf, (Pchr *)F("no change")))) return false;
|
||||
|
||||
print(F("AT+CWJAP=\"")); // Join access point
|
||||
print(ssid);
|
||||
print(F("\",\""));
|
||||
print(pass);
|
||||
println('\"');
|
||||
uint32_t save = receiveTimeout; // Temporarily override recv timeout,
|
||||
receiveTimeout = connectTimeout; // connection time is much longer!
|
||||
boolean found = find(); // Await 'OK' message
|
||||
receiveTimeout = save; // Restore normal receive timeout
|
||||
if(found) {
|
||||
println(F("AT+CIPMUX=0")); // Set single-client mode
|
||||
found = find(); // Await 'OK'
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
void Adafruit_ESP8266::closeAP(void) {
|
||||
println(F("AT+CWQAP")); // Quit access point
|
||||
find(); // Purge 'OK'
|
||||
}
|
||||
|
||||
// Open TCP connection. Hostname is flash-resident string.
|
||||
// Returns true on successful connection, else false.
|
||||
boolean Adafruit_ESP8266::connectTCP(Fstr *h, int port) {
|
||||
|
||||
print(F("AT+CIPSTART=\"TCP\",\""));
|
||||
print(h);
|
||||
print(F("\","));
|
||||
println(port);
|
||||
|
||||
if(find(F("Linked"))) {
|
||||
host = h;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Adafruit_ESP8266::closeTCP(void) {
|
||||
println(F("AT+CIPCLOSE"));
|
||||
find(F("Unlink\r\n"));
|
||||
}
|
||||
|
||||
// Requests page from currently-open TCP connection. URL is
|
||||
// flash-resident string. Returns true if request issued successfully,
|
||||
// else false. Calling function should then handle data returned, may
|
||||
// need to parse IPD delimiters (see notes in find() function.
|
||||
// (Can call find(F("Unlink"), true) to dump to debug.)
|
||||
boolean Adafruit_ESP8266::requestURL(Fstr *url) {
|
||||
print(F("AT+CIPSEND="));
|
||||
println(25 + strlen_P((Pchr *)url) + strlen_P((Pchr *)host));
|
||||
if(find(F("> "))) { // Wait for prompt
|
||||
print(F("GET ")); // 4
|
||||
print(url);
|
||||
print(F(" HTTP/1.1\r\nHost: ")); // 17
|
||||
print(host);
|
||||
print(F("\r\n\r\n")); // 4
|
||||
return(find()); // Gets 'SEND OK' line
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Requests page from currently-open TCP connection. URL is
|
||||
// character string in SRAM. Returns true if request issued successfully,
|
||||
// else false. Calling function should then handle data returned, may
|
||||
// need to parse IPD delimiters (see notes in find() function.
|
||||
// (Can call find(F("Unlink"), true) to dump to debug.)
|
||||
boolean Adafruit_ESP8266::requestURL(char* url) {
|
||||
print(F("AT+CIPSEND="));
|
||||
println(25 + strlen(url) + strlen_P((Pchr *)host));
|
||||
if(find(F("> "))) { // Wait for prompt
|
||||
print(F("GET ")); // 4
|
||||
print(url);
|
||||
print(F(" HTTP/1.1\r\nHost: ")); // 17
|
||||
print(host);
|
||||
print(F("\r\n\r\n")); // 4
|
||||
return(find()); // Gets 'SEND OK' line
|
||||
}
|
||||
return false;
|
||||
}
|
||||
65
libraries/Adafruit_ESP8266/Adafruit_ESP8266.h
Normal file
65
libraries/Adafruit_ESP8266/Adafruit_ESP8266.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*------------------------------------------------------------------------
|
||||
An Arduino library for the ESP8266 WiFi-serial bridge
|
||||
|
||||
https://www.adafruit.com/product/2282
|
||||
|
||||
The ESP8266 is a 3.3V device. Safe operation with 5V devices (most
|
||||
Arduino boards) requires a logic-level shifter for TX and RX signals.
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried and Phil Burgess for Adafruit Industries.
|
||||
MIT license, all text above must be included in any redistribution.
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _ADAFRUIT_ESP8266_H_
|
||||
#define _ADAFRUIT_ESP8266_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#define ESP_RECEIVE_TIMEOUT 1000L
|
||||
#define ESP_RESET_TIMEOUT 5000L
|
||||
#define ESP_CONNECT_TIMEOUT 15000L
|
||||
#define ESP_IPD_TIMEOUT 120000L
|
||||
|
||||
typedef const __FlashStringHelper Fstr; // PROGMEM/flash-resident string
|
||||
typedef const PROGMEM char Pchr; // Ditto, kindasorta
|
||||
|
||||
#define defaultBootMarker F("ready\r\n")
|
||||
|
||||
// Subclassing Print makes debugging easier -- output en route to
|
||||
// WiFi module can be duplicated on a second stream (e.g. Serial).
|
||||
class Adafruit_ESP8266 : public Print {
|
||||
public:
|
||||
Adafruit_ESP8266(Stream *s = &Serial, Stream *d = NULL, int8_t r = -1);
|
||||
boolean hardReset(void),
|
||||
softReset(void),
|
||||
find(Fstr *str = NULL, boolean ipd = false),
|
||||
connectToAP(Fstr *ssid, Fstr *pass),
|
||||
connectTCP(Fstr *host, int port),
|
||||
requestURL(Fstr *url),
|
||||
requestURL(char* url);
|
||||
int readLine(char *buf, int bufSiz);
|
||||
void closeAP(void),
|
||||
closeTCP(void),
|
||||
debugLoop(void),
|
||||
setDebug(Stream *d = NULL),
|
||||
setTimeouts(uint32_t rcv = ESP_RECEIVE_TIMEOUT,
|
||||
uint32_t rst = ESP_RESET_TIMEOUT,
|
||||
uint32_t con = ESP_CONNECT_TIMEOUT,
|
||||
uint32_t ipd = ESP_IPD_TIMEOUT),
|
||||
setBootMarker(Fstr *s = NULL);
|
||||
private:
|
||||
Stream *stream, // -> ESP8266, e.g. SoftwareSerial or Serial1
|
||||
*debug; // -> host, e.g. Serial
|
||||
uint32_t receiveTimeout, resetTimeout, connectTimeout, ipdTimeout;
|
||||
int8_t reset_pin; // -1 if RST not connected
|
||||
Fstr *host, // Non-NULL when TCP connection open
|
||||
*bootMarker; // String indicating successful boot
|
||||
boolean writing;
|
||||
virtual size_t write(uint8_t); // Because Print subclass
|
||||
};
|
||||
|
||||
#endif // _ADAFRUIT_ESP8266_H_
|
||||
4
libraries/Adafruit_ESP8266/README.md
Normal file
4
libraries/Adafruit_ESP8266/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
Adafruit_ESP8266
|
||||
================
|
||||
|
||||
Example code for ESP8266 chipset
|
||||
117
libraries/Adafruit_ESP8266/examples/webclient/webclient.ino
Normal file
117
libraries/Adafruit_ESP8266/examples/webclient/webclient.ino
Normal file
@@ -0,0 +1,117 @@
|
||||
/*------------------------------------------------------------------------
|
||||
Simple ESP8266 test. Requires SoftwareSerial and an ESP8266 that's been
|
||||
flashed with recent 'AT' firmware operating at 9600 baud. Only tested
|
||||
w/Adafruit-programmed modules: https://www.adafruit.com/product/2282
|
||||
|
||||
The ESP8266 is a 3.3V device. Safe operation with 5V devices (most
|
||||
Arduino boards) requires a logic-level shifter for TX and RX signals.
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
#include <Adafruit_ESP8266.h>
|
||||
#include <SoftwareSerial.h>
|
||||
|
||||
#define ESP_RX 2
|
||||
#define ESP_TX 3
|
||||
#define ESP_RST 4
|
||||
SoftwareSerial softser(ESP_RX, ESP_TX);
|
||||
|
||||
// Must declare output stream before Adafruit_ESP8266 constructor; can be
|
||||
// a SoftwareSerial stream, or Serial/Serial1/etc. for UART.
|
||||
Adafruit_ESP8266 wifi(&softser, &Serial, ESP_RST);
|
||||
// Must call begin() on the stream(s) before using Adafruit_ESP8266 object.
|
||||
|
||||
#define ESP_SSID "SSIDNAME" // Your network name here
|
||||
#define ESP_PASS "PASSWORD" // Your network password here
|
||||
|
||||
#define HOST "www.adafruit.com" // Host to contact
|
||||
#define PAGE "/testwifi/index.html" // Web page to request
|
||||
#define PORT 80 // 80 = HTTP default port
|
||||
|
||||
#define LED_PIN 13
|
||||
|
||||
void setup() {
|
||||
char buffer[50];
|
||||
|
||||
// Flash LED on power-up
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
for(uint8_t i=0; i<3; i++) {
|
||||
digitalWrite(13, HIGH); delay(50);
|
||||
digitalWrite(13, LOW); delay(100);
|
||||
}
|
||||
|
||||
// This might work with other firmware versions (no guarantees)
|
||||
// by providing a string to ID the tail end of the boot message:
|
||||
|
||||
// comment/replace this if you are using something other than v 0.9.2.4!
|
||||
wifi.setBootMarker(F("Version:0.9.2.4]\r\n\r\nready"));
|
||||
|
||||
softser.begin(9600); // Soft serial connection to ESP8266
|
||||
Serial.begin(57600); while(!Serial); // UART serial debug
|
||||
|
||||
Serial.println(F("Adafruit ESP8266 Demo"));
|
||||
|
||||
// Test if module is ready
|
||||
Serial.print(F("Hard reset..."));
|
||||
if(!wifi.hardReset()) {
|
||||
Serial.println(F("no response from module."));
|
||||
for(;;);
|
||||
}
|
||||
Serial.println(F("OK."));
|
||||
|
||||
Serial.print(F("Soft reset..."));
|
||||
if(!wifi.softReset()) {
|
||||
Serial.println(F("no response from module."));
|
||||
for(;;);
|
||||
}
|
||||
Serial.println(F("OK."));
|
||||
|
||||
Serial.print(F("Checking firmware version..."));
|
||||
wifi.println(F("AT+GMR"));
|
||||
if(wifi.readLine(buffer, sizeof(buffer))) {
|
||||
Serial.println(buffer);
|
||||
wifi.find(); // Discard the 'OK' that follows
|
||||
} else {
|
||||
Serial.println(F("error"));
|
||||
}
|
||||
|
||||
Serial.print(F("Connecting to WiFi..."));
|
||||
if(wifi.connectToAP(F(ESP_SSID), F(ESP_PASS))) {
|
||||
|
||||
// IP addr check isn't part of library yet, but
|
||||
// we can manually request and place in a string.
|
||||
Serial.print(F("OK\nChecking IP addr..."));
|
||||
wifi.println(F("AT+CIFSR"));
|
||||
if(wifi.readLine(buffer, sizeof(buffer))) {
|
||||
Serial.println(buffer);
|
||||
wifi.find(); // Discard the 'OK' that follows
|
||||
|
||||
Serial.print(F("Connecting to host..."));
|
||||
if(wifi.connectTCP(F(HOST), PORT)) {
|
||||
Serial.print(F("OK\nRequesting page..."));
|
||||
if(wifi.requestURL(F(PAGE))) {
|
||||
Serial.println("OK\nSearching for string...");
|
||||
// Search for a phrase in the open stream.
|
||||
// Must be a flash-resident string (F()).
|
||||
if(wifi.find(F("working"), true)) {
|
||||
Serial.println(F("found!"));
|
||||
} else {
|
||||
Serial.println(F("not found."));
|
||||
}
|
||||
} else { // URL request failed
|
||||
Serial.println(F("error"));
|
||||
}
|
||||
wifi.closeTCP();
|
||||
} else { // TCP connect failed
|
||||
Serial.println(F("D'oh!"));
|
||||
}
|
||||
} else { // IP addr check failed
|
||||
Serial.println(F("error"));
|
||||
}
|
||||
wifi.closeAP();
|
||||
} else { // WiFi connection failed
|
||||
Serial.println(F("FAIL"));
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
9
libraries/Adafruit_ESP8266/library.properties
Normal file
9
libraries/Adafruit_ESP8266/library.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
name=Adafruit ESP8266
|
||||
version=1.0.0
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Example code for ESP8266 chipset
|
||||
paragraph=Example code for ESP8266 chipset
|
||||
category=Communication
|
||||
url=https://github.com/adafruit/Adafruit_ESP8266
|
||||
architectures=*
|
||||
367
libraries/Adafruit_ESP8266/previous/Adafruit_ESP8266.ino
Normal file
367
libraries/Adafruit_ESP8266/previous/Adafruit_ESP8266.ino
Normal file
@@ -0,0 +1,367 @@
|
||||
// This is a super simple demo program for ESP8266's that can use software serial
|
||||
// @ 9600 baud. Requires firmware that runs at 9600 baud, only tested with Adafruit
|
||||
// programmed modules!
|
||||
|
||||
#include <SoftwareSerial.h>
|
||||
#define SSID "SSIDNAME" //your wifi ssid here
|
||||
#define PASS "PASSWORD" //your wifi key here
|
||||
|
||||
// www.adafruit.com/testwifi/index.html
|
||||
#define HOST "www.adafruit.com"
|
||||
#define WEBPAGE "/testwifi/index.html"
|
||||
#define PORT "80"
|
||||
|
||||
#define ESP_RST 4
|
||||
|
||||
// Use software serial (check to make sure these are valid softserial pins!)
|
||||
#define ESP_RX 2
|
||||
#define ESP_TX 3
|
||||
SoftwareSerial softser(ESP_RX, ESP_TX); // RX, TX
|
||||
Stream *esp = &softser;
|
||||
|
||||
// can also do
|
||||
// Stream *esp = &Serial1;
|
||||
|
||||
#define REPLYBUFFSIZ 255
|
||||
char replybuffer[REPLYBUFFSIZ];
|
||||
uint8_t getReply(char *send, uint16_t timeout = 500, boolean echo = true);
|
||||
uint8_t espreadline(uint16_t timeout = 500, boolean multiline = false);
|
||||
boolean sendCheckReply(char *send, char *reply, uint16_t timeout = 500);
|
||||
|
||||
|
||||
enum {WIFI_ERROR_NONE=0, WIFI_ERROR_AT, WIFI_ERROR_RST, WIFI_ERROR_SSIDPWD, WIFI_ERROR_SERVER, WIFI_ERROR_UNKNOWN};
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(9, OUTPUT);
|
||||
pinMode(13, OUTPUT);
|
||||
|
||||
//blink led13 to indicate power up
|
||||
for(int i = 0; i<3; i++)
|
||||
{
|
||||
digitalWrite(13,HIGH);
|
||||
delay(50);
|
||||
digitalWrite(13,LOW);
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// Serial debug console
|
||||
Serial.begin(115200);
|
||||
// Set time to wait for response strings to be found
|
||||
|
||||
//Open software serial for chatting to ESP
|
||||
softser.begin(9600); // requires new firmware!
|
||||
// OR use hardware serial
|
||||
//Serial1.begin(9600);
|
||||
|
||||
Serial.println(F("Adafruit's ESP8266 Demo"));
|
||||
|
||||
Serial.println(F("Hard reset..."));
|
||||
// hard reset if you can
|
||||
pinMode(ESP_RST, INPUT);
|
||||
digitalWrite(ESP_RST, LOW);
|
||||
pinMode(ESP_RST, OUTPUT);
|
||||
delay(100);
|
||||
pinMode(ESP_RST, INPUT);
|
||||
delay(2000);
|
||||
|
||||
//test if the module is ready
|
||||
if(! espReset()) {
|
||||
Serial.println("Module didn't respond :(");
|
||||
debugLoop();
|
||||
}
|
||||
|
||||
Serial.println(F("ESP Module is ready! :)"));
|
||||
|
||||
//connect to the wifi
|
||||
byte err = setupWiFi();
|
||||
|
||||
if (err) {
|
||||
// error, print error code
|
||||
Serial.print("setup error:"); Serial.println((int)err);
|
||||
|
||||
debugLoop();
|
||||
}
|
||||
|
||||
// success, print IP
|
||||
uint32_t ip = getIP();
|
||||
Serial.print("ESP setup success, my IP addr:");
|
||||
if (ip) {
|
||||
Serial.println(ip, HEX);
|
||||
} else {
|
||||
Serial.println("none");
|
||||
}
|
||||
|
||||
sendCheckReply("AT+CIPSTO=0", "OK");
|
||||
|
||||
//set the single connection mode
|
||||
}
|
||||
|
||||
boolean ESP_GETpage(char *host, uint16_t port, char *page) {
|
||||
String cmd = "AT+CIPSTART=\"TCP\",\"";
|
||||
cmd += host;
|
||||
cmd += "\",";
|
||||
cmd += port;
|
||||
cmd.toCharArray(replybuffer, REPLYBUFFSIZ);
|
||||
|
||||
getReply(replybuffer);
|
||||
|
||||
if (strcmp(replybuffer, "OK") != 0) {
|
||||
// this is OK! could be a version that says "Linked"
|
||||
if (strcmp(replybuffer, "Linked") != 0) {
|
||||
sendCheckReply("AT+CIPCLOSE", "OK");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
String request = "GET ";
|
||||
request += page;
|
||||
request += " HTTP/1.1\r\nHost: ";
|
||||
request += host;
|
||||
request += "\r\n\r\n";
|
||||
|
||||
cmd = "AT+CIPSEND=";
|
||||
cmd += request.length();
|
||||
cmd.toCharArray(replybuffer, REPLYBUFFSIZ);
|
||||
sendCheckReply(replybuffer, ">");
|
||||
|
||||
Serial.print("Sending: "); Serial.println(request.length());
|
||||
Serial.println(F("*********SENDING*********"));
|
||||
Serial.print(request);
|
||||
Serial.println(F("*************************"));
|
||||
|
||||
request.toCharArray(replybuffer, REPLYBUFFSIZ);
|
||||
|
||||
esp->println(request);
|
||||
|
||||
while (true) {
|
||||
espreadline(3000); // this is the 'echo' from the data
|
||||
Serial.print(">"); Serial.println(replybuffer); // probably the 'busy s...'
|
||||
|
||||
// LOOK AT ALL THESE POSSIBLE ARBITRARY RESPONSES!!!
|
||||
if (strstr(replybuffer, "wrong syntax"))
|
||||
continue;
|
||||
else if (strstr(replybuffer, "ERROR"))
|
||||
continue;
|
||||
else if (strstr(replybuffer, "busy s..."))
|
||||
continue;
|
||||
else break;
|
||||
}
|
||||
|
||||
if (! strstr(replybuffer, "SEND OK") ) return false;
|
||||
|
||||
espreadline(1000); Serial.print("3>"); Serial.println(replybuffer);
|
||||
char *s = strstr(replybuffer, "+IPD,");
|
||||
if (!s) return false;
|
||||
uint16_t len = atoi(s+5);
|
||||
//Serial.print(len); Serial.println(" bytes total");
|
||||
|
||||
int16_t contentlen = 0;
|
||||
while (1) {
|
||||
espreadline(50);
|
||||
s = strstr(replybuffer, "Content-Length: ");
|
||||
if (s) {
|
||||
//Serial.println(replybuffer);
|
||||
contentlen = atoi(s+16);
|
||||
Serial.print(F("C-Len = ")); Serial.println(contentlen);
|
||||
}
|
||||
s = strstr(replybuffer, "Content-Type: ");
|
||||
if (s && contentlen) {
|
||||
int16_t i;
|
||||
char c;
|
||||
|
||||
for (i=-2; i<contentlen; i++) { // eat the first 2 chars (\n\r)
|
||||
while (!esp->available());
|
||||
c = esp->read(); //UDR0 = c;
|
||||
if (i >= 0) {
|
||||
replybuffer[i] = c;
|
||||
}
|
||||
}
|
||||
replybuffer[i] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//while (1) {
|
||||
// if (esp.available()) UDR0 = esp.read();
|
||||
//}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
ESP_GETpage(HOST, 80, WEBPAGE);
|
||||
|
||||
Serial.println(F("**********REPLY***********"));
|
||||
Serial.print(replybuffer);
|
||||
Serial.println(F("**************************"));
|
||||
|
||||
sendCheckReply("AT+CIPCLOSE", "OK");
|
||||
|
||||
debugLoop();
|
||||
|
||||
delay(1000);
|
||||
|
||||
while (1);
|
||||
|
||||
}
|
||||
|
||||
boolean getVersion() {
|
||||
// Get version?
|
||||
getReply("AT+GMR", 250, true);
|
||||
}
|
||||
|
||||
boolean espReset() {
|
||||
getReply("AT+RST", 1000, true);
|
||||
if (! strstr(replybuffer, "OK")) return false;
|
||||
delay(2000);
|
||||
|
||||
// turn off echo
|
||||
getReply("ATE0", 250, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean ESPconnectAP(char *s, char *p) {
|
||||
|
||||
getReply("AT+CWMODE=1", 500, true);
|
||||
if (! (strstr(replybuffer, "OK") || strstr(replybuffer, "no change")) )
|
||||
return false;
|
||||
|
||||
String connectStr = "AT+CWJAP=\"";
|
||||
connectStr += SSID;
|
||||
connectStr += "\",\"";
|
||||
connectStr += PASS;
|
||||
connectStr += "\"";
|
||||
connectStr.toCharArray(replybuffer, REPLYBUFFSIZ);
|
||||
getReply(replybuffer, 500, true);
|
||||
espreadline(5000);
|
||||
Serial.print("<-- "); Serial.println(replybuffer);
|
||||
|
||||
return (strstr(replybuffer, "OK") != 0);
|
||||
}
|
||||
|
||||
|
||||
byte setupWiFi() {
|
||||
// reset WiFi module
|
||||
Serial.println(F("Soft resetting..."));
|
||||
if (!espReset())
|
||||
return WIFI_ERROR_RST;
|
||||
|
||||
delay(1000);
|
||||
|
||||
Serial.println(F("Checking for ESP AT response"));
|
||||
|
||||
if (!sendCheckReply("AT", "OK"))
|
||||
return WIFI_ERROR_AT;
|
||||
|
||||
getVersion();
|
||||
Serial.print(F("Firmware Version #")); Serial.println(replybuffer);
|
||||
|
||||
Serial.print(F("Connecting to ")); Serial.println(SSID);
|
||||
if (!ESPconnectAP(SSID, PASS))
|
||||
return WIFI_ERROR_SSIDPWD;
|
||||
|
||||
Serial.println(F("Single Client Mode"));
|
||||
if (!sendCheckReply("AT+CIPMUX=0", "OK"))
|
||||
return WIFI_ERROR_SERVER;
|
||||
|
||||
return WIFI_ERROR_NONE;
|
||||
}
|
||||
|
||||
// NOT IMPLEMENTED YET!
|
||||
uint32_t getIP() {
|
||||
getReply("AT+CIFSR", 500, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/************************/
|
||||
uint8_t espreadline(uint16_t timeout, boolean multiline) {
|
||||
uint16_t replyidx = 0;
|
||||
|
||||
while (timeout--) {
|
||||
if (replyidx > REPLYBUFFSIZ-1) break;
|
||||
|
||||
while(esp->available()) {
|
||||
char c = esp->read();
|
||||
if (c == '\r') continue;
|
||||
if (c == 0xA) {
|
||||
if (replyidx == 0) // the first 0x0A is ignored
|
||||
continue;
|
||||
|
||||
if (!multiline) {
|
||||
timeout = 0; // the second 0x0A is the end of the line
|
||||
break;
|
||||
}
|
||||
}
|
||||
replybuffer[replyidx] = c;
|
||||
// Serial.print(c, HEX); Serial.print("#"); Serial.println(c);
|
||||
replyidx++;
|
||||
}
|
||||
|
||||
if (timeout == 0) break;
|
||||
delay(1);
|
||||
}
|
||||
replybuffer[replyidx] = 0; // null term
|
||||
return replyidx;
|
||||
}
|
||||
|
||||
uint8_t getReply(char *send, uint16_t timeout, boolean echo) {
|
||||
// flush input
|
||||
while(esp->available()) {
|
||||
esp->read();
|
||||
}
|
||||
|
||||
if (echo) {
|
||||
Serial.print("---> "); Serial.println(send);
|
||||
}
|
||||
esp->println(send);
|
||||
|
||||
// eat first reply sentence (echo)
|
||||
uint8_t readlen = espreadline(timeout);
|
||||
|
||||
//Serial.print("echo? "); Serial.print(readlen); Serial.print(" vs "); Serial.println(strlen(send));
|
||||
|
||||
if (strncmp(send, replybuffer, readlen) == 0) {
|
||||
// its an echo, read another line!
|
||||
readlen = espreadline();
|
||||
}
|
||||
|
||||
if (echo) {
|
||||
Serial.print ("<--- "); Serial.println(replybuffer);
|
||||
}
|
||||
return readlen;
|
||||
}
|
||||
|
||||
boolean sendCheckReply(char *send, char *reply, uint16_t timeout) {
|
||||
getReply(send, timeout, true);
|
||||
|
||||
/*
|
||||
for (uint8_t i=0; i<strlen(replybuffer); i++) {
|
||||
Serial.print(replybuffer[i], HEX); Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
for (uint8_t i=0; i<strlen(reply); i++) {
|
||||
Serial.print(reply[i], HEX); Serial.print(" ");
|
||||
}
|
||||
Serial.println();
|
||||
*/
|
||||
return (strcmp(replybuffer, reply) == 0);
|
||||
}
|
||||
|
||||
void debugLoop() {
|
||||
Serial.println("========================");
|
||||
//serial loop mode for diag
|
||||
while(1) {
|
||||
if (Serial.available()) {
|
||||
esp->write(Serial.read());
|
||||
delay(1);
|
||||
}
|
||||
if (esp->available()) {
|
||||
Serial.write(esp->read());
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user