====== Беспроводная метеостанция ====== {{ :projects:meteo_overview.jpg?direct&700 }} * Платформы: Teensy, Arduino Uno * Языки программирования: [[wp>Wiring_(development_platform) | Wiring (C++)]] * Проект на [[wpru>GitHub]]: http://github.com/amperka-projects/wirelessmeteo * Тэги: метеостанция, погода, температура, влажность, прогноз ===== Что это такое? ===== В этой статье мы расскажем о том, как собрать полноценную метеостанцию, передающую данные о погоде на широко известный сервис «[[http://narodmon.ru/|народный мониторинг]]». Наша метеостанция будет состоять из двух устройств: компактного автономного устройства, измеряющего погодные показатели, и устройства-ретранслятора, получающего эти показатели и отправляющего их на «народный мониторинг». Устройства будут связываться по беспроводному каналу связи на частоте 433 МГц. Автономная часть будет питаться от трёх пальчиковых батареек и сможет просуществовать на одном комплекте батарей до года при периоде опроса датчиков в 20 мин. Такая конструкция позволяет не сверлить стены для прокладки проводов с улицы, где необходимо производить измерения, в помещение, где результатами этих измерений надо пользоваться. ===== Что для этого необходимо? ===== {{ :projects:meteo_collage.jpg?direct&700 }} Для изготовления автономного передатчика нам понадобятся: -[[amp>product/teensy-40?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Teensy 4.0]] -[[amp>product/rf-433-transmitter?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Передатчик на 433 МГц]] -[[amp>product/temperature-humidity-sensor-sht1x?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Датчик температуры и влажности]] -[[amp>product/breadboard-mini?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Макетная плата Mini]] -Держатель пальчиковых батареек на x3 AA -[[amp>product/wire-mm?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Провода папа-папа ×3 шт]] -[[amp>product/resistor?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Резистор на 100 кΩ]] -[[amp>product/resistor?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Резистор на 10 кΩ]] -[[amp>product/pin-headers?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Штырьковые соединители x36 контактов]] Для изготовления ретранслятора нам понадобятся: -[[amp>product/arduino-uno?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Arduino Uno]] -[[amp>product/arduino-ethernet?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Arduino Ethernet]] -[[amp>product/rf-433-receiver?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Приёмник на 433 МГц]] -[[amp>product/breadboard-mini?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Макетная плата Mini]] -[[amp>product/wire-mm?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Провода папа-папа ×4 шт]] Так же удобно установить два светодиода для индикации процессов: -[[amp>product/wire-mm?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Провода папа-папа ×2 шт]] -[[amp>product/led-5mm?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Светодиод красный ×1 шт]] -[[amp>product/led-5mm?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Светодиод зелёный ×1 шт]] -[[amp>product/resistor?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Резисторы на 220 Ω x2 шт]] Для звуковой индикации разряда батареи автономной части удобно использовать пьезо-пищалку: -[[amp>product/wire-mm?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Провод папа-папа ×1 шт]] -[[amp>product/piezo-buzzer?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|Пьезо-пищалка]] ===== Как это собрать? ===== ==== Сборка автономной части ==== - Припаяйте штыри к проводам батарейного отсека и воткните их в макетную плату. На этапе разработки очень удобно закрепить все элементы на какой-нибудь основе (мы использовали обычный картон). {{ :projects:meteo_build_sender_0.jpg?direct&700 }} - Припаяйте штыри к отверстиям на длинных сторонах Teensy и вставьте плату в макетку. Подсоедините питание. {{ :projects:meteo_build_sender_1.jpg?direct&700 }} - Вставьте беспроводной передатчик так, чтобы его контакт ''0'' оказался соединённым с контактом ''GND'' Teensy. Контакт ''2'' передатчика проводом соедините с контактом ''5'' Teensy. {{ :projects:meteo_build_sender_2.jpg?direct&700 }} - Подсоедините резисторы так, как показано на рисунке. Это наш делитель напряжения для функции измерения напряжения питания. {{ :projects:meteo_build_sender_3.jpg?direct&700 }} - Подключите через трёхпроводные шлейфы со штырьковыми контактами датчик температуры и влажности. {{ :projects:meteo_build_sender_4.jpg?direct&700 }} ==== Сборка ретранслятора ==== - Вставьте Ethernet шилд в Arduino Uno, установите сверху макетку и вставьте в неё беспроводной приёмник. Подключите вывод ''7'' Arduino к выводу ''2'' приёмника. {{ :projects:meteo_build_receiver_0.jpg?direct&700 }} - Подключите питание и землю приёмника к выводам ''GND'' и ''5V'' Arduino. {{ :projects:meteo_build_receiver_1.jpg?direct&700 }} На этом сборка минимально функционального ретранслятора закончена. Если вы хотите установить светодиодную индикацию и звуковую сигнализацию, то выполните пункты ниже. - Установите светодиоды и резисторы, подключите красный светодиод к контакту ''6'', зелёный — к контакту ''5''. {{ :projects:meteo_build_receiver_2.jpg?direct&700 }} - Установите пьезопищалку, подключите её к контакту ''4''. {{ :projects:meteo_build_receiver_3.jpg?direct&700 }} ===== Исходный код ===== ==== Код автономной части ==== #include #include #include #include // Таймаут между посылками (не более 65535) #define TIMEOUT 60000 // Количество попыток отправки посылки #define ATTEMPTS 3 // Информационный пин передатчика #define RF_PIN 5 // Пины датчика температуры и влажности #define GND1_PIN 10 #define VCC1_PIN 11 #define GND2_PIN 7 #define VCC2_PIN 8 #define DATA_PIN 12 #define CLK_PIN 9 AmperkaLine rf(RF_PIN); SHT1x sht1x(CLK_PIN, DATA_PIN); void loop(void); // Функция усыпления платы. Каждые TIMEOUT секунд // будет вызываться функция loop_func. TEENSY3_LP LP = TEENSY3_LP(); sleep_block_t* LP_config; void sleep_mode(void) { LP_config = (sleep_block_t*)calloc(1,sizeof(sleep_block_t)); // Просыпаться будем по таймеру LP_config->modules = (LPTMR_WAKE); // Задаём таймаут для таймера LP_config->lptmr_timeout = TIMEOUT; // По истечении таймаута будет вызываться функция loop LP_config->callback = loop; LP.Hibernate(LP_config); } // Функция включения периферии void periferial_start(void) { // Включаем линию передачи данных pinMode(RF_PIN, OUTPUT); // Включаем питания и земли датчиков температуры и влажности pinMode(GND1_PIN, OUTPUT); pinMode(GND2_PIN, OUTPUT); pinMode(VCC1_PIN, OUTPUT); pinMode(VCC2_PIN, OUTPUT); digitalWrite(GND1_PIN, LOW); digitalWrite(GND2_PIN, LOW); digitalWrite(VCC1_PIN, HIGH); digitalWrite(VCC2_PIN, HIGH); // Включаем светодиод для индикации передачи pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); // Выбираем в качестве опорного напряжения внутренний // источник (=1.2 В) analogReference(INTERNAL); } // Функция выключения периферии void periferial_stop(void) { // Выключаем линию передачи данных pinMode(RF_PIN, INPUT); // Выключаем датчик температуры и влажности pinMode(GND1_PIN, INPUT); pinMode(GND2_PIN, INPUT); pinMode(VCC1_PIN, INPUT); pinMode(VCC2_PIN, INPUT); pinMode(18, INPUT_PULLUP); pinMode(19, INPUT_PULLUP); // Выключаем светодиод digitalWrite(LED_BUILTIN, LOW); } void setup(void) { // Ничего не инициализируем, сразу засыпаем sleep_mode(); } // Эта функция выполняется раз в TIMEOUT секунд void loop(void) { unsigned long msg; byte temp, humidity, voltage; // Включаем периферию periferial_start(); // Подождём, пока включится датчик температуры и влажности delay(30); // Получаем входные данные с сенсоров temp = (byte)(sht1x.readTemperatureC() + 40.)*2; humidity = (byte)sht1x.readHumidity(); voltage = analogRead(A0)/4; // Составляем из данных посылку msg = 0; msg |= voltage; msg <<= 8; msg |= humidity; msg <<= 8; msg |= temp; // Отправляем несколько раз посылку for(int i = 0; i < ATTEMPTS; i++) rf.send(msg); // Выключаем периферию periferial_stop(); // После выхода из функции плата снова уснёт } ==== Код платы, работающей в помещении ==== #include #include #include #include byte mac[] = { 0x90, 0xA7, 0xDA, 0x0F, 0xBC, 0x75 }; char server[] = "narodmon.ru"; EthernetClient client; const int rfpin = 7; AmperkaLine rf(rfpin); void setup(void) { pinMode(rfpin, INPUT); pinMode(6, OUTPUT); Serial.begin(9600); Serial.println("Started."); } void loop(void) { static unsigned long pushtimeout = 0; static float temp, humidity, voltage; unsigned long msg; int res; if((res = rf.receive(&msg)) == 0) { temp = ((float)(msg&0xFF))/2. - 40.; msg >>= 8; humidity = (float)(msg&0xFF); msg >>= 8; voltage = (float)(msg&0xFF) / 256. * 1.2 * 10 * 1.1; digitalWrite(6, HIGH); Serial.print("Temp: "); Serial.print(temp); Serial.print(", humidity: "); Serial.print(humidity); Serial.print(", voltage: "); Serial.println(voltage); digitalWrite(6, LOW); } else Serial.println('E'); if(millis() - pushtimeout > 60000*5) { pushtimeout = millis(); Serial.println("Starting Ethernet..."); if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); while(1) { } } delay(1000); Serial.println("connecting..."); if (client.connect(server, 8283)) { Serial.println("connected"); client.println("#90-A7-DA-0F-BC-75#Sensor#55.751775#37.616856#0.0"); client.print("#90A7DA0FBC7501#"); client.print(temp, DEC); client.println("#In"); client.print("#90A7DA0FBC7502#"); client.print(humidity, DEC); client.println("#Humidity"); client.print("#90A7DA0FBC7503#"); client.print(voltage, DEC); client.println("#Voltage"); client.println("##"); } else Serial.println("connection failed"); { unsigned long tm = millis(); while(millis() - tm < 5000) { if (client.available()) { char c = client.read(); Serial.print(c); } } } client.stop(); } } ===== Регистрация метеостанции в «Народном мониторинге» ===== Чтобы данные, передаваемые нашим устройством, корректно отображались на народном мониторинге, необходимо выполнить следующее: - Установить уникальный MAC-адрес устройства. - Зарегистрироваться на сайте «Народного мониторинга».{{ :projects:meteo_register.png?direct&700 }} - Авторизоваться. - Открыть список датчиков и установить номиналы передаваемых данных.{{ :projects:meteo_sensorsfix.png?direct&700 }} ===== Демонстрация работы устройства ===== {{youtube>1Iv1meDU588?large}} ===== Что ещё можно сделать? ===== - Мы установили только сенсор температуры и влажности. Но у Teensy остаётся ещё много свободных ножек, т.ч. можно добавить разных датчиков: [[amp>product/ldr?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|освещённости]], [[amp>product/barometer?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|атмосферного давления]], [[amp>product/anemometer-kit?utm_source=proj&utm_campaign=wirelessmeteo&utm_medium=wiki|скорости ветра]] и т.д. - Teensy прямо на борту имеет часы реального времени (RTC). Для их работоспособности не хватает только кварца. Можно купить кварц на 32,768 КГц в любом магазине радиоэлементов и припаять его. Тогда можно пробуждать Teensy по будильнику RTC. Достоинство в том, что можно будить устройство чаще в те часы, когда нужны более точные показания. Например, в рабочее время будить устройство каждые 5 минут, а в остальное — каждые полчаса.