Веб-сервер ESP8266 не отвечает при запуске функции HTTP-запроса
Я пытаюсь создать что-то, что может управлять шаговым двигателем на основе информации о погоде из openweathermap. Я настроил веб-сервер ESP8266 для ручного управления движением двигателя с помощью кнопок и настроил структуру для взаимодействия с API openweathermap для получения нужной мне информации (пока печатаю их на серийный монитор для тестирования).
Однако, когда я объединил две вещи, они сломались. Текущий код позволяет мне отлично получать информацию о погоде, но я больше не могу подключиться к своему веб-серверу, работающему в режиме STA. Что-то в функции getWeather()
мешает работе веб-сервера, потому что если я удалю getWeather()
из своего цикла, веб-сервер заработает.
Есть идеи, что я делаю неправильно?
#include <SPI.h>
#include <AccelStepper.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h> // библиотека веб-доступа по http
#include <ArduinoJson.h> // библиотека декодирования JSON
// Определяем соединения шагового двигателя и тип интерфейса двигателя. Тип интерфейса двигателя должен быть установлен на 1 при использовании драйвера:
#define dirPin 5
#define stepPin 4
#define motorInterfaceType 1
bool motorStop;
bool motorCW;
bool motorCCW;
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
//Поместите свой SSID & Пароль
const char* ssid = "[ssid]"; // Введите SSID здесь
const char* password = "[password]"; //Введите пароль здесь
//Ключ API OpenWeatherMap
String apiKey= "[apikey]";
//Местоположение OpenWeatherMap
String location= "lat=37.30&lon=-121.91";
String unit= "metric";
const unsigned long postingInterval = 1000*60*60; // задержка между обновлениями в миллисекундах
WiFiClient client;
ESP8266WebServer server(80);
// Установите свой статический IP-адрес
IPAddress local_IP(192, 168, 86, 248);
// Установите IP-адрес вашего шлюза
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);
// Настраивает статический IP-адрес
if (!WiFi.config(local_IP, gateway, subnet,primaryDNS)) {
Serial.println("STA Failed to configure");
}
stepper.setMaxSpeed(1000);
Serial.println("Connecting to ");
Serial.println(ssid);
//подключаемся к вашей локальной сети wi-fi
WiFi.begin(ssid, password);
//проверяем, подключен ли wi-fi к сети wi-fi
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
//Выводим информацию о соединении
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);}
// Шаг мотора с постоянной скоростью, заданной setSpeed():
stepper.runSpeed();
getWeather();
}
void getWeather()
{
// если есть успешное соединение:
if (client.connect("api.openweathermap.org", 80))
{
Serial.println("connected");
// отправляем HTTP-запрос PUT:
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"]; // "Америка/Лос-Анджелес"
int timezone_offset = doc["timezone_offset"]; // -25200
JsonArray daily = doc["daily"];
// завтрашний прогноз (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"]; // "Очистить"
const char* daily_1_weather_0_description = daily_1_weather_0["description"]; // "чистое небо"
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
// распечатать информацию о погоде
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
{
// если не удалось установить соединение:
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;
}
@user2201584, 👍0
1 ответ
Лучший ответ:
В конце getWeather()
вы вызываете delay(postingInterval);
postingInterval
установлено значение 60*60*1000
... один час. Это означает, что getWeather()
не вернется в течение одного часа, и в течение этого времени ничего в loop()
не будет обрабатываться, включая веб-сервер.
Вам нужно удалить этот вызов delay()
и переписать свой цикл, чтобы проверить, прошло ли миллисекунды postingInterval
, и вызывать только getWeather()
если они есть.
- Esp8266 - server.handleClient() не может вызвать назначенную функцию
- MCU узла Esp12-E не поддерживает функцию приема сервером
- Как заставить 5-вольтовое реле работать с NodeMCU
- ESP8266 не подключается к Wi-Fi
- Разница между этими двумя платами NodeMCU?
- NodeMCU - использовать кнопку flash в качестве входного сигнала в loop()
- Как определить размер Flash?
- Как изменить имя модуля ESP8266-12E по умолчанию
Спасибо, это работает! Однако теперь появилась новая проблема. Я использую
millis()
в своем цикле для вызоваgetWeather()
. Однако «интервал» повлияет на работу степпера. Предполагается, что stepper.runSpeed() заставляет степпер работать непрерывно в заданном направлении; но теперь степпер будет останавливаться на «интервале»., @user2201584Отлично, рад, что помог. Новая проблема звучит как хорошая вещь, чтобы опубликовать ее как новый вопрос; тогда вы привлечете внимание многих людей, которые могут ответить на него и не увидеть его здесь в качестве комментария :), @romkey
Сделаю. Благодарю вас!, @user2201584