IT News: Digital Camera, OS, Laptop, Smartphone, Smart TV, Sound...

The Author's Project by Valeri N.Kravchuk
Сайт проверен Dr.Web
Меню сайта
  • Главная страница
  • Информация о сайте
  • Дневник
  • Каталог файлов
  • Обратная связь
  • Каталог сайтов
  • FAQ
  • Доска объявлений
  • Форум
  • Фотоальбом
  • Категории раздела
    Автомобильные гаджеты, ремонт... [220]
    Безопасность IT [484]
    Блоки питания, Power Banks, зарядки... [490]
    Видеорегистраторы [220]
    Гаджеты для спорта и здоровья... [190]
    Гаджеты, аксессуары... [625]
    Измерительная техника, инструменты [449]
    Накопители данных [226]
    Нетбуки, Ноутбуки, Ультрабуки [680]
    Мультиварки, блендеры и не только... [158]
    Планшеты [758]
    Радар-детекторы [26]
    Роботы-пылесосы [37]
    Своими руками [357]
    Сети, сетевые технологии, оборудование... [269]
    Смартфоны [4966]
    Фотокамеры, объективы, искусство фотографии.. [543]
    Умный дом [47]
    Электронные книги [96]
    CB, LPD, PMR- связь... [171]
    DECT, IP-телефоны [18]
    Drones, boats, cars... [108]
    electric cars [35]
    GPS-навигаторы, трекеры... [51]
    Linux и не только [4380]
    mini computers и не только... [409]
    News IT, Это интересно, ликбез... [1113]
    Smart TV, UltraHD, приставки, проекторы... [414]
    Smart Watch [263]
    Sound: наушники, плееры, усилители... [616]
    Windows 10... [298]
    Windows 11 [28]
    Погода

  • Метеорадар БРЕСТ
  • Погода в Бресте от www.yr.no

    Яндекс.Погода БРЕСТ

  • Интересные ссылки

    COMPIZOMANIA

    Наш опрос
    Оцените мой сайт
    Всего ответов: 1340
    Статистика
    Анализ веб сайтов

    Яндекс.Метрика

    Рейтинг@Mail.ru Яндекс цитирования

    Russian America Top. Рейтинг ресурсов Русской Америки.

    eXTReMe Tracker

    Правильный CSS!


    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0
    Locations of visitors to this page
    Форма входа
    Главная » 2014 » Июнь » 11 » Метеостанция: от идеи до реализации
    14:46
    Метеостанция: от идеи до реализации

    Метеостанция: от идеи до реализации


    Прочитал множество статей, посвященных разработке своего устройства, и захотел рассказать о своем опыте. Происходило это несколько лет назад, на 4-м курсе универа. Сейчас я многое сделал бы уже по-другому, а в то время я только начинал осваивать электронику, это — мое первое устройство, так что не судите строго.

    Мне всегда хотелось чего-то большего, чем обычный градусник за окном или ЖК-экран метеостанции с температурой на улице и в комнате. Поэтому, когда я задумался, «что же такое сделать» для того, чтобы начать знакомство с миром микроконтроллеров, ответ нашелся сам собой — свою метеостанцию. Естественно, с отображением градусов на улице и внутри помещения, влажности и давления. И с подсветкой — мне всегда нравилась реализация прогноза погоды на Яндексе — одного взгляда на фон достаточно, чтобы понять, будет тепло или холодно, и насколько.

    Весь дальнейший функционал был определен небольшим мозговым штурмом. Наличие подсветки, безусловно, плюс, но как быть ночью и вечером? Я решил установить ИК-сенсор, реагирующий на приближение. При подходе к прибору на комфортное расстояние включается подсветка, в иное время экран по умолчанию не горит. Использование ИК подтолкнуло к реализации управления прибором также по ИК-каналу — через пульт (поначалу были опасения о взаимных помехах, но они не подтвердились). Вполне естественно для такого устройства наличие часов.

    В качестве основы для системы была выбрана Arduino, которую я только начинал осваивать. Саму Arduino я рассматриваю сейчас (да и тогда), как фреймворк — в первую очередь программный, позволяющий быстро строить необходимую систему, подключая при необходимости плагины-библиотеки. Да, мы можем писать и на чистом С/С++, но в большинстве рядовых задач это дает лишь незначительный прирост производительности, практически незаметный на фоне простоты и удобства загрузки скетчей в Arduino, а также обширнейшей коллекции библиотек для работы с различным железом. (Само собой, что есть особые задачи, но сейчас речь не о них).
    В аппаратной же реализации я предпочитаю использовать синюю плату Arduino только на этапе прототипирования на «макетке», а по окончанию разработки устройств обычно проектирую одну-единственную плату с микроконтроллером и всем остальным. Так было и в тот раз.

    Подбор компонентов я начал с экрана. Довольно быстро нашелся замечательный экран с RGB-подсветкой www.adafruit.com/products/398, что позволяло получить практически любые цвета. Он построен на популярном чипе HD44780 и поддерживается огромным количеством библиотек, в том числе и LiquidCrystal в Arduino.

    Также я поинтересовался ценами на индивидуальное производство дисплеев. Минимальная цена за 1 экземпляр монохромного ЖК (как в типовой метеостанции) по ценам того времени была порядка 1 000 евро, для некоммерческого проекта в единичном экземпляре я счел такой ценник нецелесообразным.





    В качестве ИК-датчика был выбран Sharp GP2Y0A02YK0F. Немаловажной характеристикой в моем случае являлась дальность обнаружения объектов, у этого датчика она равна 1.5 м, в то время как у многих других сенсоров она не превышает 30 см. Как показала себя эксплуатация, для небольшого экрана 16х2 полтора метра — действительно оптимальное расстояние.

    В качестве датчика давления был выбран Bosch BMP085, работающий по I2C, влажности HH10D — с частотным выходом. Забегая вперед, скажу, что сейчас я бы ни в коем случае не использовал последний, а предпочел бы исключительно I2C-варианты, например HTU21D.

    В качестве внешних сенсоров температуры использовались всеми любимые DS18B20. Их огромным преимуществом является возможность подключать (и отключать при необходимости) на 1 шину сразу несколько датчиков, без необходимости менять код программы. С беспроводной передачей данных температуры я в своем первом проекте я связываться не стал, тем более что у меня была возможность проложить провода без ущерба эстетике.

    ИК-приемник был взят наиболее типовой, типа TSOP382. Пультом для метеостанции стал пульт от какого-то видеорегистратора. Зуммер (она же пищалка) — самый обычный пьезоизлучатель.





    В качестве часов реального времени я выбрал DS1307, также работающую по I2C, кроме того, у меня была крошечная микросхема флеш-памяти 24AA256 на 64 Кб с I2C-интерфейсом. Ее я добавил в проект из чистого любопытства — попробовать работу с внешней памятью, записывая в нее данные о погодных условиях. Питание для проекта – внешнее, от блока питания. На входе стоит преобразователь/стабилизатор напряжения LM7805, сам узел питания очень похож на используемый в Arduino (хотя и не является клоном).

    Разработку я выполнял итерациями, так намного проще выполнять отладку и знакомиться с новой для себя областью. На самом первом этапе с термометра DS18B20 считывались данные и выводились на ЖК-экран. На следующем — значения температуры должны были превращаться в RGB-код для подсветки.

    Тут меня подстерегала особенность цветопередачи. Управление цветом экрана осуществляется при помощи широтно-импульсной модуляции для каждого из трех светодиодов подсветки (при помощи стандартной библиотеки) с 256 ступенями – казалось бы, вполне обычный 24-битный цвет. К сожалению, длины волн для цветов R, G и B монитора и светодиодов подсветки сильно различаются, и из-за этого обычные цвета, вроде #ffff00, на фоне моего ЖК-экрана выглядят совершенно иначе («уходят в сторону»). Поэтому мне пришлось написать на С# программу с тремя ползунками и color picker’ом, передающую три компоненты цвета в последовательный порт Arduino. Дальше пришлось вспомнить азы математики и составить функцию, преобразующую температуру в градусах по Цельсию в RGB-цветовую шкалу. Естественно, я уже не ограничивался желто-голубой шкалой Яндекса, и использовал и другие цвета — на основе своих ассоциаций.

    Следующими этапом стали подключение IR дальномера, датчиков температуры и влажности. И, если с первыми двумя не возникло никаких сложностей (кроме пайки BMP085 в LCC8-корпусе), то датчик влажности доставил массу проблем.

    Все дело в том, что итоговое значение относительной влажности рассчитывается по формуле, одним из аргументов которой является частота меандра на выходе датчика. Измерение частоты выполняется при помощи аппаратного таймера микроконтроллера. В 328, к сожалению, таких таймеров всего лишь три, и большая их часть уже задействована при ШИМе для подсветки дисплея. (Сейчас уже не помню все детали, возможно, что-то пропустил).

    Из этой ситуации было несколько выходов. Если бы я разрабатывал устройство сегодня, я бы однозначно использовал только I2C-сенсоры. Другим вариантом было использовать более мощный микроконтроллер. Я же тогда выбрал третий вариант — установить отдельный микроконтроллер для работы со звуком (пищалка) и подсветкой дисплея (напомню, это был в первую очередь образовательный проект, и мне было интересно попробовать организовать взаимодействие между двумя МК). В него же перешла функция преобразования температуры в цвет, что облегчило на пару килобайт прошивку главного МК (в Atmega328 размер памяти программы составляет всего лишь 32Кб, моя прошивка в итоге вплотную приблизилась к этому пределу). Взаимодействие между МК было все так же организовано по I2C.

    После этого были добавлены пульт, часы, флеш-память. Следующей стадией стало написание удобного меню, добавление программных фич (таких, как блокировка подсветки в текущем состоянии, режим больших цифр — как на уличных часах, с прокруткой всех параметров), поддержка нескольких датчиков температуры с их добавлением / удалением онлайн (да, я знаю, что так лучше не делать). Вполне привычное дело для ПК — и необычное поначалу для собранного тобой устройства, когда без изменения схемы в несколько раз возрастает функциональность проекта…

    Пульт использовал какой-то свой проприетарный протокол. Я не стал заниматься его реверс-инжинирингом, мне было вполне достаточно шестнадцатеричного представления каждой кнопки, получаемого мной от библиотеки IRRemote. Для флеш-памяти я выбрал запись данных погоды каждые 10 минут, при длине записи в 16 байт этого хватает на 4 месяца.
     

    Код, отвечающий за работу с флеш-памятью
    LOGGER.h
    #ifndef LOGGER_h
    #define LOGGER_h
    
    #include <WProgram.h>
    
    class LOGGER {
     public:
     LOGGER(int);
     void storeRecord16(byte* buffer);
     void getRecord16(unsigned int address, byte* buffer);
     int getAddress();
     void setAddress(int);
     private:
     int _FlashI2CAddress;
     void _getAddress();
     void _setAddress();
     unsigned int _addr;
    };
    
    #endif
    

    LOGGER.cpp
    #include <WProgram.h>
    #include <Wire.h>
    #include "LOGGER.h"
    /*
    MEMORY MAP:
    0000 - MSB of last written address
    0001 - LSB of last written address
    ...
    0040 - 7FFF - storage,
    */
    
     LOGGER::LOGGER(int a)
     {
     _FlashI2CAddress = a;
     }
    void LOGGER::storeRecord16(byte* buffer)
    {
     byte c;
     //get address
     LOGGER::_getAddress();
     //increase addr
     delay(5);
     _addr+=16;
     if(_addr>0x7FF0) _addr = 64;
    
     //store buffer
     Wire.beginTransmission(_FlashI2CAddress);
     Wire.send((byte) (_addr >> 8) & 0xFF); // MSB
     Wire.send((byte) (_addr & 0xFF) ); // LSB
     for ( c = 0; c < 16; c++)
     Wire.send(buffer[c]);
     Wire.endTransmission();
     delay(20);
     //save new addr
     LOGGER::_setAddress();
    }
    void LOGGER::getRecord16(unsigned int address, byte* buffer)
    {
     byte c;
     //set address
     Wire.beginTransmission(_FlashI2CAddress);
     Wire.send((byte) (address >> 8) & 0xFF); // MSB
     Wire.send((byte) (address & 0xFF) ); // LSB
     Wire.endTransmission();
     Wire.requestFrom(_FlashI2CAddress,16);
     for (c = 0; c < 16; c++ )
     if (Wire.available()) buffer[c] = Wire.receive();
    }
    void LOGGER::_getAddress()
    {
     byte c;
     Wire.beginTransmission(_FlashI2CAddress);
     Wire.send(0); 
     Wire.send(0); 
     Wire.endTransmission();
     Wire.requestFrom(_FlashI2CAddress,2);
     for (c = 0; c < 2; c++ )
     if (Wire.available()) _addr = _addr * 256 + Wire.receive();
    }
    void LOGGER::_setAddress()
    {
     Wire.beginTransmission(_FlashI2CAddress);
     Wire.send(0); // pointer
     Wire.send(0); // pointer
     Wire.send((byte) (_addr >> 8) & 0xFF); // MSB
     Wire.send((byte) (_addr & 0xFF) ); // LSB
     Wire.endTransmission();
    }
    void LOGGER::setAddress(int addr)
    {
     _addr = addr;
     LOGGER::_setAddress();
    }
    int LOGGER::getAddress()
    {
     LOGGER::_getAddress();
     return _addr;
    }
    


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

    После этого законченная функционально метеостанция пробыла в виде Arduino и макетных плат где-то с неделю. За это время тестов обнаружилась возможность зависания (вызванная нарушением герметичности уличного датчика температуры). Конструкцию датчика я переделал (сегодня я бы брал только фабричный, например, такой ), но и саму возможность зависаний хотелось исключить в принципе. Кроме того, я предположил, что через 49 дней непрерывной работы произойдет переполнение функции millis(), что, в связи с особенностями алгоритма прошивки, также приведет к зависанию. Вещь должна быть надежной! Поэтому последним штрихом в системе стала активация watchdog таймера, в итоге любое зависание гарантированно не продлится более чем 2 сек + 5 сек на reboot (да, в наш цифровой век даже метеостанции нужно время на загрузку.

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

    Я начал с похода в ближайший радиомагазин и выбора корпуса. Из 20-30 различных вариантов мне приглянулся тот, что на рисунке в начале статьи – из-за минимума требуемой переделки, из-за возможности удобно закрепить снаружи корпуса дальномер, так, чтобы он сильно не выпирал, из-за хорошей вентиляции (а значит, более точных показаний температуры в комнате). Сегодня, наверное, я бы заказал печать на 3D-принтере и сделал что-то вот в этом стиле:
     


    (Сложно найти похожую картинку, а в 3D -моделировании я не профи. Экран располагается в верхней части, все остальное в подставке). И, разумеется, никаких проводов — 433МГц для сенсоров и Wi-Fi для связи с ПК.

    После примерок и раздумий, как лучше расположить все, пришла очередь разработки платы. В своем первом проекте я использовал систему Eagle. Начертил контур платы, разместил на ней элементы и связи (да, этот проект я делал «неправильным» образом – без принципиальной схемы. Точнее, без схемы в Eagle), трассировщик с легкостью все развел. Отнес на производство…
     
    На Хабре очень любят тему изготовления печатных плат, поэтому здесь сделаю отступление. С ЛУТом я знаком, но у меня нет желания/возможности делать платы, в том числе связываться с химией (хлорное железо та еще вещь). Зато при универе есть небольшое опытное производство, где по очень умеренным ценам (~$3 за кв.дм. на то время) могут изготовить практически любую двустороннюю ПП. Технология – фоторезист, отверстия – от 0.6мм, минимальная ширина дорожки – вроде бы 0.2мм (точно не крупнее, сейчас уже не вспомню). К сожалению, никаких паяльных масок, металлизации переходных отверстий за такую цену ждать не приходится, но это все решаемо. В конце концов, для прототипирования (а платы готовят за день-два) и мелкосерийного производства можно обойтись и без масок (имхо; пайку подразумеваю вручную и крупную).


    Впрочем, когда я делал заказ, то про металлизацию переходных отверстий я не подумал. Eagle благополучно использовал ножки элементов в качестве таковых, и обошелся всего лишь 2-3 отдельно стоящими соединениями между слоями. Человек на выдаче обратил на это внимание и любезно предложил тончайший провод для создания переходов в отверстиях для элементов (то есть, сначала через отверстие к верхней и нижней контактной площадке припаивается проводок, после чего в него уже вставляется сама ножка элемента). Я попробовал так действовать, но результаты и объем дополнительной работы не внушали оптимизма. Пришлось перетрассировать плату, создав зоны запрета для расположения via вблизи всех PTH-элементов. Тут автоматический трассировщик доводить работу до конца отказался, и мне пришлось разводить оставшиеся цепи вручную (желания и времени менять систему проектирования уже не было). Сами переходные отверстия в итоге делались точно по такой же технологии, но их количество я свел к минимуму. Паять вновь заказанную плату было несравненно проще.

    Далее – работа дрелью, ножом и напильниками, корпус приобрел окошко для экрана, крепления для платы. Пара вечеров – и устройство в корпусе, успешно работает. И все же, чего-то не хватает…

    А не хватает наклейки на переднюю панель (особенно после прорезки окна в ней). Самоклеющаяся бумага – отличная вещь для подобных задач. То, что получилось – на титульном фото, строго не судите:) После этого внешний вид устройства изменился радикально…

    Вот так (вкратце) выглядел у меня путь разработки моего первого устройства. За кадром осталось много кода, много решений различных мелких возникавших по ходу задач. Главное, что я приобрел для себя – это опыт разработки, набитые «шишки», понимание принципов работы, плюс бонусом стала сама метеостанция. Уникальная и единственная в своем роде.
     

    P.S. Я знаю, что многие из решений не оптимальны, но, именно благодаря им (в том числе) я теперь понимаю, что оптимально, а что нет:). Бонусом прилагаю функциональную схему на английском и несколько фото, а также рендер платы.

    Функциональная схема:





    Рендер, реальная плата без паяльной маски. Не показан держатель литиевой батареи, пьезоизлучатель, DIN-разъем (питание, связь с ПК, датчики) и разная мелочевка. Кроме того, в реальном устройстве микроконтроллеры стоят в панельках.

    Режим «Больших цифр», для лучшей читаемости издали:



     

    http://habrahabr.ru/post/223829/

    Категория: Своими руками | Просмотров: 683 | Добавил: laptop | Рейтинг: 4.8/4
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Волк слабее льва и тигра, но в цирке волк не выступает!
    Волк слабее льва и тигра, но в цирке волк не выступает!
    Волк - единственный из зверей, который может пойти в бой на более сильного противника.
    Если же он проиграл бой, то до последнего вздоха смотрит в глаза противника. После этого умирает...

    Праздники сегодня

    Поиск
    Календарь
    «  Июнь 2014  »
    ПнВтСрЧтПтСбВс
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30
    Архив записей
    Друзья сайта
  • Официальный блог
  • JEEP - the best! Mercedes - the best! Автомобильный портал города Бреста: технические характеристики с фото, авторынок, автоспорт...
    Наша кнопка
    IT новости с моего лаптопа...

    Внимание!
    Администратор сайта laptop.ucoz.ru не несет ответственности за содержание рекламных объявлений. Все используемые на сайте зарегистрированные товарные знаки принадлежат своим законным владельцам! Используемая со сторонних источников информация публикуется с обязательными ссылками на эти источники.
    Copyright Valeri N.Kravchuk © 2007-2024