Well, I have something that works, and it seems to be simpler than most other client/server examples I have seen. I'd appreciate any suggestions on how to tidy things up, or other approaches that could simplify things further.
The debugging section is extremely limited at the moment, however in future projects I will have more information to display - this example just shows that the client and server functionality works together. I have commented as much as I understand so that hopefully it's crystal clear what's going on.
One thing I found that may have been an ongoing issue was that connecting to Thingspeak was successful only when the IP address was used - the name "api.thingspeak.com" and variations of that failed.
Hope this helps someone else,
Ewan (dukbilt)
/* Server and Client functionality for ESP8266
Sends data to Thingspeak and also shows sent data and response on a web page hosted on
the ESP8266 for local information to aid in debugging.
Version: 1.0 (07 Jul 16)
Hardware: ESP8266 module (specifically the Sparkfun ESP8266 Thing)
IDE: Arduino 1.6.9
Author: Ewan Regazzo */
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
// WiFi Definitions
#define SSID "myssid" // WiFi SSID
#define PSK "mypassword" // WiFi password
// Thingspeak definitions
#define SERVER "184.106.153.149" // Thingspeak server address (don't use 'api.thingspeak.com' - it doesn't work)
#define PORT 80 // Thingspeak port
#define API "myapiwritekey" // Thingspeak 'Write' key for this channel
/* NOTE 1 - The instance of ESP8266WebServer called 'server' uses port 81.
Port 81 must be used as Thingspeak uses port 80, so the web server by typing
XXX.XXX.XXX.XXX:81 into your browser window where XXX.XXX.XXX.XXX is the IP
address of the ESP8266 - ie, '192.168.0.5:81'
The '#include <ESP8266WebServer.h>' statement at the top of this code is
essential in allowing the 'server' instance to be created.*/
ESP8266WebServer server(81); // Create instance of ESP8266WebServer called 'server' using port 81 (see note 1 above)
WiFiClient client; // Create an instance of WiFiClient called 'client'
// Global variables (usable by all functions)
int x = 0; // Simple counter to show that something changes
String message; // The information needed to update Thingspeak is kept in a string called 'message'
String response; // Holds the response information from Thingspeak after data has been sent
// The 'setup' function is called at startup only and sets up the ESP8266
void setup()
{
WiFi.begin(SSID, PSK); // Begin the WiFi connection using SSID and PSK definitions
// Pause for 0.5 seconds while WiFi is NOT connected
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
}
// we've gotten to here so WiFi must now be connected
// Set up the web server
server.on("/", handleRoot); // If a client accesses the root page ('/') then process the 'handleRoot' function
server.begin(); // Start the server
}
// The main function that does everything.
void loop()
{
createData(); // Make the data message
server.handleClient(); // Take care of any client that accesses the web server
sendData(); // send data to Thingspeak
delay(5000); // Have a break
}
// This function takes care of a client accessing the root web server page
void handleRoot()
{
server.send(200, "text/plain", (message + "\n" + response)); // send a message to the web server
}
// This function sets the ESP8266 as a client to an external server (Thingspeak), sends data,
// and receives a response
void sendData()
{
if (client.connect(SERVER, PORT)) // If a successful connection occurs, then...
{
client.println(message); // ... send the information
}
if (client.connected()) // If we have connected...
{
response = client.read(); // ... read the response from the server
if (response == "48") // string value of "48" equals char '0' - which means data received ok
{
x ++; // increment x by 1 (just to show that something happened)
}
}
client.stop(); // We don't want the client to maintain a constant connection
}
// This function creates a simple GET message string to update Thingspeak
void createData()
{
message = "GET /update?api_key=";
message += API;
message += "&field1=";
message += x;
}