класс Forecaster или Предсказатель погоды

Тема в разделе "Arduino & Shields", создана пользователем AlexVS, 1 окт 2015.

  1. AlexVS

    AlexVS Гик

    Многие начинающие (и не только) Ардуинщики прошли через создание устройства с громким названием - Метеостанция, я в их числе.
    Многие варианты, которые я изучал, интересны с точки зрения полета мысли создателя, из многих я почерпнул идеи, о чем и не скрываю.
    Но помимо фиксации показаний с собственных датчиков, визуализации их через различные интерфейсы типа всевозможных Дисплеев и Веб-страничек, мне было интересно использовать данные о прогнозе погоды на некоторое время вперед. Тут, на мой взгляд есть два пути, с первым я ознакомился в статье http://mcucpu.ru/index.php/pdevices...ispolzovanie-datchikov-atmosfernogo-davleniya , но мне больше понравилась возможность получать прогноз из Интернета.
    Основную информацию об этом я почерпнул из статьи на Амперке http://wiki.amperka.ru/дисплеи-и-индикаторы:8x8rgb и развил эту идею дальше, благо предложенный в статье ресурс, позволяет это сделать.
    В результате моя версия погодной станции получила класс Forecaster, отвечающий за предсказание погоды. Вот данный класс, в контексте тестового проекта, я и хочу представить публике в лице читателей данного форума.
    Сразу оговорюсь:
    1. У меня серверная часть метеостанции построена на Arduino Mega 2560, поэтому нехватки памяти в проекте я не испытываю.
    2. Мне пришлось внести некоторые изменения в стандартную библиотеку Ethernet, изменения коснулись количества сокетов и выделенной под них буферной памяти.
    Исходная версия имеет 4 сокета по 2кБ на каждый сокет, я же сделал 2 сокета по 4кБ. Увеличить буферную память пришлось в связи с тем, что при получении с сервера информации о прогнозе погоды, объем информации может достигать 15-18кБ (при получении 3х часового прогноза). Т.е. при размере буфера в 2кБ - большая ее часть просто терялась. При 4кБ буфере удается получить прогноз на 2 дня с дискретностью 3 часа, что уже совсем не плохо. Все изменения библиотеки задокументированы прямо в коде самого класса.
    Иногда, при получении и разборе 3х часового прогноза удается обработать меньшее количество элементов (не 16, а всего 3-6), я так и не понял из-за чего это происходит, возможно Ардуинка не успевает выбрать данные из буфера.

    Для демонстрации работы Предсказателя :) я собрал тестовый проект, который опробовал на 2х устройствах:
    1. Arduino Uno + Ethernet shield (w5100)
    2. iBoard
    В связи с нехваткой памяти в этих устройствах пришлось закомментить отдельные связанные функции.
    Внутри класса:
    Код (C++):
    int FORECAST::GetForecastDays(FORECAST::_WeatherDay* wdp)     // Получение 4х дневного прогноза
    int FORECAST::GetForecast(FORECAST::_WeatherPacket& whr)        // Получение текущей погоды
    В теле основного цикла закомментирован код, вызывающий эти функции. Их работу можно проверить, по очереди комментируя и убирая комменты с соответствующих участков кода. Если же код залить в Mega2560, то необходимость комментирования отпадет и все будет работать.
    Проект собирается под IDE версии 1.6.5. (На 1.0.5r2 - тоже без проблем).

    Так же хочу оговориться, я не являюсь адептом С (С++), поэтому частенько задаю вопросы на форуме как работать со строками и тому подобное. В связи с этим вполне вероятно, что какие то участки кода написаны странно или не оптимально, короче - здоровая критика приветствуется :)

    Город, для которого запрашиваем прогноз прописан в объявлениях класса :
    Код (C++):
    const char p_request3Hour[] PROGMEM  = "GET /data/2.5/forecast?q=Krasnoyarsk&mode=xml&units=metric";
    const char p_request4Day[]  PROGMEM  = "GET /data/2.5/forecast/daily?q=Krasnoyarsk&mode=xml&units=metric&cnt=4";
    const char p_requestToDay[] PROGMEM  = "GET /data/2.5/weather?q=Krasnoyarsk&mode=xml&units=metric";
    Объявление класса предсказания погоды
    Код (C++):
    FORECAST frc;
    FORECAST::_WeatherPacket weather;  //  текущая погода с сайта
    FORECAST::_WeatherDay wPack1Day;  // прогноз погоды с сайта на 4 дня (начиная с сегодня)
    FORECAST::_WeatherThreeHour wPack3Hour;  // 3х часовой прогноз погоды с сайта на 2 дня
    Инициализация
    Код (C++):
    frc.Init(client, 7);  // client  - это EthernetClient, 7 - это часовой пояс
    Запрос погоды на сервере
    Код (C++):
    frc.GetForecast(weather)                    //структура weather - содержит данные о погоде
    frc.GetForecast3Hour(&wPack3Hour)   //wPack3Hour - массив из 16 струкур с 3х часовым прогнозом
    frc.GetForecastDays(&wPack1Day)      //wPack1Day - массив из 4 структур с прогнозом на 4 дня
    Структуры с метеоданными имеют небольшую длину и поэтому без труда могут быть переданы через nRF24. Естественно что 1 структура содержит данные за 1 день или за 3 часа, и что бы передать все дынные полностью, потребуется соответствующее кол-во сеансов передачи. Для этого я создал специальный протокол обмена между дисплейным и серверным модулями.
     

    Вложения:

  2. vlom

    vlom Нуб

    Добрый день.
    Подскажите, при попытке скомпилировать выдаёт ошибку
    Код (C++):

    Forecaster.ino: In function 'void ConvertDT(time_t, char*)':
    Forecaster:83: error: 'TimeElements' was not declared in this scope
       TimeElements t_e;
       ^
    Forecaster:83: error: expected ';' before 't_e'
       TimeElements t_e;
                    ^
    Forecaster:85: error: 't_e' was not declared in this scope
       breakTime(tt, t_e);
                     ^
     
    Насколько я понял, используется не объявленная функция?
     
  3. AlexVS

    AlexVS Гик

    TimeElements входит в библиотеку Time.h, которая в моем тестовом скетче, стоит самой первой строчкой.
    Сейчас специально скачал выложенный архив, загрузил в IDE 1.6.8 - компилится без проблем!
    Может вы что-то поменяли?
    1. Так же хочу добавить, что теперь без API ключа, укахзанного в теле класса, прогноз не выдается.
    2. Здесь выложена самая ранняя версия (но работоспособная!!!), в настоящий момент я переделал библиотеку под работу с прогнозом в формате JSON.
    3. При использовании в проекте Ethernet шилда на чипе W5500 - никаких танцев с бубном, по изменению объема буферов не требуется.
     
  4. AlexVS

    AlexVS Гик

    Скриншот
     

    Вложения: