I am trying to build something that can control a stepper motor based on weather information from openweathermap. I've set up a ESP8266 webserver to manually control motor movement with buttons and I have set up the structure to talk to openweathermap API to get the information I want (printing them to serial monitor for now for testing).
However, when I combined the 2 things break. The current code allows me to get weather perfectly but I can no longer connect to my web server running in STA mode. Something in the getWeather()
function is messing with the web server because if I remove getWeather()
from my loop the web server works.
Any idea what I am doing wrong here?
#include <SPI.h>
#include <AccelStepper.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h> // http web access library
#include <ArduinoJson.h> // JSON decoding library
// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 5
#define stepPin 4
#define motorInterfaceType 1
bool motorStop;
bool motorCW;
bool motorCCW;
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
//Put your SSID & Password
const char* ssid = "[ssid]"; // Enter SSID here
const char* password = "[password]"; //Enter Password here
//OpenWeatherMap API key
String apiKey= "[apikey]";
//OpenWeatherMap location
String location= "lat=37.30&lon=-121.91";
String unit= "metric";
const unsigned long postingInterval = 1000*60*60; // delay between updates, in milliseconds
WiFiClient client;
ESP8266WebServer server(80);
// Set your Static IP address
IPAddress local_IP(192, 168, 86, 248);
// Set your Gateway IP address
IPAddress gateway(192, 168, 86, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(192, 168, 86, 1);
void setup() {
Serial.begin(9600);
delay(100);
// Configures static IP address
if (!WiFi.config(local_IP, gateway, subnet,primaryDNS)) {
Serial.println("STA Failed to configure");
}
stepper.setMaxSpeed(1000);
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
//Print out connection info
Serial.println("");
Serial.println("WiFi connected..!");
server.on("/", handle_OnConnect);
server.on("/cw_on", handle_CW_on);
server.on("/cw_off", handle_CW_off);
server.on("/ccw_on", handle_CCW_on);
server.on("/ccw_off", handle_CCW_off);
server.on("/mstop", handle_stop);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
if(motorStop)
{stepper.setSpeed(0);}
if(motorCW)
{stepper.setSpeed(400);}
if(motorCCW)
{stepper.setSpeed(-400);}
// Step the motor with a constant speed as set by setSpeed():
stepper.runSpeed();
getWeather();
}
void getWeather()
{
// if there's a successful connection:
if (client.connect("api.openweathermap.org", 80))
{
Serial.println("connected");
// send the HTTP PUT request:
client.println("GET /data/2.5/onecall?" + location + "&exclude=current,minutely,hourly" + "&appid=" + apiKey);
client.println("Host: api.openweathermap.org");
client.println("Connection: close");
client.println();
const size_t capacity = 8*JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(8) + 16*JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 8*JSON_OBJECT_SIZE(6) + 8*JSON_OBJECT_SIZE(14) + 1810;
DynamicJsonDocument doc(capacity);
deserializeJson(doc, client);
float lat = doc["lat"]; // 37.3
float lon = doc["lon"]; // -121.91
const char* timezone = doc["timezone"]; // "America/Los_Angeles"
int timezone_offset = doc["timezone_offset"]; // -25200
JsonArray daily = doc["daily"];
// tomorrow's forecast (daily_1)
JsonObject daily_1 = daily[1];
long daily_1_dt = daily_1["dt"]; // 1596225600
long daily_1_sunrise = daily_1["sunrise"]; // 1596201109
long daily_1_sunset = daily_1["sunset"]; // 1596251761
JsonObject daily_1_temp = daily_1["temp"];
float daily_1_temp_day = daily_1_temp["day"]; // 306.61
float daily_1_temp_min = daily_1_temp["min"]; // 288.67
float daily_1_temp_max = daily_1_temp["max"]; // 306.61
float daily_1_temp_night = daily_1_temp["night"]; // 288.67
float daily_1_temp_eve = daily_1_temp["eve"]; // 295.94
float daily_1_temp_morn = daily_1_temp["morn"]; // 293.26
JsonObject daily_1_feels_like = daily_1["feels_like"];
int daily_1_feels_like_day = daily_1_feels_like["day"]; // 303.31
float daily_1_feels_like_night = daily_1_feels_like["night"]; // 287.59
float daily_1_feels_like_eve = daily_1_feels_like["eve"]; // 293.77
float daily_1_feels_like_morn = daily_1_feels_like["morn"]; // 292.42
int daily_1_pressure = daily_1["pressure"]; // 1015
int daily_1_humidity = daily_1["humidity"]; // 17
float daily_1_dew_point = daily_1["dew_point"]; // 278.68
float daily_1_wind_speed = daily_1["wind_speed"]; // 3.12
int daily_1_wind_deg = daily_1["wind_deg"]; // 318
JsonObject daily_1_weather_0 = daily_1["weather"][0];
int daily_1_weather_0_id = daily_1_weather_0["id"]; // 800
const char* daily_1_weather_0_main = daily_1_weather_0["main"]; // "Clear"
const char* daily_1_weather_0_description = daily_1_weather_0["description"]; // "clear sky"
const char* daily_1_weather_0_icon = daily_1_weather_0["icon"]; // "01d"
int daily_1_clouds = daily_1["clouds"]; // 0
int daily_1_pop = daily_1["pop"]; // 0
float daily_1_uvi = daily_1["uvi"]; // 9.53
// print out weather information
Serial.print("Tomorrow's Forecast");
Serial.print("Temperature: ");
Serial.println(daily_1_feels_like_day);
Serial.print("Weather: ");
Serial.println(daily_1_weather_0_main);
delay (postingInterval);
}
else
{
// if you couldn't make a connection:
Serial.println("connection failed");
delay (postingInterval);
}
}
void handle_OnConnect() {
motorStop = HIGH;
motorCW = LOW;
motorCCW = LOW;
Serial.println("Motor: Stopped");
server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}
void handle_CW_on() {
motorStop = LOW;
motorCW = HIGH;
motorCCW = LOW;
Serial.println("Motor: Running Clock-wise");
server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}
void handle_CW_off() {
motorStop = HIGH;
motorCW = LOW;
motorCCW = LOW;
Serial.println("Motor: Stopped");
server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}
void handle_CCW_on() {
motorStop = LOW;
motorCW = LOW;
motorCCW = HIGH;
Serial.println("Motor: Motor: Running Counter Clock-wise");
server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}
void handle_CCW_off() {
motorStop = HIGH;
motorCW = LOW;
motorCCW = LOW;
Serial.println("Motor: Stopped");
server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}
void handle_stop() {
motorStop = HIGH;
motorCW = LOW;
motorCCW = LOW;
Serial.println("Motor: Stopped");
server.send(200, "text/html", SendHTML(motorStop, motorCW, motorCCW));
}
void handle_NotFound(){
server.send(404, "text/plain", "Not found");
}
String SendHTML(uint8_t mstop,uint8_t cw, uint8_t ccw){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>LED Control</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
ptr +=".button {display: block;width: 80px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
ptr +=".button-cw {background-color: #1abc9c;}\n";
ptr +=".button-cw:active {background-color: #16a085;}\n";
ptr +=".button-ccw {background-color: #34495e;}\n";
ptr +=".button-ccw:active {background-color: #2c3e50;}\n";
ptr +=".button-mstop {background-color: #34495e;}\n";
ptr +=".button-mstop:active {background-color: #2c3e50;}\n";
ptr +="p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<h1>Weather Station</h1>\n";
ptr +="<h3>Runs either direction continuously</h3>\n";
if(cw)
{ptr +="<p>Motor running Clock-wise</p><a class=\"button button-off\" href=\"/cw_off\">Stop</a>\n";}
else
{ptr +="<p>Motor not running Clock-wise</p><a class=\"button button-on\" href=\"/cw_on\">Run</a>\n";}
if(ccw)
{ptr +="<p>Motor running Counter Clock-wise</p><a class=\"button button-off\" href=\"/ccw_off\">Stop</a>\n";}
else
{ptr +="<p>Motor not running Counter Clock-wise</p><a class=\"button button-on\" href=\"/ccw_on\">Run</a>\n";}
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}