INT 21h

Hi, I am Vladimir Smagin, sysadmin. Telegram Email

ESP8266: Погода из Яндекса и часы по NTP

№ 8366 В разделах: Программирование Электроника от July 9th, 2017,

Использованы библиотеки:

ВНИМАНИЕ! Источник данных XML завернут через мой собственный сервер и работает только для Томска. Разумеется, вы хотите получать данные для вашего собственного города, но бяка Яндекс не отдает данные по http. Вам придется завернуть траффик через ваш вебсервер (например, nginx как у меня), получать данные по https, а отдавать часикам уже по http. Если вам не влом, можете прикрутить ssl, но мне было влом и я сделал так. Если вам тоже вломы, то можно использовать https://openweathermap.org/api.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TimeLib.h>
#include <NtpClientLib.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <tinyxml2.h> //TinyXML2 for XML parsing
using namespace tinyxml2;

#define YOUR_WIFI_SSID "mywifispot"
#define YOUR_WIFI_PASSWD "superpasswd"

#define ONBOARDLED 2 // Built in LED on ESP-12/ESP-07

//LCD display connected via I2C->44780 board "mjkdz"
LiquidCrystal_I2C lcd(0x20, 20, 4);

//set timezone
static const int8_t timeZone = 6;

/*
 Weather source. This source only for Tomsk, Russia!
 Setup your own xml weather source! 
 
 I used nginx on my server to do this:

    location /weather {
        proxy_pass "https://export.yandex.ru/bar/reginfo.xml?region=67";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host "export.yandex.ru";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
*/
static const char* yandexUrl = "http://blindage.org/weather";

// Start NTP only after IP network is connected
void onSTAGotIP(WiFiEventStationModeGotIP ipInfo) {
  Serial.printf("Got IP: %s\r\n", ipInfo.ip.toString().c_str());
  // Write your local NTP server here!
  NTP.begin("ntp.tsu.ru", timeZone, true);
  NTP.setInterval(3600);
  digitalWrite(ONBOARDLED, LOW); // Turn on LED
}

// Manage network disconnection
void onSTADisconnected(WiFiEventStationModeDisconnected event_info) {
  Serial.printf("Disconnected from SSID: %s\n", event_info.ssid.c_str());
  Serial.printf("Reason: %d\n", event_info.reason);
  digitalWrite(ONBOARDLED, HIGH); // Turn off LED
}

void processSyncEvent(NTPSyncEvent_t ntpEvent) {
  if (ntpEvent) {
    Serial.print("Time Sync error: ");
    if (ntpEvent == noResponse) {
      Serial.println("NTP server not reachable");
    }
    else if (ntpEvent == invalidAddress) {
      Serial.println("Invalid NTP server address");
    }
  }
  else {
    Serial.print("Got NTP time: ");
    Serial.println(NTP.getTimeDateString(NTP.getLastNTPSync()));
    // Get XML from weather source
    HTTPClient http;
    http.begin(yandexUrl);
    Serial.println(yandexUrl);
    int httpCode = http.GET();
    if (httpCode > 0) {
      Serial.println(httpCode);
      if (httpCode == HTTP_CODE_OK) {
        String payload = http.getString();
        XMLDocument doc;
        doc.Parse( payload.c_str() );

        XMLElement* dayElement = doc.FirstChildElement( "info" )->
	        FirstChildElement( "weather" )->FirstChildElement( "day" )->FirstChildElement( "day_part" );

        const char* temp = dayElement->FirstChildElement( "temperature" )->GetText();
        const char* pressure = dayElement->FirstChildElement( "pressure" )->GetText();
        const char* dampness = dayElement->FirstChildElement( "dampness" )->GetText();
        const char* wind = dayElement->FirstChildElement( "wind_speed" )->GetText();
        const char* wind_direction = dayElement->FirstChildElement( "wind_direction" )->Attribute("id");
        const char* weather_code = dayElement->FirstChildElement( "weather_code" )->GetText();

        lcd.clear();
        //temperature
        lcd.setCursor(0, 1);
        lcd.print(temp);
        lcd.setCursor(strlen(temp), 1);
        lcd.print((char)0xDF);
        lcd.setCursor(strlen(temp) + 2, 1);
        lcd.print(weather_code);

        //pressure
        lcd.setCursor(0, 2);
        lcd.print("Pressure:");
        lcd.setCursor(10, 2);
        lcd.print(pressure);
        lcd.setCursor(14, 2);
        lcd.print("mm Hg");

        //hum and wind
        string line4 = "Wind ";
        line4 += wind;
        line4 += " ";
        line4 += wind_direction;
        line4 += " Hum ";
        line4 += dampness;
        line4 += "%";
        lcd.setCursor(0, 3);
        lcd.print(line4.c_str());
      }
    }
  }
}

void lineClear(uint8_t line)
{
  lcd.setCursor(0, line);
  lcd.print("                    ");
}

boolean syncEventTriggered = false;
NTPSyncEvent_t ntpEvent;

void setup()
{
  static WiFiEventHandler e1, e2;

  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.hostname("megaclock");
  WiFi.begin(YOUR_WIFI_SSID, YOUR_WIFI_PASSWD);

  pinMode(ONBOARDLED, OUTPUT); // Onboard LED
  digitalWrite(ONBOARDLED, HIGH); // Switch off LED

  NTP.onNTPSyncEvent([](NTPSyncEvent_t event) {
    ntpEvent = event;
    syncEventTriggered = true;
  });

  e1 = WiFi.onStationModeGotIP(onSTAGotIP); // As soon WiFi is connected, start NTP Client
  e2 = WiFi.onStationModeDisconnected(onSTADisconnected);

  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Weather station");
  lcd.setCursor(0, 1);
  lcd.print("(C) Vladimir Smagin");
  lcd.setCursor(0, 2);
  lcd.print("http://blindage.org");
  lcd.setCursor(0, 3);
  lcd.print("21h@blindage.org");
  delay(5000);
  lcd.clear();
}

void loop()
{
  static int i = 0;
  static int last = 0;

  if (syncEventTriggered) {
    processSyncEvent(ntpEvent);
    syncEventTriggered = false;
  }

  delay(100);
  lcd.setCursor(0, 0);
  lcd.print(NTP.getTimeDateString());
}

Недавно я переделал проект под ESP-01 просто переопределив I2C выводы. К сожалению, как обычно дефайнами это не делается и поэтому пришлось поправить код библиотеки. Когда-нибудь у меня дойдут руки убрать всю эту лапшу и сделать красиво.

Нет комментариев »

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Комментарии

  • 21h: нене ) без меня )
  • Серегй: Не совсем грабить)) если грабить можно и без рации, есть...
  • 21h: магазин грабить собрались? ) не, тут я не помощник ;)
  • Серегй: А что бы мне поймать чужую волну, что мне для этого нужно...
  • 21h: слушать никто не запрещает. нет закона, который запрещает...
  • Серегй: Я хотел узнать могу ли я просто прийти с данной рацией baofeng...
  • 21h: У меня есть только эти 2. По другим ничего не знаю. В интернете...

© Vladimir Smagin, 2005-2017. Копирование материалов без разрешения запрещено.
Яндекс.Метрика