Jump to content
iT4iT.CLUB
Kitsum

esp8266 и парсинг погоды с OpenWeatherMap

Recommended Posts

Всем доброго времени суток, сегодня поговорим о esp8266 и парсинге погоды с интернета. Это довольно интересная альтернатива метеостанции описанной в параллельной теме и думаю, что первый пост стоит посвятить базовой программе - своего рода фундаменту, на базе которого можно производить дальнейшие модификации от подключения дисплея до прикручивания MQTT протокола для системы умного дома.

О самом проекте OpenWeatherMap много написано в сети, но я познакомился с ним недавно, как и с микроконтроллером esp8266 который мы будем программировать в доработанной среде Arduino IDE. Но перед тем как начать, необходимо посетить сайт, с которого мы будем вытаскивать данные об окружающей среде.

И так, OpenWeatherMap предоставляет нам удобный и бесплатный API. На момент публикации статьи (05.2016) мы можем:

  • Производить не более 60 запросов в минуту
  • Не более 50000 запросов в день
  • Два типа прогноза (на 5 и на 16 дней)
  • Доступность сервиса 95%
  • Интервал обновление данных < 2 часов

Отлично, нас все устраивает. Регистрируемся и в личном кабинете переходим в раздел API Keys. По умолчанию нам уже дадут один ключ, можно воспользоваться им, а можно создать новый и обозвать его более понятным именем. Это довольно актуально, если планируется использовать несколько устройств, да и вообще должен быть порядок везде.

esp-owm1.png

Без данного ключа получить доступ к API невозможно.

Осталось определиться с интересующей нас местностью. API гласит, что есть несколько вариантов:

  • По названию города и коду страны
  • По уникальному идентификатору города
  • По географическим координатам
  • По почтовому индексу

Мне показалось удобным использовать географические координаты. При этом сервер сам найдет ближайший населенный пункт, а по сути, ближайшую метеостанцию и предоставит данные с неё.

esp-owm2.png

Данные по необходимым для Вас координатам можно взять прямо с сайта, воспользовавшись любезно предоставленной картой. При выборе населенного пункта долгота и широта будут указаны в описании.

Список всех доступных населенных пунктов можно найти тут http://openweathermap.org/help/city_list.txt

Теперь переходим к самому интересному - скетч. В начале поста я оставил ссылку на ресурс, подробно описывающий все процедуры необходимые, чтобы завести контроллер и использовать Arduino IDE для прошивки. Но я пошел еще более простым путем и приобрел ESP-12E с обвесом под NodeMCU, это позволило прошивать контроллер без нажатия кнопок RESET и FLASH.

esp-owm3.jpg

Получать данные от сервера можно в двух форматах, XML и JSON. Последний мне показался более предпочтительным и в связи с этим нам понадобится библиотека ArduinoJson

Программа

Скрытый текст

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

const char* ssid     = "WiFi AP name";
const char* password = "WiFi AP password";
const String server  = "api.openweathermap.org";
const String lat     = "51.31";
const String lon     = "37.89";
const String appid   = "b1f6b0a1ea9e10feb04eb3a2de2ad2b9";
const String url     = "http://" + server + "/data/2.5/weather?lat=" + lat + "&lon=" + lon + "&units=metric&appid=" + appid;

unsigned long lastConnectionTime = 0;
unsigned long postingInterval = 0;

String httpData;

struct weather_structure {
  unsigned int id;
  const char* main;
  const char* icon;
  const char* descript;
  float temp;
  float pressure;
  byte  humidity;
  float speed;
  float deg;
};
weather_structure weather;

void setup() {
  Serial.begin(115200);
  Serial.print("\nConnecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nWiFi connected\nIP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();
}

void loop() {
  if (WiFi.status() == WL_CONNECTED) {
    if (millis() < lastConnectionTime) lastConnectionTime = 0;
    if (millis() - lastConnectionTime > postingInterval or lastConnectionTime == 0) {
      if (httpRequest() and parseData()) {
        Serial.println("\nWeather");
        Serial.printf("id: %d\n", weather.id);
        Serial.printf("main: %s\n", weather.main);
        Serial.printf("description: %s\n", weather.descript);
        Serial.printf("icon: %s\n", weather.icon);
        Serial.printf("temp: %d celsius\n", round(weather.temp));
        Serial.printf("humidity: %d %\n", round(weather.humidity));
        Serial.printf("pressure: %d hPa or %d mmHg\n", round(weather.pressure), round(weather.pressure * 0.75));
        Serial.printf("wind's speed: %d\n", round(weather.speed));
        Serial.printf("wind's direction: %d\n", round(weather.deg));
        Serial.println();
      }
    }
  }
}

bool httpRequest() {
  HTTPClient client;
  bool find = false;
  //client.setTimeout(1000);
  Serial.print("Connecting ");
  client.begin(url);
  int httpCode = client.GET();

  if (httpCode > 0) {
    Serial.printf("successfully, code: %d\n", httpCode);
    if (httpCode == HTTP_CODE_OK) {
      httpData = client.getString();
      if (httpData.indexOf(F("\"main\":{\"temp\":")) > -1) {
        lastConnectionTime = millis();
        find = true;
      }
      else Serial.println("Failed, json string is not found");
    }
  }
  else Serial.printf("failed, error: %s\n", client.errorToString(httpCode).c_str());

  postingInterval = find ? 600L * 1000L : 60L * 1000L;
  client.end();

  return find;
}

bool parseData() {
  Serial.println(httpData);

  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(httpData);

  if (!root.success()) {
    Serial.println("Json parsing failed!");
    return false;
  }

  weather.id       = root["weather"][0]["id"];
  weather.main     = root["weather"][0]["main"];
  weather.descript = root["weather"][0]["description"];
  weather.icon     = root["weather"][0]["icon"];
  weather.temp     = root["main"]["temp"];
  weather.humidity = root["main"]["humidity"];
  weather.pressure = root["main"]["pressure"];
  weather.speed    = root["wind"]["speed"];
  weather.deg      = root["wind"]["deg"];

  httpData = "";
  return true;
}

 

Все, что нам нужно редактировать, это начальные переменные (ключ указан рабочий, но это все временно)

const char* ssid     = "WiFi AP name";
const char* password = "WiFi AP password";
const String server  = "api.openweathermap.org";
const String lat     = "51.31";
const String lon     = "37.89";
const String appid   = "b1f6b0a1ea9e10feb04eb3a2de2ad2b9";

По умолчанию программа производит запрос информации с сервера каждые 10 минут, но если что-то пойдет не так и информация не будет получена, то интервал уменьшится до 1 минуты, а при ближайшем удачном подключении вернется обратно.

И так, на данный момент мы собираем:

  • weather.id - Идентификатор погодных условий (будет полезен, см. отсылку с weather.icon)
  • weather.main - Группа метеорологических параметров
  • weather.descript - Описание погодных условий в группе
  • weather.icon - Идентификатор иконки (подробнее ознакомиться с ними можно тут)
  • weather.temp - Текущая температура в градусах Цельсия
  • weather.humidity - Текущая влажность в %
  • weather.pressure - Текущее давление (по умолчанию сервер отдает её в hPa, но при умножении на 0,75 мы получаем mmHg)
  • weather.speed - Скорость ветра метры/сек.
  • weather.deg - Направление ветра в градусах

Выглядит это следующим образом

Connecting to Lenovo S90
......
WiFi connected
IP address: 
10.10.1.243

Connecting successfully, code: 200
{"coord":{"lon":37.84,"lat":51.3},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03d"}],"base":"cmc stations","main":{"temp":18.24,"pressure":996.52,"humidity":92,"temp_min":18.24,"temp_max":18.24,"sea_level":1021.77,"grnd_level":996.52},"wind":{"speed":2.01,"deg":30.5008},"clouds":{"all":48},"dt":1464076525,"sys":{"message":0.0025,"country":"RU","sunrise":1464053115,"sunset":1464110798},"id":487928,"name":"Staryy Oskol","cod":200}


Weather
id: 802
main: Clouds
description: scattered clouds
icon: 03d
temp: 18 celsius
humidity: 92 %
pressure: 997 hPa or 747 mmHg
wind's speed: 2
wind's direction: 31

Как оказалось, ничего сложного в реализации задуманного не было, но местами пришлось повозиться. Думаю, что это будет хорошей отправной точкой для дальнейшего развития проекта.

  • Like 1

Share this post


Link to post
Share on other sites

я 07 ту что с внешней антенкой прошил так. 

scheme.jpg

 

 

Edited by svchekalin
канденсатор не той емкасти
  • Like 1

Share this post


Link to post
Share on other sites

Программа отличная! А как можно привязать к нему LCD I2C 20x4 для вывода данных?

с уважением, Ale[ander.

Share this post


Link to post
Share on other sites

@Alexander Воспользуйтесь библиотекой LiquidCrystal_I2C

Чтобы вывести что-то на дисплей имеются стандартные функции

lcd.setCursor(0,2);       // Выставить позицию
lcd.print(weather.temp);  // Вывести температуру

 

Share this post


Link to post
Share on other sites

@Kitsum А если сервер в ответ присылает строку вот такого вида  -  hostname:192.169.0.103;dhtt1:61.0;dhth1:30.0;dsw1:-3.0;  её с помощью ArduinoJson разобрать не получиться.?!

Share this post


Link to post
Share on other sites

@EndWar формат json имеет строгий синтаксис. Отталкиваясь от этого, Ваша строка должна иметь следующий вид

{"hostname":"192.169.0.103","dhtt1":61,"dhth1":30,"dsw1":-3}

 

Share this post


Link to post
Share on other sites

Не подскажете, что нужно изменить дабы запрос информации с сервера производился не каждые 10 мин, а каждый час?

 

Share this post


Link to post
Share on other sites

@В К Найдите строку

postingInterval = find ? 600L * 1000L : 60L * 1000L;

и замените ее на

postingInterval = find ? 3600L * 1000L : 60L * 1000L;

 

Share this post


Link to post
Share on other sites

спасибо большое за Ваш код. Скопировал себе, поменял настройки WiFi, координаты и API ключ, прошил, но в ответ получил Connecting successfully, code 401. Что это означает? 

image.png

Share this post


Link to post
Share on other sites

Доброе время суток.

@Же ка Ваша проблема скорее всего связана с ошибочным значением в переменной appid. Возможно опечатка или Вы не прошли до конца процесс получения ключа. Проверьте все еще раз.

Таблицу с кодами ответов можно посмотреть тут https://ru.wikipedia.org/wiki/Список_кодов_состояния_HTTP#401

А вот тестовый пример для проверки API.

https://samples.openweathermap.org/data/2.5/weather?lat=35&amp;lon=139&amp;appid=b6907d289e10d714a6e88b30761fae22

Share this post


Link to post
Share on other sites

добрый день! Спасибо автору за его работу! но есть вопрос. после конекта к серверу получаем ответ в строке все ок. а ниже данных нет...

20:17:03.961 -> Connecting failed, error: connection refused
20:17:09.148 -> Connecting successfully, code: 200
20:17:09.353 -> {"coord":{"lon":37.89,"lat":51.31},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"model","main":{"temp":-11.22,"feels_like":-16.93,"temp_min":-11.22,"temp_max":-11.22,"pressure":1026,"humidity":83,"sea_level":1026,"grnd_level":999},"wind":{"speed":3.46,"deg":12},"clouds":{"all":9},"dt":1581182214,"sys":{"country":"RU","sunrise":1581137765,"sunset":1581172150},"timezone":10800,"id":487928,"name":"Staryy Oskol","cod":200}
20:17:09.386 -> 
20:17:09.386 -> Weather
20:17:09.386 -> id: 800
20:17:09.386 -> main: Clear
20:17:09.386 -> description: clear sky
20:17:09.386 -> icon: 01n
20:17:09.386 -> temp: 0 celsius
20:17:09.386 -> humidity: 0 
20:17:09.386 -> pressure: 0 hPa or 1083181056 mmHg
20:17:09.386 -> wind's direction: 0
20:17:09.386 -> 

 

Share this post


Link to post
Share on other sites

так работает

        Serial.println("temp:"); Serial.println(weather.temp);
        Serial.println("humidity %:"); Serial.println(weather.humidity);
        Serial.println("pressure hPa:"); Serial.println(weather.pressure);
        Serial.println("pressure mmHg:"); Serial.println(weather.pressure * 0.75);
        Serial.println("wind's speed m/s:"); Serial.println(weather.speed);
        Serial.println("wind's direction:"); Serial.println(weather.deg);

а так нет

		Serial.printf("temp: %d celsius\n", round(weather.temp));
        Serial.printf("humidity: %d %\n", round(weather.humidity));
        Serial.printf("pressure: %d hPa or %d mmHg\n", round(weather.pressure), round(weather.pressure * 0.75));
        Serial.printf("wind's speed: %d\n", round(weather.speed));
        Serial.printf("wind's direction: %d\n", round(weather.deg));
    

 

Share this post


Link to post
Share on other sites
{"cod":"200","message":0,"cnt":40,"list":[{"dt":1586379600,"main":{"temp":5.05,"feels_like":1.37,"temp_min":3.49,"temp_max":5.05,"pressure":1020,"sea_level":1020,"grnd_level":999,"humidity":83,"temp_kf":1.56},"weather":[{"id":800,"main":"Clear","description":"ясно","icon":"01n"}],"clouds":{"all":2},"wind":{"speed":2.96,"deg":322},"sys":{"pod":"n"},"dt_txt":"2020-04-08 21:00:00"},{"dt":1586390400,"main":{"temp":3.26,"feels_like":-0.12,"temp_min":2.09,"temp_max":3.26,"pressure":1020,"sea_level":1020,"grnd_level":999,"humidity":86,"temp_kf":1.17},"weather":[{"id":800,"main":"Clear","description":"ясно","icon":"01n"}],"clouds":{"all":1},"wind":{"speed":2.24,"deg":305},"sys":{"pod":"n"},"dt_txt":"2020-04-09 00:00:00"},{"dt":1586401200,"main":{"temp":1.98,"feels_like":-1.59,"temp_min":1.2,"temp_max":1.98,"pressure":1019,"sea_level":1019,"grnd_level":999,"humidity":86,"temp_kf":0.78},"weather":[{"id":800,"main":"Clear","description":"ясно","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":2.24,"deg":249},"sys":{"pod":"d"},"dt_txt":"2020-04-09 03:00:00"},{"dt":1586412000,"main":{"temp":6.25,"feels_like":1.88,"temp_min":5.86,"temp_max":6.25,"pressure":1018,"sea_level":1018,"grnd_level":997,"humidity":70,"temp_kf":0.39},"weather":[{"id":800,"main":"Clear","description":"ясно","icon":"01d"}],"clouds":{"all":6},"wind":{"speed":3.67,"deg":236},"sys":{"pod":"d"},"dt_txt":"2020-04-09 06:00:00"},{"dt":1586422800,"main":{"temp":10.59,"feels_like":5.34,"temp_min":10.59,"temp_max":10.59,"pressure":1015,"sea_level":1015,"grnd_level":995,"humidity":54,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04d"}],"clouds":{"all":59},"wind":{"speed":5.03,"deg":240},"sys":{"pod":"d"},"dt_txt":"2020-04-09 09:00:00"},{"dt":1586433600,"main":{"temp":11.79,"feels_like":6.05,"temp_min":11.79,"temp_max":11.79,"pressure":1012,"sea_level":1012,"grnd_level":992,"humidity":50,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04d"}],"clouds":{"all":77},"wind":{"speed":5.74,"deg":229},"sys":{"pod":"d"},"dt_txt":"2020-04-09 12:00:00"},{"dt":1586444400,"main":{"temp":10.83,"feels_like":6.09,"temp_min":10.83,"temp_max":10.83,"pressure":1010,"sea_level":1010,"grnd_level":990,"humidity":55,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"пасмурно","icon":"04d"}],"clouds":{"all":100},"wind":{"speed":4.41,"deg":226},"sys":{"pod":"d"},"dt_txt":"2020-04-09 15:00:00"},{"dt":1586455200,"main":{"temp":8.54,"feels_like":3.79,"temp_min":8.54,"temp_max":8.54,"pressure":1008,"sea_level":1008,"grnd_level":988,"humidity":61,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"пасмурно","icon":"04n"}],"clouds":{"all":100},"wind":{"speed":4.26,"deg":225},"sys":{"pod":"n"},"dt_txt":"2020-04-09 18:00:00"},{"dt":1586466000,"main":{"temp":8.42,"feels_like":3.41,"temp_min":8.42,"temp_max":8.42,"pressure":1006,"sea_level":1006,"grnd_level":985,"humidity":69,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"небольшой дождь","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":5.03,"deg":223},"rain":{"3h":0.14},"sys":{"pod":"n"},"dt_txt":"2020-04-09 21:00:00"},{"dt":1586476800,"main":{"temp":7.52,"feels_like":3.57,"temp_min":7.52,"temp_max":7.52,"pressure":1005,"sea_level":1005,"grnd_level":985,"humidity":82,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"небольшой дождь","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":3.93,"deg":274},"rain":{"3h":1.3},"sys":{"pod":"n"},"dt_txt":"2020-04-10 00:00:00"},{"dt":1586487600,"main":{"temp":4.44,"feels_like":-0.78,"temp_min":4.44,"temp_max":4.44,"pressure":1006,"sea_level":1006,"grnd_level":986,"humidity":81,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"небольшой дождь","icon":"10d"}],"clouds":{"all":87},"wind":{"speed":4.94,"deg":320},"rain":{"3h":0.22},"sys":{"pod":"d"},"dt_txt":"2020-04-10 03:00:00"},{"dt":1586498400,"main":{"temp":5.18,"feels_like":-1.23,"temp_min":5.18,"temp_max":5.18,"pressure":1008,"sea_level":1008,"grnd_level":987,"humidity":63,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04d"}],"clouds":{"all":69},"wind":{"speed":6.06,"deg":327},"sys":{"pod":"d"},"dt_txt":"2020-04-10 06:00:00"},{"dt":1586509200,"main":{"temp":7,"feels_like":1.03,"temp_min":7,"temp_max":7,"pressure":1009,"sea_level":1009,"grnd_level":989,"humidity":55,"temp_kf":0},"weather":[{"id":801,"main":"Clouds","description":"небольшая облачность","icon":"02d"}],"clouds":{"all":15},"wind":{"speed":5.41,"deg":328},"sys":{"pod":"d"},"dt_txt":"2020-04-10 09:00:00"},{"dt":1586520000,"main":{"temp":7.97,"feels_like":2.59,"temp_min":7.97,"temp_max":7.97,"pressure":1010,"sea_level":1010,"grnd_level":990,"humidity":51,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"небольшой дождь","icon":"10d"}],"clouds":{"all":40},"wind":{"speed":4.54,"deg":332},"rain":{"3h":0.14},"sys":{"pod":"d"},"dt_txt":"2020-04-10 12:00:00"},{"dt":1586530800,"main":{"temp":7.6,"feels_like":2.67,"temp_min":7.6,"temp_max":7.6,"pressure":1011,"sea_level":1011,"grnd_level":990,"humidity":52,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04d"}],"clouds":{"all":79},"wind":{"speed":3.88,"deg":319},"sys":{"pod":"d"},"dt_txt":"2020-04-10 15:00:00"},{"dt":1586541600,"main":{"temp":4.1,"feels_like":-0.98,"temp_min":4.1,"temp_max":4.1,"pressure":1012,"sea_level":1012,"grnd_level":992,"humidity":66,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"небольшой дождь","icon":"10n"},{"id":600,"main":"Snow","description":"небольшой снег","icon":"13n"}],"clouds":{"all":86},"wind":{"speed":4.09,"deg":332},"rain":{"3h":0.19},"snow":{"3h":0.19},"sys":{"pod":"n"},"dt_txt":"2020-04-10 18:00:00"},{"dt":1586552400,"main":{"temp":1.9,"feels_like":-2.73,"temp_min":1.9,"temp_max":1.9,"pressure":1013,"sea_level":1013,"grnd_level":992,"humidity":76,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04n"}],"clouds":{"all":76},"wind":{"speed":3.41,"deg":322},"sys":{"pod":"n"},"dt_txt":"2020-04-10 21:00:00"},{"dt":1586563200,"main":{"temp":0.23,"feels_like":-4.06,"temp_min":0.23,"temp_max":0.23,"pressure":1013,"sea_level":1013,"grnd_level":992,"humidity":88,"temp_kf":0},"weather":[{"id":802,"main":"Clouds","description":"переменная облачность","icon":"03n"}],"clouds":{"all":40},"wind":{"speed":2.99,"deg":335},"sys":{"pod":"n"},"dt_txt":"2020-04-11 00:00:00"},{"dt":1586574000,"main":{"temp":-0.52,"feels_like":-4.23,"temp_min":-0.52,"temp_max":-0.52,"pressure":1013,"sea_level":1013,"grnd_level":992,"humidity":93,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"ясно","icon":"01d"}],"clouds":{"all":8},"wind":{"speed":2.17,"deg":337},"sys":{"pod":"d"},"dt_txt":"2020-04-11 03:00:00"},{"dt":1586584800,"main":{"temp":2.35,"feels_like":-2.35,"temp_min":2.35,"temp_max":2.35,"pressure":1013,"sea_level":1013,"grnd_level":993,"humidity":75,"temp_kf":0},"weather":[{"id":802,"main":"Clouds","description":"переменная облачность","icon":"03d"}],"clouds":{"all":25},"wind":{"speed":3.55,"deg":344},"sys":{"pod":"d"},"dt_txt":"2020-04-11 06:00:00"},{"dt":1586595600,"main":{"temp":2.75,"feels_like":-3.02,"temp_min":2.75,"temp_max":2.75,"pressure":1014,"sea_level":1014,"grnd_level":994,"humidity":72,"temp_kf":0},"weather":[{"id":600,"main":"Snow","description":"небольшой снег","icon":"13d"}],"clouds":{"all":96},"wind":{"speed":5.05,"deg":331},"snow":{"3h":0.47},"sys":{"pod":"d"},"dt_txt":"2020-04-11 09:00:00"},{"dt":1586606400,"main":{"temp":2.6,"feels_like":-4.39,"temp_min":2.6,"temp_max":2.6,"pressure":1015,"sea_level":1015,"grnd_level":994,"humidity":71,"temp_kf":0},"weather":[{"id":600,"main":"Snow","description":"небольшой снег","icon":"13d"}],"clouds":{"all":98},"wind":{"speed":6.73,"deg":347},"snow":{"3h":0.65},"sys":{"pod":"d"},"dt_txt":"2020-04-11 12:00:00"},{"dt":1586617200,"main":{"temp":2.18,"feels_like":-4.71,"temp_min":2.18,"temp_max":2.18,"pressure":1016,"sea_level":1016,"grnd_level":995,"humidity":69,"temp_kf":0},"weather":[{"id":600,"main":"Snow","description":"небольшой снег","icon":"13d"}],"clouds":{"all":95},"wind":{"speed":6.45,"deg":347},"snow":{"3h":0.19},"sys":{"pod":"d"},"dt_txt":"2020-04-11 15:00:00"},{"dt":1586628000,"main":{"temp":-0.57,"feels_like":-6,"temp_min":-0.57,"temp_max":-0.57,"pressure":1018,"sea_level":1018,"grnd_level":997,"humidity":83,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04n"}],"clouds":{"all":54},"wind":{"speed":4.34,"deg":334},"sys":{"pod":"n"},"dt_txt":"2020-04-11 18:00:00"},{"dt":1586638800,"main":{"temp":-1.05,"feels_like":-6.31,"temp_min":-1.05,"temp_max":-1.05,"pressure":1019,"sea_level":1019,"grnd_level":998,"humidity":86,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"ясно","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":4.09,"deg":324},"sys":{"pod":"n"},"dt_txt":"2020-04-11 21:00:00"},{"dt":1586649600,"main":{"temp":-1.26,"feels_like":-6.42,"temp_min":-1.26,"temp_max":-1.26,"pressure":1019,"sea_level":1019,"grnd_level":998,"humidity":88,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"ясно","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":3.97,"deg":312},"sys":{"pod":"n"},"dt_txt":"2020-04-12 00:00:00"},{"dt":1586660400,"main":{"temp":-1.49,"feels_like":-6.32,"temp_min":-1.49,"temp_max":-1.49,"pressure":1019,"sea_level":1019,"grnd_level":998,"humidity":88,"temp_kf":0},"weather":[{"id":802,"main":"Clouds","description":"переменная облачность","icon":"03d"}],"clouds":{"all":45},"wind":{"speed":3.45,"deg":310},"sys":{"pod":"d"},"dt_txt":"2020-04-12 03:00:00"},{"dt":1586671200,"main":{"temp":1.46,"feels_like":-4.6,"temp_min":1.46,"temp_max":1.46,"pressure":1019,"sea_level":1019,"grnd_level":998,"humidity":72,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04d"}],"clouds":{"all":58},"wind":{"speed":5.24,"deg":318},"sys":{"pod":"d"},"dt_txt":"2020-04-12 06:00:00"},{"dt":1586682000,"main":{"temp":3.72,"feels_like":-2.73,"temp_min":3.72,"temp_max":3.72,"pressure":1018,"sea_level":1018,"grnd_level":997,"humidity":61,"temp_kf":0},"weather":[{"id":600,"main":"Snow","description":"небольшой снег","icon":"13d"}],"clouds":{"all":99},"wind":{"speed":5.79,"deg":325},"snow":{"3h":0.14},"sys":{"pod":"d"},"dt_txt":"2020-04-12 09:00:00"},{"dt":1586692800,"main":{"temp":4.85,"feels_like":-1.09,"temp_min":4.85,"temp_max":4.85,"pressure":1017,"sea_level":1017,"grnd_level":997,"humidity":56,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"пасмурно","icon":"04d"}],"clouds":{"all":99},"wind":{"speed":5.05,"deg":323},"sys":{"pod":"d"},"dt_txt":"2020-04-12 12:00:00"},{"dt":1586703600,"main":{"temp":4.11,"feels_like":-0.44,"temp_min":4.11,"temp_max":4.11,"pressure":1017,"sea_level":1017,"grnd_level":996,"humidity":60,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04d"}],"clouds":{"all":78},"wind":{"speed":3.1,"deg":325},"sys":{"pod":"d"},"dt_txt":"2020-04-12 15:00:00"},{"dt":1586714400,"main":{"temp":0.72,"feels_like":-2.21,"temp_min":0.72,"temp_max":0.72,"pressure":1016,"sea_level":1016,"grnd_level":995,"humidity":77,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04n"}],"clouds":{"all":72},"wind":{"speed":0.81,"deg":279},"sys":{"pod":"n"},"dt_txt":"2020-04-12 18:00:00"},{"dt":1586725200,"main":{"temp":0.05,"feels_like":-3.41,"temp_min":0.05,"temp_max":0.05,"pressure":1015,"sea_level":1015,"grnd_level":994,"humidity":83,"temp_kf":0},"weather":[{"id":801,"main":"Clouds","description":"небольшая облачность","icon":"02n"}],"clouds":{"all":22},"wind":{"speed":1.63,"deg":202},"sys":{"pod":"n"},"dt_txt":"2020-04-12 21:00:00"},{"dt":1586736000,"main":{"temp":0.8,"feels_like":-3.63,"temp_min":0.8,"temp_max":0.8,"pressure":1012,"sea_level":1012,"grnd_level":991,"humidity":81,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"облачно с прояснениями","icon":"04n"}],"clouds":{"all":58},"wind":{"speed":3.08,"deg":187},"sys":{"pod":"n"},"dt_txt":"2020-04-13 00:00:00"},{"dt":1586746800,"main":{"temp":0.5,"feels_like":-4.71,"temp_min":0.5,"temp_max":0.5,"pressure":1008,"sea_level":1008,"grnd_level":988,"humidity":91,"temp_kf":0},"weather":[{"id":600,"main":"Snow","description":"небольшой снег","icon":"13d"}],"clouds":{"all":100},"wind":{"speed":4.44,"deg":188},"snow":{"3h":0.41},"sys":{"pod":"d"},"dt_txt":"2020-04-13 03:00:00"},{"dt":1586757600,"main":{"temp":2.64,"feels_like":-2.79,"temp_min":2.64,"temp_max":2.64,"pressure":1005,"sea_level":1005,"grnd_level":985,"humidity":90,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"небольшой дождь","icon":"10d"}],"clouds":{"all":100},"wind":{"speed":5.18,"deg":192},"rain":{"3h":1.51},"sys":{"pod":"d"},"dt_txt":"2020-04-13 06:00:00"},{"dt":1586768400,"main":{"temp":4.21,"feels_like":-1.65,"temp_min":4.21,"temp_max":4.21,"pressure":1002,"sea_level":1002,"grnd_level":982,"humidity":88,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"небольшой дождь","icon":"10d"}],"clouds":{"all":100},"wind":{"speed":6.08,"deg":218},"rain":{"3h":0.99},"sys":{"pod":"d"},"dt_txt":"2020-04-13 09:00:00"},{"dt":1586779200,"main":{"temp":5.9,"feels_like":0.45,"temp_min":5.9,"temp_max":5.9,"pressure":1000,"sea_level":1000,"grnd_level":980,"humidity":78,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"небольшой дождь","icon":"10d"}],"clouds":{"all":100},"wind":{"speed":5.48,"deg":210},"rain":{"3h":1.21},"sys":{"pod":"d"},"dt_txt":"2020-04-13 12:00:00"},{"dt":1586790000,"main":{"temp":8.5,"feels_like":4.05,"temp_min":8.5,"temp_max":8.5,"pressure":997,"sea_level":997,"grnd_level":977,"humidity":68,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"пасмурно","icon":"04d"}],"clouds":{"all":100},"wind":{"speed":4.19,"deg":197},"sys":{"pod":"d"},"dt_txt":"2020-04-13 15:00:00"},{"dt":1586800800,"main":{"temp":6.94,"feels_like":3.65,"temp_min":6.94,"temp_max":6.94,"pressure":995,"sea_level":995,"grnd_level":975,"humidity":86,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"небольшой дождь","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":3.02,"deg":205},"rain":{"3h":1.93},"sys":{"pod":"n"},"dt_txt":"2020-04-13 18:00:00"}],"city":{"id":564912,"name":"Дружба","coord":{"lat":55.8856,"lon":37.7403},"country":"RU","population":4058,"timezone":10800,"sunrise":1586313640,"sunset":1586362832}}

Подскажите пожалуйста, как парсить это? ESP8266 уходит в перезагруз!

Edited by Alex-2818

Share this post


Link to post
Share on other sites
08.04.2020 в 23:08, Alex-2818 сказал:

{"cod":"200","message":0,"cnt":40,"list":[{"dt":1586379600,"main":{"temp":5.05,"feels_li

Все, разобрался!

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Similar Content

    • By Kitsum
      Всем привет, в этой статье поговорим об уже надоевшей всем теме - "Метеостанция". Каждый пытается сделать что-то свое, вот и я не стал исключением и попытался материализовать свои эротические фантазии на контроллере ESP8266. Тема задумывалась уже давно как некое обновление для предыдущего проекта этой тематики, но из-за своей неспешности переросла в нечто самостоятельное.


      При всей привлекательности микроконтроллера ESP8266 с его большим объемом памяти, железной поддержкой Wi-Fi и массой разных плюшек, он не лишен недостатков. Самый основной - ограниченное количество поддерживаемых одновременных TCP соединений равное 5. Если превысить этот лимит, то контроллер потеряет связь с окружающим миром, при этом watchdog будет думать, что все в порядке, а следовательно, даже не попытается нам помочь. Будем стараться это помнить!
      Стоит начать с концепции
      Доступ к данным метеостанции нужно получать без установки внешних приложений и под любой операционной системой. Для этих целей подойдет практически любой современный браузер. Меня всем устраивает Chrome. Раз уж за основу взят HTTP протокол, стоит озаботиться экономией трафика и ограничением числа TCP соединений. Хорошим тоном будет передача всего необходимого для формирования страницы контента только при первом обращении, а все последующие операции, такие как отображение показаний с датчиков или настройку контроллера, производить через API. В этом нам поможет JQuery. А вот, чтобы ослабить болевые ощущения от передачи файлов с SPI Flash в браузер, стоит предусмотреть систему кэширования, например, Etag. Это позволит отдавать тяжелый контент единожды, а при последующих загрузках страницы просто подтверждать его актуальность на уровне Web сервера микроконтроллера и кэш браузера вступит в игру, неимоверно уменьшив время загрузки страницы! "Вы были правы в одном, Мастер: переговоры были недолгими." © Звездные войны. Эпизод 1 Из-за того, что метеостанция с датчиками и контроллером должна располагаться на улице, жизненно необходимо предусмотреть возможность обновлять прошивку ESP через Web интерфейс. Аналогичным образом должны обновляться файлы Web сервера расположенные на SPI Flash. Этот и предыдущий пункт вкупе позволят обновлять функционал микроконтроллера из домашней сети или из интернета, если конечно в этом возникнет острая необходимость. Чтобы никто посторонний не могу вмешаться в работу устройства или изменить файлы Web сервера, последний должен хотя бы как-то себя защищать. Пускать в панель управления только после авторизации, блокировать доступ при попытках брутфорса пароля. В конце концов, контроллер обязан самостоятельно генерировать ключи (salt) для авторизации, дабы сделать алгоритм непредсказуемым и исключить потенциальный взлом, в случае если злодей завладеет исходниками проекта. Понятно, что кому она там нужна, эта метеостанция, если её не завязывать с умным домом, если только из-за спортивного интереса, но как говориться “Береженого Бог бережет”. Датчики стоит расположить по уму - в метеобудке, а вот контроллер в сухом и закрытом боксе. Объединить их между собой, как мне кажется, удобнее по I2C шине - минимум проводов, максимум удобства. Практически на всех вариантах плат ESP-xx имеется штатный светодиод, можно воспользоваться им как для индикации режимов и состояния микроконтроллера, так и для вывода какой-либо промежуточной информации. Что касаемо режимов работы ESP8266, как ни странно, но он должен находить домашнюю Wi-Fi сеть и подключаться к ней. Если вдруг звезды не были к нам благосклонны, и домашняя беспроводная сеть приказала долго жить, контроллер обязан перейти в режим точки доступа (AP) дабы к нему можно было подключиться с какого-либо устройства и перенастроить его на другую сеть. А вот пока последнее не произошло, ESP должен периодически сканировать эфир в поисках долгожданной домашней точки доступа и, если боги были к нам милосердны, и домашняя сеть появилась в эфире, незамедлительно переключиться в режим клиента (STA) и в пылу страсти воссоединиться с ней. Ну и естественно, как же без отправки данных на внешние ресурсы, сейчас без этого не обходится ни одна уважающая себя кофеварка, не говоря уже о метеостанции. Думаю, что основным блюдом станет протокол MQTT, это уже облегчает возможность интеграции с умным домом, стулом или той же кофеваркой. Ну а на закуску добавим поддержку "ThingSpeak" и "Народного мониторинга". При желании можно нарастить функционал, благо памяти у микроконтроллера еще много. Как я себе это представляю
      Учтите, что на видео, данные с датчиков, эмитируются самим микроконтроллером, это нужно для наглядности. В жизни метеорологическая обстановка намного спокойнее слава Богу.
      Перейдем к физической сборки устройства
      Как по мне, так самый оптимальный вариант, это воспользоваться отладочной платой NodeMCU V3 и базой для неё. Таким образом, мы получим отличный комплект с разведенной на его борту всей необходимой обвязкой и возможностью питать устройство от 5 до 24 Вольт.

      Отладочная плата на базе, и смотрится хорошо, и удобства хоть отбавляй.

      Заливаем прошивку, образ SPI Flash и подключаем четырьмя проводами датчики. Справится даже ребенок.
      Ссылки:
      Базовая плата для NodeMCU V3 с преобразователем питания 5-24V в 5V Отладочная плата ESP8266 от NodeMCU Естественно никто не запрещает Вам развести свою плату. Если Вы это сделаете, скиньте нам свое творение, возможно мы перейдем на него. В идеале, все должно размещаться в метеобудке.
      Датчики взятые за основу
      Теперь настал момент озаботиться, где описанные выше ребята будут жить. В прошлый раз мы использовали для этих целей, найденную в подножном корме, электрическую распределительную коробку. Кроме дешевизны в этом решении нет ничего положительного.
      В этот раз мы воспользуемся более серьезным вариантом – "Метеорологическая будка Стивенсона". Она способна защитить датчики от прямых воздействий окружающей среды, но при этом имеет открытую структуру со стенками в виде жалюзи. Удобно, красиво и самое главное – правильно!
      Будка печатается на 3D принтере по эскизам опубликованным на Thingiverse неким kowomike, спасибо добрый человек! Архив с эскизами можно будет скачать в конце поста.

      Фото готовой будки

      Шпилька М8 крепится через зажимной хомут к мачте уличной антенны.
      Примерка. Шпилька практически не укорачивалась, чтобы не закрывать будку параболической Wi-Fi антенной.
      Хотя в моем случае все это сделано не правильно т.к это солнечная сторона дома. Доступа на теневую сторону дома у меня нет, поэтому приходиться довольствоваться тем, что имеем. По прошлой метеостанции мне говорили "на солнечной стороне все эти измерения - сферический конь в вакууме, слепи %описание-многА-букАв% и закрепи на теневой стороне дома".
      Я пока живу в панельном многоквартирном доме, как и не малая часть нашей страны. Доступ к теневой стороне дома (а для меня, по факту, это окна в подъезде) - прямой вызов всем гопникам района трущимся рядом, любопытным соседям с бегающими глазками и всей элите человечества скрашивающей фоном мою унылую и слишком простую, по их мнению, жизнь. Думаю, что мысль я донес.

      Датчики располагаются на разных уровнях. В основании находится датчик освещенности BH1750 и смотрит ровно вниз. Мне кажется, так он будет меньше пачкаться и покрываться пылью и при этом смотреть наружу сквозь минимальное количество препятствий для солнечного света. Вообще размещение этого датчика, это целая головная боль. Как не крути, все будет не то. Оставил так, ведь по сути важны не сами показания, а тенденция изменения. Хотя кого я пытаюсь обмануть, точность важна всегда! Предлагайте свои варианты.
      Намного проще обстоят дела с датчиком атмосферного давления BMP180 и влажности SI7021, кстати, с последнего мы также будем забирать данные о температуре. Их размещаем в оставшемся свободном пространстве будки, благо его там с избытком, но не в конусе т.к пространство в нем менее проветриваемое.

      Все хозяйство подключается между собой следующим образом
      NodeMCU | ESP 07/12 | Датчики ----------------------------- D2 | GPIO 4 | SDA D1 | GPIO 5 | SCL 3.3V | 3.3V | 3.3V GND | GND | GND ВАЖНО: при финальном монтаже устройства на его место службы, обязательно установите перемычку между пинами GPIO 0 (D3) и питанием 3.3 Вольта. Причины её установки описаны в закрепленном сообщении с описание обновления от 12.08.2017.
      Сам микроконтроллер будет спрятан в уже знаменитую распределительную коробку, закрепленную на шпильке, чуть ниже будки Стивенсона. У меня все находится на стадии неторопливой сборки с попутным поиском более удачных идей.
      Плата расширения, на которой будет установлена плата NodeMCU, закреплена через ножки для крепления компьютерных материнских плат в корпусах.

      Разъемы для подключения внешних датчиков и питающей линии установил на местах где была пара штатных заглушек. Закрепил все через переходную пластину, выпиленную из куска фольгированного текстолита. Естественно, предварительно пластина была протравлена, а вся медь искоренена, ибо в этом случае она нам не друг.
      Также была предусмотрена проставка из полиэтиленового поролона (используется в качестве упаковочного материала при транспортировке грузов) между текстолитом и корпусом, общей толщиной 5мм, а после затяжки крепежных винтов, его толщина не превышает 1мм. Это было сделано из-за опыта эксплуатации предыдущего (временного) бокса для этой метеостанции. Без проставки влага быстро найдет путь вовнутрь, и срок службы устройства снизится.
      Производим примерку.
      При окончательном монтаже обязательно необходимо удалить все не плотно прилегающие части полиэтиленового поролона, то есть те части, которые располагаются снаружи и не сдавлены крепежной текстолитовой пластиной. Это необходимо сделать для препятствования накоплению влаги в доступных для неё полостях. Также пришлось увеличить число крепежных болтов для более надежного прилегания текстолита, в противном случае он может выгибаться.
      Все самое сложное позади, остается только вывести на один разъем шину i2c с питание 3.3 Вольта, а на другой подвести пины питания платы расширения. Но т.к у меня валялся "хвост" отрезанный когда-то от не рабочего блока питания маршрутизатора, и я не побрезговал им воспользоваться по прямому назначению.

      Далее останется все подравнять, проверить качество монтажа, возможность замены платы NodeMCU, если это будет необходимо при эксплуатации и самое главное, дважды проверить, что и куда припаяно. Мои кривые руки и невнимательность уже наказывали меня, а т.к ждать новые запчасти долго, повторять не хочется.

      Общий вид получился таким
      А вот как все выглядит в боевых условиях. Кстати, могу предложить идею с помещением в бокс мешочка содержащий впитывающий влагу гель, они часто встречаются в коробках с обувью. Если все герметично, то он впитает остатки влаги, а если нет, то лишним уж точно не будет.


      Требования (!!!Читать обязательно!!!)
      Arduino IDE с поддержкой контроллера ESP8266, версия 2.6.2 (на версиях выше работоспособность не проверялась) Установленный модуль в Arduino IDE для загрузки файлов во Flash память микроконтроллера. Как установить описано тут. Для работы модуля загрузки файлов во Flash может понадобится последняя версия Python https://www.python.org/downloads/ Любой модуль на базе ESP8266 c Flash 4MB (3MB выделяем под SPIFFS) В параметрах выставляем lwIP версии 2 и максимальную производительность (lwIP v2 Higher Bandwidth) Сам архив с последней версией проекта. Скачать можно в конце статьи или по этой ссылке.   
      Обязательные библиотеки (!!!Читать обязательно!!!)
      ArduinoJson (v5.13.5) PubSubClient Ссылки на библиотеки сенсоров указаны в комментариях к коду. Сами библиотеки, как и обслуживаемые ими сенсоры, не являются обязательными. Вы вольны использовать любые датчики, как физические, так и программные.
      Порядок установки (!!!Читать обязательно!!!)
      Изучите файлы проекта с примерами использования тех или иных сенсоров. Все файлы с примерами начинаются с префикса users_, это users_auto.h, users_bme280_x2.h и т.д. Загрузите необходимые Вам библиотеки или используйте эти файлы как пример для добавления иных датчиков. Выставите необходимые настройки для контроллера в среде разработки Arduino IDE. Пример настроек указан на скриншоте выше. Обязательно убедитесь, что выбрано правильное распределение места для внутренней файловой системы, это значит, что 3MB должно быть выделено под файловую систему. Также проверяем, чтобы использовался lwIP v2 в режиме максимальной производительности (lwIP v2 Higher Bandwidth). Произведите загрузку программы с помощью среды разработки (Ctrl + U). Произведите загрузку содержимого каталога data в файловую систему. Меню/Инструменты/ESP8266 Sketch Data Upload Перед тем как устанавливать метеостанцию на постоянное место жительства, подтянуть GPIO-0 (пин D3 на плате NodeMCU) к питанию 3.3V. Во время данной процедуры, питание на контроллере должно отсутствовать. Первый запуск (!!!Читать обязательно!!!)
      Помните, что вся конфигурация микроконтроллера производится исключительно через web интерфейс. Никаких изменений значений тех или иных параметров в коде не требуется, а подобную практику будем считать плохим тоном.
      И так, после запуска микроконтроллера он сразу перейдет в аварийный режим и поднимет собственную точку доступа с именем WeatherStation. Это нормальное поведение т.к подразумевается использование метеостанции в домашней беспроводной сети, ну а раз о ней пока ничего не известно, то и подключаться не к чему.
      Подключитесь к данной сети с любого удобного устройства и перейдите в панель управления (для этого имеется соответствующая иконка, запутаться невозможно), контроллер будет доступен по адресу http://espws.local или http://192.168.4.1 При попытке входа в панель управления будет запрошено имя пользователя и пароль, по умолчанию admin/admin. После входа в панель управления перейдите в раздел "Основные настройки WiFi" и укажите имя и пароль Вашей домашней сети, а также, при необходимости, укажите пароль для подключения к точке доступа поднимаемой контроллером в аварийном режиме. Если все сделано правильно, то контроллер подключится к домашней сети в течении 5-и минут.
      Если Ваша домашняя сеть скрыта, то после первоначальной настройки необходимо перезагрузить контроллер. Это необходимо из-за частичной поддержки работы со скрытыми сетями. После перезагрузки контроллер увидит Вашу сеть и запомнит её MAC адрес. Помните об этом если захотите сменить домашний маршрутизатор.
      Хотите помочь проекту или спонсировать новый?
      Yandex.Money PayPal.me Файлы
       
    • By Kitsum
      Хотите помочь проекту или спонсировать новый?
      Yandex.Money PayPal.me Тема проекта
      Arduino IDE + Project + Libraries + tools: https://yadi.sk/d/jseefFB50NMhAg
    • By Kitsum
      Просмотреть файл [esp8266] Библиотека CMD, реализует настройку микроконтроллера и управление вашей программой через терминал.
      Основная задача библиотеки, это прием пользовательских команд через UART интерфейс, их обработка и выполнение пользовательского кода, связанного с той или иной командой.
      Данная библиотека позволяет реализовать:
      Управление микроконтроллером Любую настройку, будь то WiFi, другие библиотеки или часть Вашей программы Вызывать Ваши задачи (функции) из терминала по команде и передавать им требуемые параметры Использовать контроллер в качестве шлюза между датчиками и программами на PC Внимание: любая команда, передаваемая в терминал обязана заканчиваться символом перевода строки "\n".
      Подключение библиотеки
      #include <cmd.h> Инициализация объекта, к которому мы будем обращаться для добавления команд. В качестве параметра объекту необходимо передать указатель на объект Serial или любой другой схожий по типу интерфейс.
      cmd command(&Serial); В функции Setup описываем какие команды требуется обрабатывать. Например, по команде "test" вызывать пользовательскую функцию с именем "myFunctionName". Имя пользовательской функции может быть абсолютно любым.
      void Setup() { Serial.begin(115200); command.add("test", myFunctionName); } Пользовательская функция будет вызываться каждый раз, когда по интерфейсу Serial поступит команда "test". Если команда будет передана с параметрами, то эти параметры будут переданы в качестве аргументов пользовательской функции.
      В функции loop должна находится команда вызова обработчика.
      void loop() { command.handleEvents(); } Пользовательская функция обязана соответствовать ряду требований:
      Не возвращать никакого результата (быть объявленной с типом void) Принимать в качестве первого аргумента переменную с типом byte в которой будет храниться число равное количеству переданных параметров Принимать в качестве второго параметра переменную с типом char** в которой будет храниться указатель на массив со всеми указателями (char*) на переданные параметры void myFunctionName(byte argc, char** argv) { /* ... */ } Функция всегда должна иметь такой вид, даже если не подразумевается, что ей будут передаваться какие-либо параметры.
      Чтобы перебрать все переданные параметры и вывести их в консоль, можно воспользоваться следующим примером
      void myFunctionName(byte argc, char** argv) { if (0 < argc) { for (uint8_t i = 0; i < argc; i++) { Serial.printf("%i. %s\n", i, argv[i]); } } } Пример вызова пользовательской функции без параметров и с ними
      # test No parameter was passed # test p1 p2 p3 p4 p5 0. p1 1. p2 2. p3 3. p4 4. p5 Помните, что параметры представлены в виде указателей и работать с ними нужно как с обычными переменными не получится т.к указатель содержит не значение переменной (переданный параметр), а указатель на ту область памяти микроконтроллера в которой это значение находится.
      Чтобы сравнить два значения, например, параметр под индексом 0 (идет первым в списке) с каким-либо значением в программе, воспользуйтесь функцией strcmp, которая возвращает целочисленное значение, указывающее на лексическое расхождение строк. Если строки равны, то возвращаемое значение равно 0.
      if (!strcmp(argv[0], "wifi")) { Serial.println(F("Первый аргумент WiFi")); } else { Serial.println(F("Первый аргумент НЕ WiFi!!!")); } Для копирования значения указателя в другую переменную с типом char можно воспользоваться функцией strcpy
      char myVar[20]; strcpy(myVar, argv[0]); if (myVar == "123456") { Serial.prinln(F("ok")); } Также можно обернуть указатель объектом String и получить весь функционал этого объекта, который будет содержать значение параметра
      String param1(argv[0]); // String param1 = argv[0]; Serial.printf("argv[0] length: %i\n", param1.length()); Serial.printf("argv[0] is integer?: %s\n", param1.toInt() ? "YES" : "NO"); if (param1 == "qwerty") { Serial.println(F("Hello QWERTY!")); } С библиотекой идут несколько примеров, в том числе и пример конфигурации WiFi в режиме STA.
      Автор Kitsum Добавлен 05.12.2018 Категория Библиотеки  
    • By Kitsum
      Просмотреть файл [esp8266] Библиотека smartBlink, реализует умное управление штатным светодиодом, что позволяет добавить индикацию состояния вашей программы или микроконтроллера.
      Основная задача библиотеки, это добавление индикации состояния Вашей программы или микроконтроллера. Отображение состояния производится посредством светодиода. Что самое важное, работа библиотеки через прерывание, это позволяет ей поддерживать индикацию даже в то время, когда выполняется длительный код основной программы. Например, Вы можете использовать её для отображения в каком режиме сейчас работает WiFi микроконтроллера, STA или AP и т.д. Или ход выполнения какой-либо операции, например, передача данных на внешний сервер.
      Подключение библиотеки
      #include <smartBlink.h> Чтобы инициализировать управление светодиодом необходимо создать объект, через который мы буем задавать режимы работы индикации.
      smartBlink::smartBlink(byte gpio, bool on = LOW); Объекту необходимо передать два параметра, первый это номер порта, на котором находится светодиод, а второй это уровень логического сигнала, который заставит светодиод работать. Сигнал может быть низким (LOW) или высоким (HIGH), это зависит от схемотехники подключения светодиода.
      Например, штатный светодиод модуля ESP12, использующий GPIO2 (порт 2) можно объявить следующим образом.
      #define led2_pin 2 #define led2_on_signal LOW smartBlink led2(led2_pin, led2_on_signal); Теперь можно в основной программе использовать метод устанавливающий какой режим индикации использовать.
      smartBlink::setMode(mode_t mode); Например, зададим режим светодиода led2 в котором светодиод будет давать одну короткую вспышку раз в секунду.
      led2.setMode(smartBlink::mode_flash1); Режимов работы может быть несколько.
      led2.setMode(smartBlink::mode_off); led2.setMode(smartBlink::mode_flash1); led2.setMode(smartBlink::mode_flash2); led2.setMode(smartBlink::mode_flash3); led2.setMode(smartBlink::mode_flash4); led2.setMode(smartBlink::mode_burn); led2.setMode(smartBlink::mode_inhalf); Чтобы вернуть предыдущий режим индикации для ранее объявленного светодиода led2 используйте следующий метод
      led2.previous(); Благодаря работе библиотеки через прерывания по таймеру, индикация будет работать даже в тех случаях, когда выполняется долгий код.
      С библиотекой идут несколько примеров.
      Автор Kitsum Добавлен 10.12.2018 Категория Библиотеки  
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...