====== Беспроводная метеостанция ======
{{ :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 минут, а в остальное — каждые полчаса.