Ремонт Стены Уход

Самодельный анемометр. Как сделать анемометр из электрического двигателя

Анемометр – прибор для измерения скорости ветра. Классический чашечный анемометр представляет собой чисто механический прибор, способный измерять скорость ветра в диапазоне от 2 до 20 м/с. Анемометр просто подсчитывает количество оборотов крыльчатки. Для определения скорости ветра надо отмерить количество оборотов за некоторый промежуток времени, например 30 с, а затем рассчитать количество делений которые проходит стрелка анемометра за 1 с. После этого для определения скорости ветра следует воспользоваться графиком.

Сконструировать его аналог проще всего на основе маломощного электромотора, например ДМ-03-3АМ 3 91, который выступает в роли генератора. Четырехлопастная крыльчатка анемометра взята готовая, приобретена на Aliexpress примерно за 1 доллар.

Диаметр крыльчатки 10 см, а высота 6 см.

Электромотор располагается в корпусе, сделанном из емкости для холодной сварки, в крышке которой прорезано отверстие для вала электродвигателя и ведущих от двигателя проводов.

К электродвигателю подключен диодный мост VD1 собранный на диодах Шоттки 1N5817. На выходе диодного моста подключен электролитический конденсатор C1 1000 мкФ х 16 В.

Схема подключения анемометра

Диоды Шоттки выбраны из-за того, что скорость вращения крыльчатки, в обычных условиях (если нет урагана) не очень велика. При скорости ветра около 6 м/с, на выходе прибора появляется напряжение около 0,5 В. В таких условиях рационально минимизировать потери на всех элементах схемы. По этой же причине в качестве соединительных проводов используются проводники избыточно большого сечения.

К выводам выпрямителя можно подключить любой вольтметр постоянного тока на 2 В. С его ролью отлично справляется мультиметр. Хотя использование отдельного стрелочного прибора позволяет непосредственно градуировать шкалу в скорости ветра.

Так как устройство планировалось эксплуатировать на улице диодный мост был залит в эпоксидную смолу. Как оказалось конденсатор был взят избыточно емкий так, что быстрые перепады напряжения и соответственно, порывы ветра прибор зафиксировать не может. Автор обзора Denev.

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

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

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

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

Шаг 1: Инструмент и периферия для изготовления анемометра на базе Arduino

В таблице ниже перечислены все необходимые компоненты для конструирования и их особенности.

Компонент Особенности
Модуль МПЗ Во всех инструкциях указано, что общая поддержка модуля равняется 25 тысячам фрагментов фраз, звуковых сигналов и мелодичных тонов. Загруженное аудио делится ровно на 255 музыкальных композиций. Встроено 30 уровней для регулирования громкости, а эквалайзер включает в себя 6 режимов обработки.
«Ручной» анемометр Инструмент представляет собой сенсорный датчик, который используется для слежения и оповещения, для человека, занимающегося различными видами спорта, где учитывается дуновение ветра.

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

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

Микропроцессор Ардуино Составляющие компоненты микропроцессора: аппаратная и программная группа. Программируемый код записан на знаменитом языке программирования С++, который был гораздо упрощен до Wiring. В микропроцессор встроена бесплатная среда, в которой любой пользователь может дать жизнь своей программе с помощью кода. Ардуино-среду разработки поддерживают все операционные системы: Виндовс, Мак ОС и Линукс.

Ардуино-платформа «разговаривает» с компьютером с помощью юсб-кабеля. Чтобы микропроцессор работал в автономном режиме, придется приобрести блок питания до 12 В. Однако питание для Ардуино-платформы, кроме юсб адаптера, может осуществляться с помощью батареи. Определение источника производится автоматическим образом.

Норма для питания платы варьируется между 6 и 20 В. Следует учитывать, что если напряжение в электрической сети меньше 7 В, работа микропроцессора становится неустойчива: возникает перегрев, после чего на плате появляются повреждения. Поэтому не стоит верить указанной в инструкции норме питания и выбрать диапазон, начиная с 7 В.

Встроенная в микропроцессор флеш-память равна 32 кБ. Однако 2 кБ потребуется для работы бутлоадера, с помощью которого осуществляется прошивка Ардуино с использованием компьютера и юсб-кабеля. Предназначение флеш памяти в таком случае – сохранение программ и надлежащих статических ресурсов.

В Ардуино платформу также включена СРАМ-память, в которой числится 2 кБ. Предназначение данного вида памяти микропроцессора – сохранение временных сведений в качестве переменных, использующихся в программных кодах. Данную закономерность можно сравнить с оперативной памятью любого компьютерного устройства. Когда платформа отключается от источника питания, оперативная память очищается.

Динамик с мощностью до 3-х Вт Можно купить в любом компьютерном магазине.
Карта с памятью не меньше 32 Гб Аналогично предыдущему пункту.
Резистор на 220 Ом в количестве 2 штуки Такие резисторы отличаются постоянной мощностью в 0,5 ВТ и точностью до 5 процентов. Работа осуществляется под напряжением не более 350 В.
Батарея «Крона» Батарейка «Крона» сделана на алкалайновой основе и отлично работает на 9 В. Инструмент предназначен для управления электронной самодельной аппаратурой, к которой подключаются периферийные устройства наподобие сенсорных или дисплейных датчиков. Выпускает заряженное «чудо» компания из Германии – Ansmann.
Кабель питания для подзарядки батареи Кабель предназначен для того, чтобы заряжать стандартные батарейки «Крона» на 9 В. С одной стороны торчит штекер с плюсовым центром, с другой – разъем для применения батареи.
Провода для соединения схемы «папа-папа» Данные провода отлично соединяют периферийные устройства между собой.
Бредбоард Бредбоард – специальная дощечка, которая создана для прототипирования. Такое устройство не заставит юного электронщика делать множественные спайки, которые обычно требуются для конструирования электронных устройств.
Клеммник в количестве 3 штуки Клеммник – небольшая коробочка для присоединения пары контактов. Расстояние между разъемами контактов равняется 2х3 мм. Оборудование легко установить на макетной плате: все соединительные провода плотно фиксируются и крепко сжимаются.

Шаг 2: Схема подключения

После того, как все компоненты куплены или собраны, переходим к схеме подключения ардуино анемометра:

  1. Соединяем все вышеперечисленные компоненты выше между собой, используя при этом соединительные провода и клеммники. Питание пока не включаем.
  2. Записываем на флешку 7 поочередных мелодий, придумываем соответствующие названия.
  3. Флешку подключаем к МП3-модулю.
  4. Подаем в устройство питание.
  5. В разделе ниже приведен код программы, которую нужно перенести на Ардуино микропроцессор.
  6. Испытываем прибор в действии.

Шаг 3: Программирование Arduino для считывания данных с анемометра

Алгоритм кода для осуществления работы анемометра:

#include mp3TF mp3tf = mp3TF (); unsigned int speed; unsigned char prev_speed; unsigned int speed_change_counter = 0; boolean speed_changed = false; void setup() { mp3tf.init(&Serial); Serial.begin(9600); } unsigned int measureSpeed() { return analogRead(A0); } void saySpeed() { unsigned char pseudospeed = speed/40; if(pseudospeed == 0) mp3tf.stop(); else if(pseudospeed > 6) mp3tf.play(7); else mp3tf.play(pseudospeed); } void loop() { speed = measureSpeed(); if (abs(speed-prev_speed) > 40 && speed/40 != prev_speed/40) { speed_change_counter = 0; speed_changed = true; prev_speed = speed; } else { if(speed_changed) { if(++speed_change_counter == 10) { speed_changed = false; saySpeed(); } } } delay(100); }

Шаг 4: Дополнительные примеры

Еще один вариант реализации этого устройства продемонстрировали коллеги из компании ForceTronics. Они сделали видео о том как происходил процесс создания анемометра:

Скетч для микроконтроллера от этой компании ниже:

//*****************Arduino anemometer sketch****************************** const byte interruptPin = 3; //anemomter input to digital pin volatile unsigned long sTime = 0; //stores start time for wind speed calculation unsigned long dataTimer = 0; //used to track how often to communicate data volatile float pulseTime = 0; //stores time between one anemomter relay closing and the next volatile float culPulseTime = 0; //stores cumulative pulsetimes for averaging volatile bool start = true; //tracks when a new anemometer measurement starts volatile unsigned int avgWindCount = 0; //stores anemometer relay counts for doing average wind speed float aSetting = 60.0; //wind speed setting to signal alarm void setup() { pinMode(13, OUTPUT); //setup LED pin to signal high wind alarm condition pinMode(interruptPin, INPUT_PULLUP); //set interrupt pin to input pullup attachInterrupt(interruptPin, anemometerISR, RISING); //setup interrupt on anemometer input pin, interrupt will occur whenever falling edge is detected dataTimer = millis(); //reset loop timer } void loop() { unsigned long rTime = millis(); if((rTime - sTime) > 2500) pulseTime = 0; //if the wind speed has dropped below 1MPH than set it to zero if((rTime - dataTimer) > 1800){ //See if it is time to transmit detachInterrupt(interruptPin); //shut off wind speed measurement interrupt until done communication float aWSpeed = getAvgWindSpeed(culPulseTime,avgWindCount); //calculate average wind speed if(aWSpeed >= aSetting) digitalWrite(13, HIGH); // high speed wind detected so turn the LED on else digitalWrite(13, LOW); //no alarm so ensure LED is off culPulseTime = 0; //reset cumulative pulse counter avgWindCount = 0; //reset average wind count float aFreq = 0; //set to zero initially if(pulseTime > 0.0) aFreq = getAnemometerFreq(pulseTime); //calculate frequency in Hz of anemometer, only if pulsetime is non-zero float wSpeedMPH = getWindMPH(aFreq); //calculate wind speed in MPH, note that the 2.5 comes from anemometer data sheet Serial.begin(57600); //start serial monitor to communicate wind data Serial.println(); Serial.println("..................................."); Serial.print("Anemometer speed in Hz "); Serial.println(aFreq); Serial.print("Current wind speed is "); Serial.println(wSpeedMPH); Serial.print("Current average wind speed is "); Serial.println(aWSpeed); Serial.end(); //serial uses interrupts so we want to turn it off before we turn the wind measurement interrupts back on start = true; //reset start variable in case we missed wind data while communicating current data out attachInterrupt(digitalPinToInterrupt(interruptPin), anemometerISR, RISING); //turn interrupt back on dataTimer = millis(); //reset loop timer } } //using time between anemometer pulses calculate frequency of anemometer float getAnemometerFreq(float pTime) { return (1/pTime); } //Use anemometer frequency to calculate wind speed in MPH, note 2.5 comes from anemometer data sheet float getWindMPH(float freq) { return (freq*2.5); } //uses wind MPH value to calculate KPH float getWindKPH(float wMPH) { return (wMPH*1.61); } //Calculates average wind speed over given time period float getAvgWindSpeed(float cPulse,int per) { if(per) return getWindMPH(getAnemometerFreq((float)(cPulse/per))); else return 0; //average wind speed is zero and we can"t divide by zero } //This is the interrupt service routine (ISR) for the anemometer input pin //it is called whenever a falling edge is detected void anemometerISR() { unsigned long cTime = millis(); //get current time if(!start) { //This is not the first pulse and we are not at 0 MPH so calculate time between pulses // test = cTime - sTime; pulseTime = (float)(cTime - sTime)/1000; culPulseTime += pulseTime; //add up pulse time measurements for averaging avgWindCount++; //anemomter went around so record for calculating average wind speed } sTime = cTime; //store current time for next pulse time calculation start = false; //we have our starting point for a wind speed measurement }

На этом пока всё. Желаем вам хороших проектов! Любые пожелания и комментарии вы можете оставить в нашей группе ВКонтакте.

Обычная бытовая фирменная или самодельная метеостанция измеряет две температуры-влажности (в комнате и на улице), атмосферное давление и дополнительно имеет часы с календарем. Однако, настоящая метеостанция имеет еще много всего - датчик солнечной радиации, измеритель осадков и всякое подобное, что, в общем, требуется только для профессиональных нужд, за одним исключением. Измеритель параметров ветра (скорости, и, главное, направления) - очень полезное дополнение для загородного дома. Причем фирменные датчики ветра довольно дороги даже на Али-Бабе, и имеет смысл присмотреться к самодельным решениям.

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

Для измерения скорости ветра (анемометрии) существует стопицот способов, главные из которых такие:

Термоанемометрический,
- механический - с пропеллером (точнее, импеллером) или чашечной горизонтальной крыльчаткой (классический чашечный анемометр), Измерение скорости в этих случаях эквивалентно измерению частоты вращения оси, на которой закреплена пропеллер или крыльчатка.
- а также ультразвуковой, объединяющий измерения скорости и направления.
Для измерения направления способов меньше:
- упомянутый ультразвуковой;
- механический флюгер с электронным съемом угла поворота. Для измерения угла поворота есть также много различных способов: оптические, резистивные, магнитные, индуктивные, механические. Можно, кстати, просто закрепить на валу флюгера электронный компас - вот только надежные и простые (для «наколеночного» повторения) способы передачи показаний с хаотично вращающейся оси придется еще поискать. Потому мы далее выбираем традиционный оптический способ.

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

О минимальном энергопотреблении

Кстати, а минимальное энергопотребление - сколько это? Если исходить из обычных бытовых батареек типа АА, то среднее потребление схемы в идеальном случае должно составлять не более 1-2 мА. Посчитайте сами: емкость приличного щелочного элемента типоразмера АА составляет около 2,5-3 А ч, то есть схема с указанным потреблением проработает от него около 1500-2500 часов, или 2-3 месяца. В принципе это тоже немного, но относительно приемлемо - меньше нельзя никак: либо разоритесь на батарейках, либо придется применять аккумуляторы, которые нужно будет заряжать еще чаще, чем менять батарейки. По этой причине мы при составлении такой схемы обязаны ловить любые крохи: обязательный режим энергосбережения, тщательно продуманная схемотехника и последовательность действий в программе. Далее мы увидим, что в окончательной конструкции я все-таки не уложился в нужные требования и пришлось применять питание от аккумулятора.


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

Конструкции датчиков

Преимущество механических датчиков в том, что никакие НИиОКР там не требуются, принцип прост и понятен, а качество результата зависит только от аккуратности исполнения тщательно продуманной конструкции.

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

Для флюгера и анемометра нужны следующие детали, которые пришлось заказать у токаря и фрезеровщика (количество и материал указаны сразу для обоих датчиков):

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

Механический датчик направления ветра - электронный флюгер

Основой флюгера (как и датчика скорости далее) служит П-образная скоба из дюраля Д-16, изображенная на чертеже вверху слева. В нижнее углубление запрессовывается кусочек фторопласта, в котором делается ступенчатое углубление последовательно сверлами 2 и 3 мм. В это углубление острым концом вставляется ось (для флюгера - из латуни). Сверху она свободно проходит через отверстие 8 мм. Над этим отверстием винтами М2 к скобе прикрепляется прямоугольный кусочек того же фторопласта толщиной 4 мм так, чтобы он перекрывал отверстие. Во фторопласте сделано отверстие точно по диаметру оси 6 мм (расположенное точно по общей оси отверстий - см. сборочный чертеж ниже). Фторопласт вверху и внизу здесь играет роль подшипников скольжения.


Ось в месте трения о фоторопласт можно отполировать, а площадь трения уменьшить, отзенковав отверстие во фторопласте. (См. на эту тему ниже UPD от 13.09.18 и 05.06.19 ). Для флюгера это не играет особой роли - некоторая «заторможенность» ему даже полезна, а для анемометра придется постараться минимизировать трение и инерцию.

Теперь о съеме величины угла поворота. Классический энкодер Грея на 16 положений применительно к нашему случаю выглядит так, как показано на рисунке:

Размер диска был выбран, исходя из условия надежной оптической изоляции пар излучатель-приемник друг от друга. При такой конфигурации щели шириной 5 мм располагаются с промежутком также 5 мм, а оптические пары расположены на расстоянии ровно 10 мм. Размеры скобы, к которой крепится флюгер, были рассчитаны именно исходя из диаметра диска 120 мм. Все это, конечно, можно уменьшить (особенно, если подобрать светодиоды и фотоприемники как можно меньшего диаметра), но было принята во внимание сложность изготовления энкодера: выяснилось, что фрезеровщики за такую тонкую работу не берутся, потому его пришлось выпиливать вручную надфилем. А тут чем больше размеры, тем надежнее результат и меньше хлопот.

На сборочном чертеже выше показано крепление диска к оси. Тщательно отцентрованный диск крепится винтиками М2 к капролоновой втулке. Втулка размещается на оси так, чтобы зазор вверху был минимальным (1-2 мм) - так, чтобы ось в нормальном положении вращалась свободно, а при перевороте острие не выпадало из гнезда внизу. Блоки фотоприемников и излучателей прикрепляются к скобе сверху и снизу диска, более конкретно об их конструкции далее.

Вся конструкция помещается в пластиковый (АБС или поликарбонат) корпус 150×150×90 мм. В собранном виде (без крышки и флюгера) датчик направления выглядит следующим образом:

Отметьте, что выбранное направление на север помечено стрелкой, его нужно будет соблюдать при установке датчика на место.

На верхушку оси крепится собственно флюгер. Он изготовлен на основе такой же латунной оси, в разрез на тупой стороне которой впаивается хвостовик из листовой латуни. На остром конце на некоторую длину нарезается резьба М6, и на ней с помощью гаек закрепляется круглый груз-противовес, отлитый из свинца:

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

Датчик скорости ветра - чашечный анемометр своими руками

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

Если для четырехбитного энкодера Грея требуется четыре оптопары, то для датчика скорости всего одна. По окружности диска на равном расстоянии просверлено 16 отверстий, таким образом один оборот диска в секунду эквивалентен 16 герцам частоты, поступающей с оптопары (можно больше отверстий, можно меньше - вопрос только в масштабе пересчета и экономии энергии на излучатели).

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

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

Мой вариант чашечного анемометра сделан на основе лазерного диска. Вид сверху и снизу показан на фото:



Чашки сделаны из донышек от бутылочек из-под детской воды «Агуша». Донышко аккуратно отрезается, причем все три - на одинаковом расстоянии, чтобы имели равный вес, локально прогревается по центру (ни в коем случае не грейте целиком - необратимо покоробится!) и тыльной стороной деревянной ручки от напильника выгибается наружу, чтобы сделать его более обтекаемым. Будете повторять - запаситесь бутылочками побольше количеством, из пяти-шести штук вам, вероятно, удастся сделать три более-менее одинаковых чашки. В изготовленных чашках делается сбоку прорезь и они закрепляются по периметру диска под 120° по отношению друг к другу с помощью водостойкого клея-герметика. Диск строго центруется относительно оси (я это делал с помощью вложенной металлической шайбы) и закрепляется на капролоновой втулке винтами М2.

Общая конструкция и установка датчиков

Оба датчика, как уже говорилось, размещаются в пластиковых корпусах 150×150×90 мм. К выбору материала корпуса надо подходить продуманно: АБС или поликарбонат имеют достаточную атмосферостойкость, но полистирол, оргстекло и тем более полиэтилен тут решительно не подойдут (и окрасить для защиты от солнца их тоже будет затруднительно). Если нет возможности приобрести фирменную коробку, лучше самостоятельно спаять корпус из фольгированного стеклотекстолита, и затем окрасить для защиты от коррозии и придания эстетического вида.

В крышке точно в месте выхода оси делается отверстие 8-10 мм, в которое тем же клеем-герметиком вклеивается пластиковый конус, вырезанный из носика от баллончика со строительным герметиком или клеем:

Чтобы отцентровать конус по оси, струбциной закрепите снизу крышки деревяшку, наметьте на ней точный центр и немного углубитесь перовым сверлом 12 мм, сделав вокруг отверстия кольцевое углубление. Конус туда должен войти точно, после чего его можно обмазывать клеем. Можно его дополнительно зафиксировать в вертикальном положении на время застывания винтом М6 с гайкой.

Датчик скорости сам накрывает ось с этим конусом, как зонтиком, предотвращая попадание воды внутрь корпуса. Для флюгера стоит дополнительно разместить над конусом втулку, которая закроет зазор между осью и конусом от прямого стока воды (см. фото общего вида датчиков далее).

Провода от оптопар у меня выведены на отдельный разъем типа D-SUB (см. фото датчика направления выше). Ответная часть с кабелем вставляется через прямоугольное отверстие в основании корпуса. Отверстие затем прикрывается крышкой с прорезью для кабеля, которая удерживает разъем от выпадания. К основанию корпуса привинчиваются дюралевые скобы для крепления на месте. Конфигурация их зависит от места установки датчиков.

В собранном виде оба датчика выглядят следующим образом:

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

Электронная часть

Метеостанция в целом состоит из двух модулей: выносного блока (который обслуживает оба датчика ветра, а также снимает показания с внешнего датчика температуры-влажности), и основного модуля с дисплеями. Выносной блок оборудован беспроводным передатчиком для отправки данных, установленным внутри него (антенна торчит сбоку). Основной модуль принимает данные от выносного блока (приемник для удобства его ориентации вынесен на кабеле в отдельный блок), а также снимает показания с внутреннего датчика температуры-влажности и выводит все это на дисплеи. Отдельная составляющая основного блока - часы с календарем, которые для удобства общей настройки станции обслуживаются отдельным контроллером Arduino Mini, и имеют свои дисплеи.

Выносной модуль и измерительная схема датчиков ветра

В качестве фотоизлучателей были выбраны светодиоды ИК-диапазона АЛ-107Б. Эти старинные светодиоды, конечно, не самые лучшие в своем классе, зато имеют миниатюрный корпус диаметром 2,4 мм и способны пропускать ток до 600 мА в импульсе. Между прочим, при испытаниях выяснилось, что образец этого светодиода около 1980 года выпуска (в корпусе красного цвета) имеет примерно вдвое большую эффективность (выразившуюся в дальности уверенной работы фотоприемника), чем современные экземпляры, купленные в «Чипе-Дипе» (они имеют прозрачный желтовато-зеленый корпус). Вряд ли в 1980 году кристаллы были лучше, чем сейчас, хотя чем черт не шутит? Возможно, однако, дело в разных углах рассеяния в том и другом оформлении.

Через светодиод в датчике скорости пропускался постоянный ток около 20 мА (резистор 150 Ом при питании 5 вольт), а в датчике направления - импульсный (меандр со скважностью 2) ток около 65 мА (те же 150 Ом при питании 12 вольт). Средний ток через один светодиод датчика направления при этом около 33 мА, всего через четыре канала - около 130 мА.

В качестве фотоприемников были выбраны фототранзисторы L-32P3C в корпусе диаметром 3 мм. Сигнал снимался с коллектора, нагруженного на резистор 1,5 или 2 кОм от питания 5 В. Эти параметры подобраны так, чтобы на расстоянии ~20 мм между фотоизлучателем и приемником на вход контроллера поступал сразу полноразмерный логический сигнал в 5-вольтовых уровнях без дополнительного усиления. Токи, фигурирующие здесь, могут показаться вам несоразмерно большими, если исходить из озвученного выше требования минимального энергопотребления, но как вы увидите, фигурируют они в каждом цикле измерения на протяжении максимум нескольких миллисекунд так, что общее потребление остается небольшим.

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

Принципиальная схема блока обработки датчиков ветра выглядит так:

О том, откуда берется питание 12-14 вольт, см. далее. Кроме компонентов, указанных на схеме, выносной блок содержит датчик температуры-влажности, который на схеме не показан. Делитель напряжения, подключенный к выводу A0 контроллера, предназначен для контроля напряжения источника питания с целью своевременной замены. Светодиод, подключенный к традиционному выводу 13 (вывод 19 корпуса DIP) - суперяркий, для его нормального, не слепящего свечения достаточно тока в доли миллиампера, что и обеспечивается необычно высоким номиналом резистора 33 кОм.

В схеме используется «голый» контроллер Atmega328 в DIP-корпусе, запрограммированный через Uno и установленный на панельку. Такие контроллеры с уже записанным Arduino-загрузчиком, продаются, например, в «Чипе-Дипе» (или загрузчик можно записать самостоятельно). Такой контроллер удобно программировать в привычной среде, но, лишенный компонентов на плате, он во-первых, получается экономичнее, во-вторых, занимает меньше места. Полноценный энергосберегающий режим можно было бы получить, избавившись и от загрузчика тоже (и вообще расписав весь код на ассемблере:), но здесь это не очень актуально, а программирование при этом неоправданно усложняется.

На схеме серыми прямоугольниками обведены компоненты, относящиеся отдельно к каналам скорости и направления. Рассмотрим функционирование схемы в целом.

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

В начале программы сделаны следующие объявления библиотек и глобальных переменных (чтобы не загромождать текст и без того обширных примеров, здесь выпущено все, что относится к датчику температуры-влажности):

#include #include #include . . . . . #define ledPin 13 //вывод светодиода (PB5 вывод 19 ATmega) #define IR_Pin 10 //управление транзистором IRLU (PB2 вывод 16 Atmega) #define in_3p 9 //вход приемника разряд 3 #define in_2p 8 //вход приемника разряд 2 #define in_1p 7 //вход приемника разряд 1 #define in_0p 6 //вход приемника разряд 0 #define IR_PINF 5 //(PD5,11) вывод для ИК-светодиода частоты #define IN_PINF 4 //(PD4,6) вход обнаружения частоты volatile unsigned long ttime = 0; //Период срабатывания датчика float ff; //значения частоты датчика скорости для осреднения char msg; //посылаемый месседж byte count=0;//счетчик int batt; //для осреднения батарейки byte wDir; //массив направлений ветра byte wind_Gray=0; //байт кода направления ветра
Для инициации режима сна и WDT (пробуждение каждые 4 с) служат следующие процедуры:

// перевод системы в режим сна void system_sleep() { ADCSRA &= ~(1 << ADEN); //экв. cbi(ADCSRA,ADEN); выключим АЦП set_sleep_mode(SLEEP_MODE_PWR_DOWN); // режим сна sleep_mode(); // система засыпает sleep_disable(); // система продолжает работу после переполнения watchdog ADCSRA |= (1 << ADEN); /экв. sbi(ADCSRA,ADEN); включаем АЦП } //**************************************************************** // ii: 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec void setup_watchdog(int ii) { byte bb; if (ii > 9) ii=9; bb=ii & 7; if (ii > 7) bb|= (1<<5); //в bb - код периода bb|= (1< Датчик скорости выдает частоту прерывания оптического канала, порядок величин - единицы-десятки герц. Мерить такую величину экономичнее и быстрее через период (этому была посвящена публикация автора «Оценка методов измерения низких частот на Arduino »). Здесь выбран метод через модифицированную функцию pulseInLong(), который не привязывает измерение к определенным выводам контроллера (текст функции periodInLong() можно найти в указанной публикации).

В функции setup() объявляются направления выводов, инициализируются библиотека передатчика 433 МГц и сторожевой таймер (строка для IN_PINF в принципе лишняя, и вставлена для памяти):

Void setup() { pinMode(IR_PINF, OUTPUT); //на выход pinMode(IN_PINF, INPUT); //вывод обнаружения частоты на вход pinMode(13, OUTPUT); //светодиод vw_setup(1200); // скорость соединения VirtualWire vw_set_tx_pin(2); //D2, PD2(4) вывод передачи VirtualWire // Serial.begin(9600); // Serial-порт для контроля при отладке setup_watchdog(8); //WDT период 4 c wdt_reset(); }
Наконец, в основном цикле программы мы сначала каждый раз при пробуждении (каждые 4 секунды) считываем напряжение и рассчитываем частоту датчика скорости ветра:

Void loop() { wdt_reset(); //обнуляем таймер digitalWrite(ledPin, HIGH); //включаем светодиод для контроля batt=analogRead(0); //читаем и сохраняем текущий код батарейки /*=== частота ==== */ digitalWrite(IR_PINF, HIGH); //включаем ИК-светодиод датчика скорости float f=0; //переменная для частоты ttime=periodInLong(IN_PINF, LOW, 250000); //ожидание 0,25 сек // Serial.println(ttime); //для контроля при отладке if (ttime!=0) {//на случай отсутствия частоты f = 1000000/float(ttime);} // вычисляем частоту сигнала в Гц digitalWrite(IR_PINF, LOW); //выключаем ИК-светодиод ff=f; //сохраняем вычисленное значение в массиве. . . . .
Время горения ИК-светодиода (потребляющего, напомню, 20 мА) здесь, как видите, будет максимальным при отсутствии вращения диска датчика и составляет при этом условии около 0,25 секунды. Минимальная измеряемая частота, таким образом, составит 4 Гц (четверть оборота диска в секунду при 16 отверстиях). Как выяснилось при калибровке датчика (см. далее), это соответствует примерно 0,2 м/с скорости ветра Подчеркнем, что это минимальная измеряемая величина скорости ветра, но не разрешающая способность и не порог трогания (который окажется гораздо выше). При наличии частоты (то есть при вращении датчика) время измерения (и, соответственно, время горения LED, то есть потребление тока) будет пропорционально уменьшаться, а разрешающая способность - увеличиваться.

Далее следуют процедуры, которые выполняются каждое четвертое пробуждение (то есть каждые 16 секунд). Значение частоты датчика скорости из накопленных четырех значений мы передаем не среднее, а максимальное - как показал опыт, это более информативная величина. Каждую из величин, независимо от ее типа, для удобства и единообразия мы перед передачей превращаем в целое положительное число размером в 4 десятичных разряда. За отсчетом числа пробуждений следит переменная count:

//каждые 16 сек усредняем батарейку и определяем максимальное значение //частоты из 4-х значений: if (count==3){ f=0; //значение частоты for (byte i=0; i<4; i++) if (f Далее - определение кода Грея направления. Здесь для снижения потребления вместо постоянно включенных ИК-светодиодов на все четыре канала одновременно через ключевой полевой транзистор с помощью функции tone() подается частота 5 кГц. Обнаружение наличия частоты на каждом из разрядов (выводы in_0p – in_3p) производится методом, аналогичным антидребезгу при считывании показаний нажатой кнопки. Сначала в цикле дожидаемся, имеется ли на выводе высокий уровень, и затем проверяем его через 100 мкс. 100 мкс есть полпериода частоты 5 кГц, то есть при наличии частоты минимум со второго раза мы опять попадем на высокий уровень (на всякий случай повторяем четыре раза) и это означает, что он точно там есть. Эту процедуру повторяем для каждого из четырех бит кода:

/* ===== Wind Gray ==== */ //направление: tone(IR_Pin,5000);//частоту 5 кГц на транзистор boolean yes = false; byte i=0; while(!yes){ //разряд 3 i++; boolean state1 = (digitalRead(in_3p)&HIGH); delayMicroseconds(100); // задержка в 100 микросекунд yes=(state1 & !digitalRead(in_3p)); if (i>4) break; //пробуем четыре раза } if (yes) wDir=1; else wDir=0; yes = false; i=0; while(!yes){ //разряд 2 i++; boolean state1 = (digitalRead(in_2p)&HIGH); delayMicroseconds(100); // задержка в 100 микросекунд yes=(state1 & !digitalRead(in_2p)); if (i>4) break; //пробуем четыре раза } if (yes) wDir=1; else wDir=0; yes = false; i=0; while(!yes){ //разряд 1 i++; boolean state1 = (digitalRead(in_1p)&HIGH); delayMicroseconds(100); // задержка в 100 микросекунд yes=(state1 & !digitalRead(in_1p)); if (i>4) break; //пробуем четыре раза } if (yes) wDir=1; else wDir=0; yes = false; i=0; while(!yes){ //разряд 0 i++; boolean state1 = (digitalRead(in_0p)&HIGH); delayMicroseconds(100); // задержка в 100 микросекунд yes=(state1 & !digitalRead(in_0p)); if (i>4) break; //пробуем четыре раза } if (yes) wDir=1; else wDir=0; noTone(IR_Pin); //выключаем частоту //собираем в байт в коде Грея: wind_Gray=wDir+wDir*2+wDir*4+wDir*8; //прямой перевод в дв. код int wind_G=wind_Gray*10+1000; //дополняем до 4-х дес. разрядов. . . . .
Максимальная длительность одной процедуры будет при отсутствии частоты на приемнике и равна 4×100 = 400 микросекунд. Максимальное время горения 4-х светодиодов направления будет тогда, когда не засвечен ни один приемник, то есть 4×400 = 1,6 миллисекунды. Алгоритм, кстати, точно так же будет работать, если вместо частоты, период которой кратен 100 мкс, просто подать постоянный высокий уровень на светодиоды. При наличии меандра вместо постоянного уровня мы просто экономим питание вдвое. Мы можем еще сэкономить, если завести каждый ИК-светодиод через отдельную линию (соответственно, через отдельный вывод контроллера со своим ключевым транзистором), но зато при этом усложняется схема, разводка и управление, а ток в 130 мА в течение 2 мс каждые 16 секунд - это, согласитесь, немного.

Наконец, беспроводная передача данных . Для передачи данных от места установки датчиков до табло метеостанции был выбран самый простой, дешевый и надежный способ: пара передатчик/приемник на частоте 433 МГц . Согласен, способ не самый удобный (из-за того, что девайсы рассчитаны на передачу битовых последовательностей, а не целых байтов, приходится изощряться в конвертации данных между нужными форматами), и уверен, что многие со мной захотят поспорить в плане его надежности. Ответ на последнее возражение простой: «ты просто не умеешь их готовить!».

Секрет в том, что обычно остается за кадром различных описаний обмена данными по каналу 433 МГц: поскольку приборы эти чисто аналоговые, то питание приемника должно быть очень хорошо очищено от любых посторонних пульсаций. Ни в коем случае не следует питать приемник от внутреннего 5-вольтового стабилизатора Arduino! Установка для приемника отдельного маломощного стабилизатора (LM2931, LM2950 или аналогичного) непосредственно поблизости от его выводов, с правильными цепями фильтрации на входе и выходе, радикально повышает дальность и надежность передачи.

В данном случае передатчик работал непосредственно от напряжения аккумулятора 12 В, приемник и передатчик были снабжены стандартными самодельными антеннами в виде отрезка провода длиной 17 см. (Напомню, что провод для антенн пригоден только одножильный, а размещать антенны в пространстве необходимо параллельно друг другу.) Пакет информации длиной в 24 байта (с учетом влажности и температуры) без каких-то проблем уверенно передавался со скоростью 1200 бит/с по диагонали через садовый участок 15 соток (около 40-50 метров), и затем через три бревенчатых стенки внутрь помещения (в котором, например, сотовый сигнал принимается с большим трудом и не везде). Условия, практически недостижимые для любого стандартного способа на 2,4 ГГц (типа Bluetooth, Zig-Bee и даже любительский Wi-Fi), притом, что потребление передатчика здесь составляет жалкие 8 мА и только в момент собственно передачи, остальное время передатчик потребляет сущие копейки. Передатчик конструктивно размещен внутри выносного блока, антенна торчит сбоку горизонтально.

Объединяем все данные в один пакет (в реальной станции к нему добавятся еще температура и влажность), состоящий из единообразных 4-байтных частей и предваряемый сигнатурой «DAT», отправляем его на передатчик и завершаем все циклы:

/*=====Transmitter=====*/ String strMsg="DAT"; //сигнатура - данные strMsg+=volt; //присоединяем батарейку 4 разряда strMsg+=wind_G; //присоединяем wind 4 разряда strMsg+=fi; //присоединяем частоту 4 разряда strMsg.toCharArray(msg,16); //переводим строку в массив // Serial.println(msg); //для контроля vw_send((uint8_t *)msg, strlen(msg)); // передача сообщения vw_wait_tx(); // ждем завершения передачи - обязательно! delay(50); //+ еще на всякий случай задержка count=0; //обнуляем счетчик }//end count==3 else count++; digitalWrite(ledPin, LOW); //гасим сигнальный светодиод system_sleep(); //систему - в сон } //end loop
Размер пакета можно сократить, если отказаться от требования представления каждой из величин разнообразных типов в виде единообразного 4-байтового кода (например, для кода Грея, конечно, хватит и одного байта). Но универсализации ради я оставил все как есть.

Питание и особенности конструкции выносного блока . Потребление выносного блока подсчитываем таким образом:

20 мА (излучатель) + ~20 мА (контроллер со вспомогательными цепями) в течение примерно 0,25 с каждые четыре секунды - в среднем 40/16 = 2,5 мА;
- 130 мА (излучатели) + ~20 мА (контроллер со вспомогательными цепями) в течение примерно 2 мс каждые 16 секунд - в среднем 150/16/50 ≈ 0,2 мА;

Накинув на этот расчет потребление контроллера при съеме данных с датчика температуры-влажности и при работе передатчика, смело доводим среднее потребление до 4 мА (при пиковом около 150 мА, заметьте!). Батарейки (которых, кстати, потребуется аж 8 штук для обеспечения питания передатчика максимальным напряжением!) придется менять слишком часто, потому возникла идея питать выносной блок от 12-вольтовых аккумуляторов для шуруповерта - их у меня образовалось как раз две штуки лишних. Емкость их даже меньше, чем соответствующего количества АА-батареек - всего 1,3 А часа, но зато никто не мешает их менять в любое время, держа наготове второй заряженный. При указанном потреблении 4 мА емкости 1300 мА часов хватит примерно на две недели, что получается не слишком хлопотно.

Отметим, что напряжение свежезаряженного аккумулятора может составить до 14 вольт. На этот случай поставлен входной стабилизатор 12 вольт - чтобы не допустить перенапряжений питания передатчика и не перегружать основной пятивольтовый стабилизатор.

Выносной блок в подходящем пластиковом корпусе размещается под крышей, к нему на разъемах подведен кабель питания от аккумулятора и соединения с датчиками ветра. Основная сложность в том, что схема оказалась крайне чувствительной к влажности воздуха: в дождливую погоду уже через пару часов начинает сбоить передатчик, измерения частоты показывают полную кашу, а измерения напряжения аккумулятора показывают «погоду на Марсе».

Поэтому после отладки алгоритмов и проверки всех соединений корпус необходимо тщательно герметизировать. Все разъемы в месте входа в корпус промазываются герметиком, то же самое касается всех головок винтов, торчащих наружу, выхода антенны и кабеля питания. Стыки корпуса промазываются пластилином (с учетом того, что их придется разнимать), и дополнительно проклеиваются сверху полосками сантехнического скотча. Неплохо дополнительно аккуратно укрепить эпоксидкой используемые разъемы внутри: так, указанный на схеме выносного модуля DB-15 сам по себе не герметичен, и между металлическим обрамлением и пластиковой основой будет медленно просачиваться влажный воздух.

Но все эти меры сами по себе дадут только кратковременный эффект - даже если не будет подсоса холодного влажного воздуха, то сухой воздух из комнаты легко превращается во влажный при падении температуры снаружи корпуса (вспомните про явление, называемое «точка росы»).

Чтобы этого избежать, необходимо внутри корпуса оставить патрончик или мешочек с влагопоглотителем - силикагелем (мешочки с ним иногда вкладывают в коробки с обувью или в некоторые упаковки с электронными устройствами). Если силикагель неизвестного происхождения и долго хранился, его перед использованием необходимо прокалить в электродуховке при 140-150 градусах несколько часов. Если корпус герметизирован как следует, то менять влагопоглотитель придется не чаще, чем в начале каждого дачного сезона.

Основной модуль

В основном модуле все величины принимаются, расшифровываются, если надо, преобразуются в соответствии с калибовочными уравнениями и выводятся на дисплеи.

Приемник вынесен за пределы корпуса основного модуля станции и помещен в маленькую коробочку с ушками для крепления. Антенна выведена через отверстие в крышке, все отверстия в корпусе загерметизированы сырой резиной. Контакты приемника выведены на очень надежный отечественный разъем типа РС-4, со стороны приемника он подключен через отрезок сдвоенного экранированного AV-кабеля:

По одной из жил кабеля снимается сигнал, по другой подается питание в виде «сырых» 9 вольт от адаптера питания модуля. Стабилизатор типа LM-2950-5.0 вместе с фильтрующими конденсаторами установлен в коробочке вместе с приемником на отдельной платке.

Производились эксперименты по увеличению длины кабеля (на всякий случай - вдруг через стенку не заработало бы?), в которых выяснилось, что в пределах длины до 6 метров ничего не меняется.

Дисплеев типа OLED всего четыре: два желтых обслуживают метеоданные, два зеленых часы и календарь. Размещение их показано на фото:

Обратите внимание, что в каждой группе один из дисплеев - текстовый, второй - графический, с искусственно созданными шрифтами в виде картинок глифов. Здесь мы в дальнейшем на вопросе вывода информации на дисплеи останавливаться не будем, чтобы не раздувать и без того обширный текст статьи и примеров: из-за наличия картинок глифов, которые приходится выводить индивидуально (зачастую простым перечислением вариантов путем оператора case) программы вывода могут быть весьма громоздки. О том, как обращаться с таким дисплеями, см. публикацию автора «Графический и текстовый режим дисплеев Winstar », где есть в том числе и пример дисплея для вывода данных ветра.

Принципиальная схема. Часы и их дисплеи для удобства настройки обслуживаются отдельным контроллером Arduino Mini и больше мы их здесь разбирать не будем. Схема подключения компонентов к Arduino Nano, управляющим приемом и выводом метеоданных, следующая:

Здесь, в отличие от выносного модуля, показано подключение метеодатчиков - барометра и внутреннего датчика температуры-влажности. Следует обратить внимание на разводку питания - дисплеи питаются от отдельного стабилизатора 5 В типа LM1085. От него же естественно запитать дисплеи часов, однако в этом случае контроллер часов также должен питаться от этого же напряжения, причем через вывод 5 В, а не Vin (для Mini Pro последний называется RAW). Если запитать контроллер часов так же, как Nano - 9 вольтами через вывод RAW, то его внутренний стабилизатор будет конфликтовать с внешними 5-ю вольтами и в этой борьбе, естественно, победит сильнейший, то есть LM1085, а Mini останется вовсе без питания. Также во избежание всяческих неприятностей перед программированием Nano и особенно Mini (то есть перед подключением USB-кабеля) внешний адаптер следует отключать.

На стабилизаторе LM1085 при подключении всех четырех дисплеев будет выделяться мощность около ватта, потому его следует установить на маленький радиатор около 5-10 см2 из алюминиевого или медного уголка.

Прием и обработка данных. Здесь я воспроизвожу и комментирую только фрагменты программы, относящиеся к данным ветра, о других датчиках несколько слов далее.

Для приема сообщения по каналу 433 МГц применим стандартный способ, описанный во множестве источников. Подключаем библиотеку и объявляем переменные:

#include . . . . . int volt; //напряжение акуумулятора в условном целом коде float batt; //реальная величина - напряжение аккумулятора byte wDir; //направление в коде Грея uint16_t t_time = 0; //интервал времени приема char str; //строка для данных uint8_t buf; //переменная для принятого сообщения uint8_t buflen = VW_MAX_MESSAGE_LEN; // max длина принятого сообщения. . . . .
С величиной размера буфера buflen связана одна особенность: объявить ее значение (VW_MAX_MESSAGE_LEN) один раз в начале программы недостаточно. Так как в функции приема (см. далее) эта переменная фигурирует по ссылке, то размер сообщения по умолчанию приходится обновлять каждый цикл. Иначе из-за приема испорченных сообщений значение buflen будет каждый раз укорачиваться, пока вы не начнете получать всякую чушь вместо данных. В примерах обе эти переменные обычно объявляют локально в цикле loop(), потому размер буфера обновляется автоматически, а здесь мы просто будем повторять присваивание нужного значения в начале каждого цикла.

В процедуре setup делаем следующие установки:

Void setup() { delay (500); //для устаканивания питания дисплеев pinMode(16,INPUT_PULLUP); //вывод для кнопки vw_setup(1200); // Скорость соединения VirtualWire vw_set_rx_pin(17); //A3 Вывод приемника VirtualWire . . . . .
Перед тем, как что-то принимать, проверяется интервал времени t_time, прошедшего с последнего приема. Если он превысил разумные пределы (например, 48 секунд - трехкратное время повтора сообщений с внешнего блока), то это воспринимается, как потеря датчика и каким-то образом индицируется на дисплее:

Void loop() { vw_rx_start(); // Готовность приема buflen = VW_MAX_MESSAGE_LEN; //размер буфера каждый раз заново if ((int(millis()) - t_time) > 48000) //если t_time не обновлялось более 48 сек { <отображаем прочерк на дисплее> }//end датчик не найден if (vw_have_message()) { //ждем приема if (vw_get_message(buf, &buflen)) // Если данные приняты { vw_rx_stop(); //останавливаем прием на время t_time = millis(); //обновляем t_time for (byte i=0;i<3;i++) // Получить первые три байта str[i]= buf[i]; str="\0"; if((str=="D")&&(str=="A")&&(str=="T")) { //сигнатура принята //принимаем данные: for (byte i=3;i<7;i++) // извлечь четыре байта аккумулятора str= buf[i]; // упаковать их в строку volt=atoi(str); //преобразовать в целое число volt=(volt/10)-100; //удаляем добавки до 4-х байт batt=float(volt)/55.5; //преобразуем в реальный вид напряжения в вольтах //и пока храним в глобальной переменной for (byte i=7;i<11;i++) // извлечь четыре байта направления str= buf[i]; // упаковать их в строку int w_Dir=atoi(str); //преобразовать в целое число w_Dir=(w_Dir-1000)/10; //возвращаем к исходному виду wDir=lowByte(w_Dir); //младший байт - код Грея <выводим направление на дисплей через оператор case> . . . . .
Коэффициент 55.5 - пересчет значения кода АЦП в реальное напряжение, его величина зависит от опорного напряжения и величин резисторов делителя.

Кстати, код Грея имеет одну особенность: в нем неважен порядок бит, все свои свойства код сохраняет при любой их перестановке. А так как при расшифровке мы здесь все равно рассматриваем каждый случай отдельно, то биты можно рассматривать в любом порядке и даже путать при подключении. Другое дело, если бы захотели это дело как-то упорядочить - например, создать массив значений направления («с», «ссз», «сз», «зсз», «з» и т.д.), и вместо индивидуального рассмотрения каждого варианта извлекать обозначения по номеру в этом массиве. Тогда пришлось бы преобразовывать код Грея в упорядоченный двоичный, и порядок бит играл бы существенную роль.

И, наконец, извлекаем значение скорости и закрываем все операторы:

For (byte i=19;i<23;i++) // Получить четыре байта частоты str= buf[i]; // упаковать их в строку int wFrq=atoi(str); //преобразовать в целое число wFrq = (wFrq-1000)/10; //удаляем добавки до 4-х байт wFrq=10+0.5*wFrq;//скорость в целом виде с десятыми <отображаем ее на дисплее поразрядно> }//end if str=DAT }//end vw_get_message } //end vw_have_message(); . . . . .
Здесь 10+0.5*wFrq - калибровочное уравнение. 10 дм/с (то есть 1.0 метра в секунду) есть порог трогания, а 0,5 - коэффициент пересчета частоты в скорость (в дм/сек). При нулевом значении входной частоты это уравнение выдает 10 дм/с, потому следует отдельно позаботиться, чтобы при этом выводить не 1 м/с, а именно нулевое значение. Калибровать датчик скорости можно с помощью любого самого дешевого ручного анемометра и настольного вентилятора. Не пытайтесь определить порог трогания экспериментально - гораздо точнее получится, если отметить две-три точки калибровочной прямой значения скорости V от частоты F: V = Vп + K×F при разных скоростях потока, тогда порог трогания определится автоматически, как величина Vп (ордината точки пересечения этой прямой с осью скоростей).

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

If (digitalRead(16)==LOW){ //кнопка нажата <выводим напряжение на дисплей, затирая значение температуры-влажности> }//конец кнопка delay(500); }//конец loop
Кнопка у меня была, как видно из схемы, с перекидным контактом, но ничто не мешает установить обычную с замыкающим, подключив ее к питанию через резистор. Можно также добавить к этому мигание символов на дисплее в случае, если напряжение аккумулятора снизится ниже, например, 10 вольт, как знак, что его пора менять.

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

Библиотеку для его подключения можно найти .

Сконструирован SHT-75 довольно по-дурацки: металлическая подложка платы отлично проводит тепло, потому его необходимо целиком выносить за пределы корпуса. Иначе наличия одного только контроллера типа ATmega328 со стабилизатором питания в замкнутом корпусе достаточно, чтобы через подложку платы подогреть датчик на пару градусов даже в случае, если его головка вынесена наружу. Моя схема с датчиками ветра, с ее токами в 20-130 мА (пусть даже текущими ничтожные миллисекунды) подогревала SHT-75 градусов на пять, поэтому он был вынесен наружу и установлен отдельно на пластиковую пластину, торчащую из корпуса вбок.

Данные с SHT-75 снимаются тем же контроллером, что и данные датчиков ветра, и посылаются из выносного модуля в едином пакете через беспроводной канал 433 МГц. Для передачи предварительно они также приводятся к формату 4-байтовой строки.

Для измерения температуры и влажности внутри помещения был выбран банальный DHT-22 - поскольку диапазон там невелик в сравнении с улицей, то совершено безразлично, какой датчик использовать (кроме, разумеется, DHT-11, который вообще использовать не следует ни при каких обстоятельствах, в целевом назначении он просто неработоспособен). Температура DHT-22 была подправлена по измерениям ртутным термометром (с SHT-75 они полностью совпали!), а влажность слегка подрихтована сравнением с SHT-75. Поправки вводятся непосредственно перед индикацией на дисплее.

Кстати, DHT-22 тоже необходимо выносить подальше от корпуса с дисплеями - иначе он будет неизбежно подогреваться и врать. Я его закрепляю на пластиковом креплении внизу корпуса, на расстоянии миллиметров десять от него. Это обстоятельство, кстати, как я подозреваю, одна из причин (кроме отсутствия индивидуальной калибровки) того, что все фирменные бытовые метеостанции RST и Oregon безбожно врут в показаниях, имея разброс даже сами с собой (внутренний датчик с наружным) в два-три градуса и до десятка процентов влажности.

Барометр не представляет проблем, поскольку почти все имеющиеся в продаже сделаны на одной и той же основе - микроэлектромеханической (MEMS) микросхеме BMP180 или ее модификациях. Мой личный опыт попытки использования более редко встречающейся разновидности на основе LPS331AP был отрицательным: библиотеку для нее найти труднее, и в довершение был обнаружен конфликт с другими устройствами на I2C-шине. Показания барометра, возможно, придется подогнать по месту установки - каждые 10-12 метров высоты над уровнем моря снижают давление на 1 мм.рт. ст. Поэтому из показаний придется вычесть (или добавить) некую величину, чтобы величина давления соответствовала показаниям официальной метеостанции в данной местности.

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

UPD от 30.06.17. Установил питание от солнечной батареи. Комплект отсюда:
солнечная панель
контроллер
АКБ
Все вместе + доставка по Москве в пределах 2,5 тыр. Работает безупречно.
Интересна методика подсчета мощности солнечной батареи и АКБ, которую предлагают консультанты с этого сайта. Пример расчета на 3 Вт потребляемой мощности (у меня гораздо меньше), цитирую:
«3Вт умножаем на 24ч и делим на 6 = 12Ач это минимальная емкость аккумулятора
3Вт умножаем на 24ч и делим на 3ч = 24Вт это минимальная мощность солнечной батареи»
Без комментариев.
В моем случае получившаяся мощность солнечной энергоустановки в десятки раз превышает необходимую при самых плохих погодных условиях. Поэтому в контроллере датчика можно особо не заботиться об энергосбережении, и применить любые необходимые частоты снятия показаний и осреднения величин.

UPD от 13.09.18. За почти два сезона эксплуатации выявились сильные и слабые стороны станции. Слабые - прежде всего то, что цикл обновления показаний в 16 секунд (из четырех серий измерений), как это было изначально, слишком длинный. Установка солнечной батареи с буферным аккумулятором позволила не думать об энергосбережении и поиграться с длительностью цикла. В результате цикл был установлен в 8 секунд (четыре измерения через две секунды).
Из механических усовершенствований был введен твердый подпятник под острие датчика скорости (да, меня еще тогда предупреждали о его необходимости, но я тогда не придумал, как его сделать). Через некоторое время ось датчика полностью пропилила фторопластовую опору и порог трогания резко возрос (на чувствительности флюгера это, кстати, совершенно не сказалось). Потому опора была заменена на подпятник из нержавейки, в котором тонким сверлом сделано небольшое углубление. Предчувствую, что придется потом еще что-то придумывать с острием, которое, как и вся ось, сделано из дюраля. Но я отложил это до момента, когда датчик все равно придется переделывать: лазерный диск, взятый за основу конструкции, за два сезона помутнел от солнца и начал растрескиваться.

UPD от 05.06.19.
О переделке датчика (флюгер оставлен тот же самый). Датчик скорости пришлось переделать и из-за стершейся оси и из-за пришедшего в негодность лазерного диска. Основа конструкции оставлена той же самой, но новый лазерный диск покрашен золотистой краской из баллончика. Решение для острия оси нашлось в следующем виде. В дюралевой оси было высверлено углубление точно по центру, и туда вставлен на секундном клее обрезок верхушки китайского метчика на 3 мм. Верхушка у метчика представляет собой хорошо отцентрованный конус с углом около 70-80 град., он был дополнительно отполирован шкуркой-нулевкой и затем пастой ГОИ. В качестве основания я использовал головку нержавеющего винта М3 со спиленным шлицем, в которой обычным сверлом D=2 мм намечено небольшое углубление по центру. Этот винт заворачивался прямо в углубление во фторопласте, пропиленное осью ранее, чем обеспечивалась центровка.
Кончик оси смазывался графитовой смазкой для защиты от коррозии (так как нержавеющие свойства метчика мне неизвестны). После некоторой притирки порог трогания снизился настолько, что его стало невозможно измерить фирменным анемометром, у которого порог составляет около 0,3-0,5 см/с. По косвенным данным (построением прямой по двум точкам) был волюнтаристски принят порог в 0,3 м/с, хотя, вероятно, он несколько меньше.

Главное изменение в алгоритмах обсчета также касается датчиков ветра, и я посчитал полезным вынести это в .

Метеостанция построена на Picaxe микроконтроллере от Revolution Education Ltd и состоит из двух основных частей: наружный блок, который посылает свои данные каждые 2 секунды, используя передатчик на частоте 433МГц. И внутренний блок, который отображает полученные данные на 20 х 4 ЖК-дисплее, а также атмосферное давление, которое измеряется локально во внутреннем блоке.

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

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

Уличные датчики

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

Датчик температуры и относительной влажности воздуха

Измерение температуры, пожалуй, проще всего. Для это используется датчик DS18B20. Для измерения влажности был использован HIH-3610, выдающий напряжение 0.8 - 3.9В при влажности 0% до 100%

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

Упрощенный код для каждого из датчиков приведен ниже. Более точный код, который считывает значения с точностью до одной десятой, показан на сайте Питера Андерсона . Его код используется в окончательном варианте метеостанции.

Датчик температуры обеспечивает точность ± 0.5 °C. Датчик влажности обеспечивает точность до ± 2%, так что это не очень важно, сколько знаков доступно после запятой!

Пример участка из программного обеспечения, работающего на ПК.

Температура

Main: readtemp B.6, b1 ; read value into b1 if b1 > 127 then neg ; test for negative sertxd (#b1, cr, lf) ; transmit value to PE terminal pause 5000 goto main neg: b1 = b1 - 128 ; adjust neg value sertxt ("-") ; transmit negative symbol sertxt (#b1, cr, lf) ; transmit value to PE terminal pause 5000 goto main

Влажность

Main: readadc B.7,b1 ; read humidity value b1 = b1 - 41 * 100 / 157 ; change to %RH sertxd (#b1, "%", cr, lf) pause 5000 ; wait 5 seconds goto main

Расчет показаний датчика влажности

Расчеты взяты из документации датчика Honeywell HIH-3610. На графике показывана стандартная зависимость при 0 °C.

Напряжение с датчика измеряется на входе АЦП (B.7) микроконтроллера Picaxe 18M2. В коде, показанном выше, значение, которое представлено в виде числа от 0 до 255 (т.е. 256 значений), хранится в переменной b1.

Наша схема питается от 5В, так что каждый шаг АЦП равен:
5/256 = 0.0195 В.

На графике видно начально значение АЦП 0.8 В:
0.8 / 0.0195 = 41

Взяв значения из графика, наклон графика (с учетом смещения) примерно:
Напряжение выхода / % относительной влажности или
(2.65 - 0.8) / 60 = 0.0308 В в% RH
(В документации 0.0306)

Рассчитаем кол-во шагов АЦП на 1% влажности:
(В на % RH) / (шаг АЦП)
0.0308 / 0.0195 = 1.57

% RH = значение с АЦП - смещение АЦП / (шаги АЦП в % RH), или
% RH = значение с АЦП - 41 / 1.57

Итоговая формула расчет для микроконтроллера будет выглядеть: % RH = значение с АЦП - 41 * 100/157

Защитный корпус

Начните с разрезания каждой панели на две части. Планки на одной части будут крепко прикреплены с двух сторон, а на второй части только с одной стороны. Не выбрасывайте эти части - они используются.

К целым частям прикрепите два деревянных бруска 20мм х 20мм сверху и с низу, и прикрутите к ним другие части.

Обрежьте одну из частей с одной целой стороной по размеру и приклейте ее к внутренней стороне одной из сторон. Убедитесь, что планки приклеены так, что образуют вместе "^" форму. Сделайте так со всеми сторонами.

Измеритель скорости и направления ветра

Механическая часть

Датчики скорости и направления ветра представляют собой сочетание механических и электронных компонентов. Механическая часть идентична для обеих датчиков.

12мм вставка из фанеры (marine ply) находится между трубой из ПВХ и диском из нержавеющей стали в верхнем конце трубы. Подшипник приклеен к диску из нержавеющей стали и удерживается нержавеющей пластиной.

Как только все будет полностью собрано и настроено, открытые места герметизируются герметиком для водонепроницаемости.

Остальные три отверстия на фотографии предназначены для лопастей. Лопасти длиной 80 мм дают радиус поворота 95мм. Чашки 50 мм в диаметре. Для них я использовал обрезанные флаконы от одеколона, которые имеют почти сферическую форму. Я не уверен в их надёжности, поэтому сделал их легкозаменяемыми.

Электронная часть

Электроника для датчика скорости ветра состоит только из транзисторного ключа, фотодиода и двух резисторов. Они монтируются на небольшой круглой ПП диаметром 32мм. Они установлены в трубе свободно, чтобы влага в случае её попадания стекала вниз не задевая электронику.

Анемометр - один из трех датчиков, который необходимо откалибровать (два других – счетчик осадков и датчик атмосферного давления)

Фотодиод обеспечивает два импульса за один оборот. В простой «последовательной» системе, к которой я стремился (все датчик опрашиваются поочередно), должен быть компромисс между длиной времени, затрачиваемого на опрос каждого датчика (в данном случае, подсчет импульсов) и отзывчивость системы в целом. В идеале, на полный цикла опроса всех датчиков должно уйти не более 2-3 секунд.

На фото выше проверка датчика при помощью мотора с регулируемыми оборотами.

; LCD-specific commands shown in blue hsersetup B9600_4, %10000 ; Use LCD Pin 1, no hserin hserout 0, (13) : pause 100 ; Initialize LCD hserout 0, (13) : pause 100 hserout 0, (13) : pause 100 pause 500 hserout 0, ("ac1", 13) ; Clear display pause 50 hserout 0, ("acc", 13) hserout 0, ("ac81", 13, "adcount: ", 13) ; Print the headings pause 10 hserout 0, ("ac95", 13, "adpulsin: ", 13) ; Print the headings pause 10 do count C.2, 1000, w0 ; Count the pulses (two per rev) w1 = 0 for b8 = 1 to 2 ; Measure pulse length twice pulsin C.2, 1, w2 ; per rev and... w1 = w1 + w2 next w1 = w1 / 2 ; ...calculate average hserout 0, ("ac89", 13, "ad ", #w0, " ", 13) ;Print the count value hserout 0, ("ac9d", 13, "ad ", #w1, " ", 13) ;Print the pulse-length value pause 100 loop

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

Если бы мы имели 100% КПД и лопасти вертелись-бы со скоростью ветра, то:
Радиус ротора = 3.75"
Диаметр ротора = 7.5" = 0.625 фута
Длина окружности ротора = 1.9642 фута

1 фут/мин = 0.0113636 м/ч,
1.9642 фут/мин = 1 об = 0.02232 м/ч
1 м/ч = 1 / 0.02232 об

1 м/ч = 44.8 об
? м/ч = об / 44.8
= (об/мин * 60) / 44.8

Поскольку за поворот выходит два импульса
? м/ч = (импульсов в секунду * 30) / 44.8
= (импульсов в секунду) / 448

Датчик направления ветра - механическая часть

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

На фото ниже показан 5мм магнит, установленный на торце центрального винта. Выравнивание магнита относительно микросхемы очень важно. Магнит должен быть точно по центру на высоте около 1мм над микросхемой. Как только все будет точно выровнено, датчик будет работать правильно.

Датчик направления ветра - электронная часть

Существуют различные схемы для измерения направления ветра. В основном они состоят либо из 8 герконов расположенных под углом 45 градусов с интервалом вращающегося магнита или потенциометра который может полностью проворачиваться.

Оба метода имеют свои преимущества и недостатки. Основным преимуществом является то, что они оба просты в реализации. Недостатком является то, что они подлежат износу - особенно потенциометры. Альтернативой использованию герконов будет использовать датчика Холла для решения механического износа, но они по-прежнему ограничиваются 8 различными позициями... В идеале, я хотел бы попробовать что-то другое и в конечном счете решил о - поворотном магнитном датчике IC. Хотя это устройство для поверхностного монтажа (которого я стараюсь избегать), оно имеет ряд преимуществ, которые делают ее использование привлекательным!

Он имеет несколько различных форматов вывода, два из которых наиболее подходит для нашей цели. Наилучшая точность достигается с помощью SSI интерфейса. AS5040 выдает импульсы длиной от 1 мкс при 0° и до 1024 мкс при 359,6°

Проверка калибровки датчика направления ветра:

Do readadc10 B.3, w0 ;Read from AS5040 magnetic bearing pause 100 w0 = w0 * 64 / 182 ; Convert to 0 - 360 (degrees) debug ; Display in Prog/Edit debug window loop

Измеритель уровня осадков

Насколько это возможно, я сделал дождемер из пластика и нержавеющей стали, основание сделано из алюминия толщиной 3 мм для жесткости.

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

На данный момент, я оставил его с прозрачными стенками (потому что интересно наблюдать это работает!). Но я подозреваю, что нужно покрасить его белой краской, чтобы отражать тепло летом, во избежание испарения. Я не мог найти маленькую воронку, поэтому пришлось сделать её самому. Обратите внимание на проволоку внутри воронки и по центру желоба. Это поможет остановить поверхностное натяжение воды в воронке и помогает капать воде. Без проволоки, дождь имел бы тенденцию к "водовороту", и его траектория была-бы непредсказуемой

Оптодатчики крупным планом:

Электронная часть дождемера

Из-за случайного характера работы датчика, программное прерывание в микроконтроллере наружного блока, казалось, логичный подход. К сожалению, некоторые команды программы, отключают механизм прерываний в то время, как они выполняются, т.о. есть вероятность, что сигнал придет в никуда. По этим причинам, дождемер имеет собственный микроконтроллер 08М Picaxe.

Использование отдельного чипа позволяет использовать его для создания достаточно точной 1-часовой задержки для того, чтобы считать ведра в час.

Калибровка

Picaxe 18м2 получает текущее количество ведерок в час и выводит его на дисплей и компьютер.

В качестве отправной точки, я использую следующие данные:
Воронка диаметров 120мм и емкость площадью 11,311мм2
1 мм дождя = 11,311мм3 или 11,3 мл.
Каждое ведро это 5,65 мл. Таким образом, 2 ведра 2 х 5,65 = 11,3 мл (или 1 мм) осадков. Одно ведро = 0,5 мм осадков.

Для сверки, я купил дешевый стакан для измерения осадков.

Для вышеприведенной схемы и схемы 08М Picaxe для датчика используется одна и та же топология печатной платы. Устройство питается от аккумулятора 12V 7Ah через стабилизатор 7805.
Я использовал набор RF Connect kit для беспроводной связи на 433 МГц. Комплект содержит пару специально запрограммированных PIC контроллеров. Комплект беспроводных модулей в ходе испытаний зарекомендовал себя как достаточно надежный.

На ПП установлен 08М Picaxe и 18м2. Каждый из них имеет свой собственный разъем программирования. Отдельные разъемы, каждый со своим +5 В, предназначены для каждого датчика - за исключением температуры и влажности.

Обратите внимание, что я нарисовал чертёж в Paintshop Pro поэтому я не могу гарантировать точность расстояния между выводами.

Внутренний блок

Во внутреннем блоке используетя 18м2 Picaxe, датчик давления и ЖК-дисплей. Также есть стабилизатор напряжения 5В.

Датчик давления

После нескольких неудачных попыток, я остановился на MPX4115A. Хотя другие датчики имеют диапазон измерения немного больше, они труднодоступны. Кроме того, другие датчики, как правило, работают от 3,3В и требуют дополнительный стабилизатор. MPX4115A выдает аналоговое напряжение от 3,79 и до 4,25В пропорционально давлению. Хотя это почти достаточное разрешение для обнаружения 1 мбар изменения давления, после некоторого обсуждения на форуме, я добавил АЦП MCP3422. Он может работать в 16-битном режиме (или выше) по сравнению с 10-битном режиме Picaxe. MCP3422 может быть связан (как в нашей схеме) в дифференциальный режим с аналоговым входом от датчика. Основным преимуществом является то, что это позволяет корректировать выход датчика, тем самым легко компенсировать ошибки MPX4115A и обеспечить простой способ калибровки датчика.

MPC3422 на самом деле имеет два дифференциальных входа, но так-как один не используется они замкнуты. Выход из MCP3422 имеет интерфейс I2C и соединяется с SDA и SCL контактам на 18м2 Picaxe – выводы B.1 и B.4 соответственно. С моей точки зрения, единственный недостаток в использовании MCP3422 том, что это небольшое устройство для поверхностного монтажа, но я его припаял к адаптеру. В дополнение к I2C интерфейсу MCP3422 18м2 просто обрабатывает поступающие данные из 433МГц беспроводной приемник, выводит данные на дисплей и передает данные на ПК. Для того чтобы избежать ошибок внутреннего блока когда компьютер не работает, нет никаких ответов от ПК. Внутренний блок передает данные и идет дальше. Он передает данные приблизительно в 2-секундным интервалом, чтобы потери данных быстро компенсировались следующий раз. Я использовал незадействованные порты на 18м2 для подключения кнопки на передней панели. Переключатель S1 (вход С.5) используется для включения подсветки ЖК-дисплея. Переключатель S2 (вход C.0) сбрасывает значение давления (мбар) на ЖК-дисплее. Переключатель S3 (вход C.1) переключает осадки отображаемые на ЖК-дисплее между общим в предыдущий час и текущими. Кнопки необходимо удерживать более 1 секунды для их реакции.

Сборка внутреннего блока

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

Плата немного больше, чем это необходимо, чтобы вписаться в пазы в алюминиевом корпусе.
Я сознательно сделал разъем для программирования немного "внутрь" от края платы, чтобы предотвратить его прикосновение к корпусу. Вырез для ЖК-дисплея производится высверливание и подгонкой до точных размеров.

На фото показано всё уже установленное в корпус.

Штырьки на плате делают сложным её установку в корпус, поэтому мне пришлось отпаять их и припаять дисплей к плате проводами.

Внешний блок - код Picaxe

; ================================================================== ; Main 18M2 code for the Picaxe Weather Station Outdoor (Transmitter) Unit ; Decimal precision Humidity & Temperature routines, ; copyright, Peter H Anderson, Baltimore, MD, Jan, "04 ; ; ================================================================== #Picaxe 18M2 Symbol HValue = w0 Symbol HighWord = w1 Symbol LowWord = w2 Symbol RH10 = w3 Symbol HQuotient = b0 Symbol HFract = b1 Symbol X = b0 Symbol aDig = b1 Symbol TFactor = b2 Symbol Tc = b3 Symbol SignBit = b4 Symbol TValue = w4 Symbol TQuotient = b10 Symbol TFract = b11 Symbol TempC_100 = w6 Symbol MagDir = w7 Symbol MagDirLo = b14 Symbol MagDirHi = b15 Symbol WindSpeed = w8 Symbol WindSpeedLo = b16 Symbol WindSpeedHi = b17 Symbol ThisHour = b18 Symbol LastHour = b19 Symbol RainRequest = b20 ; Hardware Symbol HumidRaw = B.7 Symbol TempRaw = B.6 Symbol DirRaw = B.3 Symbol Speed = B.0 do ; Read Humidity ReadADC10 HumidRaw, HValue ;Get Humidity (HValue) HighWord = 1613 ** HValue ; calculate RH LowWord = 1613 * HValue RH10 = LowWord / 1024 LowWord = Highword * 64 RH10 = RH10 + LowWord RH10 = RH10 - 258 pause 100 ; Read temperature Readtemp12 TempRaw, TValue ; Get temperature SignBit = TValue / 256 / 128 if SignBit = 0 then positive ; It"s negative so TValue = TValue ^ $ffff + 1 ; take twos comp positive: TempC_100 = TValue * 6 ; TC = value * 0.0625 TValue = TValue * 25 / 100 TempC_100 = TempC_100 + TValue TQuotient = TempC_100 / 100 TFract = TempC_100 % 100 / 10 X = TQuotient / 10 ; Calculate temperature correction factor for Humidity if SignBit = 0 then SignBit = " " else SignBit = "-" endif if SignBit = "-" then X = 4 - X else X = X + 4 endif GoSub TempCorrection ; compensate RH HQuotient = RH10 / 10 ; Calculate RH Quotient and... HFract = RH10 % 10 ; ...decimal place. if HQuotient > 99 then ; Over range HQuotient = 99 HFract = 9 endif if HQuotient > 127 then ; Under range HQuotient = 0 HFract = 0 endif ; Read AS540 magnetic encoder for wind direction readadc10 DirRaw, MagDir ; Read from AS5040 magnetic bearing pause 100 ; Read rpm from windspeed counter count Speed, 1000, WindSpeed ; Every 30th cycle (approx 1 minute), request rain gauge data from 08M inc RainRequest if RainRequest >= 30 then high C.1 serin , C.0, N2400, ("r"), LastHour, ThisHour ; Rain counters low C.1 RainRequest = 0 endif ; Send data to Indoor Unit in 8 byte blocks ; First group needs no calibration so calculations are done here first. ; Second group will need "tweaking" - more easily done at indoor end. serout C.2, N2400, ("t", SignBit, TQuotient, TFract, HQuotient, HFract, "A", "B") pause 100 serout C.2, N2400, ("m", MagDirHi, MagDirLo, WindSpeedHi, WindSpeedLo, LastHour, ThisHour, "C") loop TempCorrection: Lookup X, (87, 89, 91, 93, 95, 97, 99, 101, 103, 106, 108, 110, 113, 116, 119, 122, 126), TFactor " -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 110 120 if TFactor < 100 then aDig = TFactor / 10 RH10 = RH10 * aDig / 10 TFactor = TFactor % 10 aDig = TFactor RH10 = RH10 * aDig / 100 + RH10 else TFactor = TFactor % 100 aDig = TFactor / 10 RH10 = RH10 * aDig / 10 + RH10 TFactor = TFactor % 10 aDig = TFactor RH10 = RH10 * aDig / 100 + RH10 endif return

Использовано памяти = 295 байт из 2048

Счетчик количества осадков - 08M код

#picaxe 08M Symbol ThisHour = b2 ; Store the current sensor count in b2 Symbol LastHour = b3 ; Save the previous hour"s count in b3 ;Hardware definitions Symbol DataRequest = pin3 Symbol BucketSensor = pin4 setint %00010000, %00010000 ; pin4 is interrupt pin main: for w0 = 1 to 60000 ; Loop for 1 hour pause 60 next LastHour = ThisHour ; Update Last hour"s count with ThisHour = 0 ; current hour & reset current hour goto main ; Do the next hour interrupt: setint %00010000, %00010000 ; Re-instate interrupt if DataRequest = 1 then ; Was the interrupt from the 18M2 ? serout 2, N2400, ("r", LastHour, ThisHour) ; Yes, so send previous hour"s count & curent count. do: loop while DataRequest = 1 ; Wait until 18M2 stops requesting before continuing endif if BucketSensor = 1 then ; Was the interrupt from the rain sensor? inc ThisHour ; Yes, so increment bucket-tip count do: loop while BucketSensor = 1 ; Make sure flag has cleared sensor before continuing endif return

Внутренний блок - код Picaxe

;============================================================================ ; Main Indoor (Receiver) Program. ; ; Receives data from outdoor unit, displays on LCD and passes data on to PC ; Also measures the barometric pressure (thanks to "matherp") ;============================================================================ #PICAXE 18M2 ; Variable Definitions (b2 to b5 are re-used for mBar code when they become available) symbol Quotient = b2 symbol Fract = b3 symbol SignBit = b4 symbol Humidity = b5 symbol HFract = b14 symbol Dir = w5 symbol DirLo = b10 symbol DirHi = b11 symbol Speed = w3 symbol SpeedLo = b6 symbol SpeedHi = b7 symbol RainCountThisHour = b12 symbol RainCountLastHour = b13 symbol LCDRainWhole = b21 symbol LCDRainFract = b22 symbol LastOrThis = b23 ; MCP3422 ADC variables symbol mb900 = 17429 ; ADC reading for 900Mbar, then add 72.288 counts per mbar symbol adj0 = 72 symbol mBarADCValue = w0 symbol adj1 = b4 ; used to add 1 count every 4 mbar symbol adj2 = b5 ; used to add 1 count every 24 mbar symbol mBar = w4 ; Housekeeping variables symbol lastmbar = w8 ; Remember previous mBar reading symbol RiseFall = b18 ; Indicator for pressure rising or falling (up arrow or down arrow) symbol active = b19 ; Telltale shows activity on LCD screen symbol LCD_Status = b20 ; Is LCD Backlight on or off (0 or 1)? ; Hardware Definitions symbol Wireless = C.7 ; Incoming connection from Wireless receiver/decoder symbol Computer = C.2 ; Outgoing serial connection to computer symbol LCD = pinC.5 ; Front-panel button to blank / unblank LCD backlight symbol ClearRiseFall = pinC.0 ; Front-panel button to clear pressure "rising / falling" indicator symbol LastOrThisSwitch = pinC.1 ; Front-panel button to display current or previous hour"s rainfall Init: hsersetup B9600_4, %10000 ; Use LCD Pin 1, no hserin ; ByVac 20x4 IASI-2 Serial LCD hi2csetup i2cmaster, %11010000, i2cfast, i2cbyte ; Initialize I2C for MCP3422 ADC chip. hi2cout (%00011000) ; set MCP3422 for 16 bit continuous conversion pause 500 hserout 0, (13) : pause 100 ; Initialize LCD hserout 0, (13) : pause 100 hserout 0, (13) : pause 100 pause 500 hserout 0, ("ac50", 13) hserout 0, ("ad", 32, 32, 32, 32, 49, 42, 36, 32, 13) ; Define down arrow character (char 10) hserout 0, ("ac1", 13) ; Clear display pause 50 hserout 0, ("acc", 13) ; Hide cursor hserout 0, ("ac81", 13, "ad ", $df, "C", 13) ; Print the headings hserout 0, ("ac88", 13, "admBar", 13) hserout 0, ("ac8e", 13, "adRH %", 13) hserout 0, ("acd5", 13, "ad", "dir", 13) ; Print footings hserout 0, ("acdc", 13, "ad", "mph", 13) ; hserout 0, ("ace3", 13, "ad", "mm", 13) lastmbar = 0 ; Initialize variables LastOrThis = "c" ;========================================================================== ; Main Loop ;========================================================================== main: ; Check if a front-panel switch is pressed. The Picaxe interrupt mechanism is ; almost permanently disabled due to the large number of serin and serout commands ; so sprinkling the program with "gosub switches" to check the switch status is more ; effective that interrupts. gosub switches ; Get first group of values from outdoor unit via 433MHz radio link. serin Wireless, N2400, ("t"), SignBit, Quotient, Fract, Humidity, HFract, b15, b15 ; Flash "telltale" on LCD to indicate activity and successful "serin" from wireless. gosub telltale ; Display first group on LCD hserout 0, ("acc0", 13) hserout 0, ("ad", SignBit, #Quotient, ".", #Fract, " ", 13) hserout 0, ("acce", 13) hserout 0, ("ad", #Humidity,".", #HFract, " ", 13) gosub switches ; Send first group to computer COM port ; Each group has a start identifier, data and an end identifier: ; Start = "xS", End is "xE" eg Wind Start is WS, Wind End is WE ; Multiple data are separated by a single space character. serout Computer, N2400, ("TS", SignBit, #Quotient," ", #Fract, "TE") ; Temperature serout Computer, N2400, ("HS", #Humidity, " ", #HFract, "HE") ; Humidity ; Check switches again and at regular intervals throughout program. gosub switches ; Get second group of values from outdoor unit radio link. serin Wireless, N2400, ("m"), DirHi, DirLo, SpeedHi, SpeedLo, RainCountLastHour, RainCountThisHour, b15 gosub telltale Speed = Speed * 300 / 448 ; Estimated conversion from pulses/sec to mph Dir = Dir * 64 / 182 ; Convert 0 - 1023 to 0 - 359 degrees ; To preserve precision, rain gauge has to be calibrated by adjusting the ; mechanical stops on the tipping bucket so that 1 tip is 0.5 mm of rain. if LastOrThis = "c" then ; Decide whether to display previous hour"s LCDRainWhole = RainCountThisHour / 2 ; rainfall or the current hour"s. LCDRainFract = RainCountThisHour * 5 // 10 else LCDRainWhole = RainCountLastHour / 2 ; LCDRainFract = RainCountLastHour * 5 // 10 endif ; Send second group to LCD hserout 0, ("ac95", 13) hserout 0, ("ad", #Dir, " ", 13) hserout 0, ("ac9c", 13) hserout 0, ("ad", #Speed, " ", 13) hserout 0, ("aca1", 13) hserout 0, ("ad", LastOrThis, " ", #LCDRainWhole, ".", #LCDRainFract, " ", 13) ; Send second group to computer COM port serout Computer, N2400, ("WS", #Dir," ", #Speed, "WE") ; Wind serout Computer, N2400, ("RS", #RainCountLastHour," ", #RainCountThisHour, "RE") ; Rain gosub switches ; Thanks to "matherp" on the Picaxe forum for the mbar code loop: ; Measuring atmosperic pressure with a MPX4115A ; Analogue to digital conversion using a MCP3422 ; MPX output to V+, 2.5V to V- ; ADC in 16 bit mode hi2cin (b1,b0,b2) ; Read in the ADC reading and the status byte from MCP3422 adj1 = 0 adj2 = 0 w1 = mb900 mbar = 900 do while mBarADCValue > w1 ; mBarADCValue = w0 = b1:b0 inc mbar w1 = w1 + adj0 inc adj1 if adj1 = 4 then inc adj2 w1 = w1 + 1 adj1 = 0 endif if adj2 = 6 then w1 = w1 + 1 adj2 = 0 endif loop gosub switches gosub telltale ; Send pressure to computer COM port serout Computer, N2400, ("PS:", #mbar, "PE") ; Initialize previous pressure reading (lastmbar) if not already set if lastmbar = 0 then lastmbar = mbar RiseFall = " " endif ; Display up arrow or down arrow if pressure has changed if mbar > lastmbar then RiseFall = "^" ; ^ lastmbar = mbar endif if mbar < lastmbar then RiseFall = 10 ; Custom LCD character. Down arrow lastmbar = mbar endif hserout 0, ("acc7", 13) hserout 0, ("ad", RiseFall, #mbar, " ",13) gosub telltale goto main ; Check if one of the front panel buttons is pressed. switches: if LCD = 1 then ; LCD Backlight on/off Button is pressed if LCD_Status = 0 then ; Backlight is on so... hserout 0, ("ab0", 13) ; Turn it off LCD_Status = 1 else hserout 0, ("ab1", 13) ; Else turn it on. LCD_Status = 0 endif do: loop while LCD = 1 ; Don"t return while button is pressed endif if ClearRiseFall = 1 then ; Pressure rise/fall button is pressed RiseFall = " " ; Clear indicator and... hserout 0, ("acc7", 13) ; ... update display. hserout 0, ("ad", RiseFall, #mbar, " ",13) do: loop while ClearRiseFall = 1 endif if LastOrThisSwitch = 1 then ; Rain Previous Hour / Last Hour button. if LastOrThis = "c" then LastOrThis = "p" LCDRainWhole = RainCountLastHour / 2 ; Recalculate values and re-display to LCDRainFract = RainCountLastHour * 5 // 10 ; give visual confirmation of button-press else LastorThis = "c" LCDRainWhole = RainCountThisHour / 2 ; LCDRainFract = RainCountThisHour * 5 // 10 endif hserout 0, ("aca1", 13) hserout 0, ("ad", LastOrThis, " ", #LCDRainWhole, ".", #LCDRainFract, " ", 13) do: loop while LastOrThisSwitch = 1 endif return ; Flash "tell-tale" on LCD display to show activity telltale: if active = "*" then active = " " else active = "*" endif hserout 0, ("ac80", 13, "ad", active, 13) return

Использовано памяти = 764 байт из 2048

Программное обеспечение для ПК

Программное обеспечение, работающее на ПК было написано с использованием Borland Delphi 7. Оно довольно примитивно в его нынешнем виде, но это, по крайней мере, показывает связь Picaxe с компьютером.

Графики могут быть выбраны для показа в период 1 час или 12 часов. Графики можно прокручивать вперёд-назад с помощью мышки. Они могут быть сохранены. Для этого необходимо кликнуть по ним правой кнопкой мыши и указать имя и файл значения. Можно настроить ограниченный набор APRS данных, записываемых раз в минуту на одну строку файла APRS.TXT и которые сохраняются в той же папке, где находится Weather.exe. Отмечу, что температура в градусах по Фаренгейту и осадки в 1/100ths на дюйм.

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
Датчик температуры и относительной влажности воздуха
Датчик температуры

DS18B20

1 В блокнот
Датчик влажности HIH-3610 1 В блокнот
Резистор

4.7 кОм

1 В блокнот
Измеритель скорости и направления ветра
Фототранзистор ИК 1 В блокнот
Светодиод ИК 1 В блокнот
Резистор

220 Ом

1 В блокнот
Резистор

4.7 кОм

1 В блокнот
Магнитный энкодер 1 В блокнот
Электролитический конденсатор 10 мкФ 4 В блокнот
Конденсатор 100 нФ 1 В блокнот
Резистор

4.7 кОм

1 В блокнот
Резистор

10 кОм

1 В блокнот
Измеритель уровня осадков
МК PICAXE

PICAXE-08M

1 В блокнот
Выпрямительный диод

1N4148

2 В блокнот
Конденсатор 100 нФ 1 В блокнот
Резистор

4.7 кОм

1 В блокнот
Резистор

10 кОм

4 В блокнот
Резистор

22 кОм

1 В блокнот
Резистор

220 Ом

2 В блокнот
Светодиод ИК 1

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

1. Компоненты

Итак, для изготовления изделия понадобились следующие компоненты:
  • Шариковая мышь Mitsumi - 1 шт.
  • Мячик для пинг-понга - 2 шт.
  • Кусок оргстекла подходящего размера
  • Медная проволока сечением 2,5 мм2 - 3 см
  • Стержень от шариковой ручки - 1 шт.
  • Палочка от конфеты чупа-чупс - 1 шт.
  • Клипса для кабеля - 1 шт.
  • Полый латунный бочонок 1 шт.

2. Изготовление крыльчатки


К латунному бочонку были припаяны 3 куска медной проволоки длиной 1 см каждый под углом 120 градусов. В отверстие бочонка я припаял стойку из китайского плеера с резьбой на конце.

Трубочку от конфеты разрезал на 3 части длиной около 2 см.

Разрезал пополам 2 шарика и с помощью мелких шурупов из того же плеера и полистирольного клея (клеевым пистолетом) прикрепил половинки шарика к трубочкам от чупа-чупса.

Трубочки с половинками шарика надел на припаянные куски проволоки, сверху все закрепил клеем.

3. Изготовление основной части




Несущим элементом анемометра является металлический стержень от шариковой ручки. В нижнюю часть стержня (куда вставлялась пробка) я вставил диск от мышки (энкодер). В конструкции самой мышки нижняя часть энкодера упиралась в корпус мышки образуя точечный подшипник, там была смазка, поэтому энкодер легко крутился. Но нужно было зафиксировать верхнюю часть стержня, для этого я подобрал подходящий кусок пластика с отверстием точно по диаметру стержня (такой кусок был вырезан из системы выдвигания каретки CD-ROMa). Оставалось решить проблему с тем, чтобы стержень с энкодером не выпадал из точечного подшипника, поэтому на стержне непосредственно перед удерживающим элементом я напаял несколько капель припоя. Таким образом, стержень свободно крутился в удерживающей конструкции, но не выпадал из подшипника.

Причина, по которой была выбрана схема с энкодером, следующая: все статьи о самодельных анемометрах в Интернете описывали их изготовление на базе двигателя постоянного тока от плеера, CD-ROMa или еще какого изделия. Проблема с такими устройствами во первых в их калибровке и малой точности при малой скорости ветра, а во вторых - в нелинейной характеристике скорости ветра по отношению к выходному напряжению, т.е. для передачи информации на компьютер есть определенные проблемы, нужно просчитывать закон изменения напряжения или тока от скорости ветра. При использовании энкодера такой проблемы нет, так как зависимость получается линейной. Точность высочайшая, так как энкодер дает около 50 импульсов на один оборот оси анемометра, но несколько усложняется схема преобразователя, в котором стоит микроконтроллер, считающий количество импульсов в секунду на одном из портов и выдающий это значение в порт USB.

4. Испытания и калибровка

Для калибровки был использован лабораторный анемометр

Весь процесс наглядно виден на роликах:

Спасибо за внимание