Сборка компактной метеостанции на Arduino Nano — простое DIY-руководство
Компоненты и материалы
| Arduino Nano R3 | × | 1 |
| Модуль DHT 11 | × | 1 |
| Датчик давления BMP-280 | × | 1 |
| LCD-дисплей 1.44 дюйма ST7735 | × | 1 |
| 3D-печатный корпус | × | 1 |
| Кабель USB A — mini USB B | × | 1 |
Необходимые инструменты и станки
| Паяльник (универсальный) |
| 3D-принтер (универсальный) |
| Пятина для пайки |
| Двусторонний скотч |
Приложения и онлайн-сервисы
| Arduino IDE |
| Autodesk Fusion 360 |
О проекте
Введение
Захват физических данных в реальном времени всегда увлекателен. В этом проекте вы не только сможете зафиксировать три фундаментальных физических параметра для прогноза погоды — температуру, влажность и атмосферное давление, но и отобразить данные в реальном времени на LCD-экране.
Описание и принцип работы
В этом проекте используются два датчика: BMP-280 и DHT-11. Первый измеряет температуру и атмосферное давление, второй — относительную влажность. DHT-11 можно было бы заменить, используя BME-280 (он также измеряет влажность) вместо BMP-280, но если учитывать стоимость, то используемая здесь комбинация датчиков намного экономичнее для DIY-проектов. Также следует отметить, что хотя DHT-11 способен измерять и температуру, и влажность, он используется только для влажности, потому что его разрешение по температуре составляет ±2° по сравнению с ±0,5° у BMP-280. Сердцем этого проекта является плата разработки Arduino NANO. Здесь также NANO была выбрана вместо более популярного UNO из-за ее доступной цены. В качестве дисплея используется 1,44" TFT LCD-экран серии ST7735. Больший экран был отвергнут, чтобы не перегружать Arduino NANO.
Схема и программирование
Предоставлено сочетание принципиальной схемы и блок-схемы, максимально удобное для понимания физической конфигурации и подключения компонентов. Таблицы распиновки компонентов также приведены для упрощения. Изучая схему и таблицы, вы заметите, что пины 5V и GND разъема ICSP на Arduino NANO использованы для питания компонентов вместе с набордовыми питанием и землей. Это сделано для отказа от дополнительного источника питания, который сделал бы систему громоздкой.
Что касается программирования, в первой части подключается ряд библиотек для краткости и простоты кода. Помимо очевидных, стоит отметить библиотеки Wire.h и SPI.h: Wire.h позволяет Arduino общаться с I2C/TWI-устройствами, такими как BMP-280 и ST7735 LCD, а SPI.h обеспечивает последовательный периферийный интерфейс с ST7735 LCD. Во второй части датчики инициализируются, а макет, цвет шрифта и т.д. LCD настраиваются для отображения данных по нашему усмотрению. В финальной части программы показания датчиков считываются и отображаются с удобной задержкой между измерениями для стабильности.
Сборка и тестирование
В прототипе компоненты сохранены модульными и соединены перемычками вместо пайки. Это не только позволяет легко находить неисправности и ремонтировать, но и делает процесс сборки безболезненным. Корпус устройства был 3D-печатан на заказ для идеальной посадки компонентов. Корпус обеспечивает надлежащую вентиляцию, чтобы датчики были подвержены измеряемым величинам и рассеивалось тепло, генерируемое системой, которое иначе бы мешало чувствительным элементам. Устройство питается через тот же кабель USB Type A — Type B mini, который используется для программирования Arduino. Прототип тестировался в помещении в течение нескольких часов как от USB-порта ПК, так и от зарядного устройства смартфона 5В. Результаты довольно точны по сравнению с онлайн-метеорологическими данными, учитывая стоимость производства и время разработки.
Заключение
Подводя итог, можно сказать, что этот проект довольно экономичен, полезен, и, что самое главное, весело иметь небольшую и удобную метеостанцию, которая прямо помещается в карман.
Для заказа электронных компонентов обращайтесь к UTSOURCE
Библиография
- Google.com
- Arduino.cc
- Mytectutor.com




Код
THE CODE (C/C++)
ЭТО АКТУАЛЬНЫЙ СКЕТЧ ДЛЯ ПРОЕКТА, КОММЕНТАРИИ ОБЪЯСНЯЮТ РАБОТУ
#include <SPI.h> // библиотека последовательного периферийного интерфейса
#include <Wire.h> // библиотека двухпроводного интерфейса (I2C)
#include <Adafruit_GFX.h> // библиотека графики Adafruit
#include <Adafruit_ST7735.h> // библиотека Adafruit ST7735 TFT
#include <Adafruit_BMP280.h> // библиотека датчика Adafruit BMP280
#include "DHT.h" // библиотека датчика DHTXX
#define DHTPIN 2 // пин данных DHT11 подключен к пину D2 Arduino
#define DHTTYPE DHT11 // указание типа используемого датчика DHT
#define TFT_RST 8 // пин RST TFT подключен к пину D8 Arduino
#define TFT_CS 10 // пин CS TFT подключен к пину D9 Arduino
#define TFT_DC 9 // пин DC TFT подключен к пину D10 Arduino
// инициализация библиотеки ST7735 SERIES TFT
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// определение I2C-адреса устройства: 0x76 или 0x77 (0x77 — адрес по умолчанию в библиотеке)
#define BMP280_I2C_ADDRESS 0x76
Adafruit_BMP280 bmp280; // инициализация библиотеки Adafruit BMP280
DHT dht(DHTPIN, DHTTYPE); // инициализация датчика DHT
void setup(void) {
dht.begin(); // синхронизация датчика DHT
tft.initR(INITR_144GREENTAB); // инициализация чипа ST7735S, зеленая вкладка
tft.fillScreen(ST77XX_BLACK); // черный фон
tft.drawFastHLine(0, 15 , tft.width(), ST77XX_CYAN); // горизонтальная разделительная линия в позиции (0, 15)
tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK); // цвет текста циан, фон черный
tft.setTextSize(1); // размер текста 1
//tft.setCursor(4, 0); // курсор в позицию (4, 0)
//tft.print("ARDUINO + ST7735 TFT");
tft.setCursor(25, 5); // курсор в позицию (25, 5)
tft.print("WEATHER BUDDY"); // заголовок
// инициализация датчика BMP280
if( bmp280.begin(BMP280_I2C_ADDRESS) == 0 ) {
// ошибка подключения или неверный адрес устройства!
tft.setTextColor(ST77XX_RED, ST77XX_CYAN); // красный текст на циановом фоне
tft.setTextSize(2); // размер текста 2
tft.setCursor(5, 76); // курсор в позицию (5, 76)
tft.print("Connection");
tft.setCursor(35, 100); // курсор в позицию (35, 100)
tft.print("Error");
while(1); // останова здесь
}
tft.drawFastHLine(0, 55, tft.width(), ST77XX_CYAN); // разделительная линия в позиции (0, 55)
tft.drawFastHLine(0, 95, tft.width(), ST77XX_CYAN); // разделительная линия в позиции (0, 95)
tft.setTextColor(ST77XX_RED, ST77XX_BLACK); // красный текст на черном фоне
tft.setCursor(30, 20); // курсор в позицию (30, 20)
tft.print("TEMPERATURE "); // заголовок первой секции
tft.setTextColor(ST77XX_CYAN, ST77XX_BLACK); // циан на черном
tft.setCursor(40, 60); // курсор в позицию (40, 60)
tft.print("HUMIDITY "); // заголовок второй секции
tft.setTextColor(ST77XX_GREEN, ST7735_BLACK); // зеленый на черном
tft.setCursor(40, 100); // курсор в позицию (40, 100)
tft.print("PRESSURE "); // заголовок третьей секции
tft.setTextSize(2); // размер текста 2
}
// основной цикл
void loop() {
char _buffer[8];
// чтение температуры, влажности и давления с датчика BMP280
float temp = bmp280.readTemperature(); // температура в °C
float hum = dht.readHumidity(); // влажность в % rH
float pres = bmp280.readPressure(); // давление в Па (переведем в гПа)
// 1: вывод температуры (в °C)
if(temp < 0) // если температура < 0
sprintf( _buffer, "-%02u.%02u", (int)abs(temp), (int)(abs(temp) * 100) % 100 );
else // если температура >= 0
sprintf( _buffer, " %02u.%02u", (int)temp, (int)(temp * 100) % 100 ); // форматирование значения
tft.setTextColor(ST77XX_YELLOW, ST77XX_BLACK); // желтый текст на черном фоне
tft.setCursor(11, 34); // курсор в позицию (11,34)
tft.print(_buffer); // вывод температуры с BMP-280
tft.drawCircle(89, 34, 2, ST77XX_YELLOW); // символ градуса (°) (можно опустить, если используется *)
tft.setCursor(95, 34); // курсор в позицию (95,34)
tft.print("C"); // символ Цельсия
// 2: вывод влажности (в %)
sprintf( _buffer, "%02u ", (int)(hum)); // форматирование значения
tft.setTextColor(ST77XX_MAGENTA, ST77XX_BLACK); // пурпурный на черном
tft.setCursor(45, 74); // курсор в позицию (45,74)
tft.print(_buffer); // вывод влажности с DHT-11
tft.setCursor(75, 74); // курсор в позицию (75,74)
tft.print("%"); // символ процента
// 3: вывод давления (в гПа)
sprintf( _buffer, "%04u.%02u", (int)(pres/100), (int)((uint32_t)pres % 100) ); // форматирование значения
tft.setTextColor(ST77XX_ORANGE, ST77XX_BLACK); // оранжевый на черном
tft.setCursor(3, 112); // курсор в позицию (3,112)
tft.print(_buffer); // вывод атмосферного давления с BMP-280
tft.setCursor(91, 112); // курсор в позицию (91,112)
tft.print("hPa"); // единица измерения — гектопаскаль
delay(1000); // пауза 1 секунда перед следующим измерением
}
Печатные детали и корпуса
STL-файл для 3D-печати деталей, которые я использовал
Схемы
ВАМ НУЖНО ТОЛЬКО СЛЕДОВАТЬ ПРОВОДКЕ, ПОКАЗАННОЙ НА СХЕМЕ.

Производственный процесс
- Сборка уличной метеостанции на Raspberry Pi 2 и ADS‑WS1
- Создание метеостанции на Raspberry Pi с ежедневными email-отчётами о погоде
- Удалённый мониторинг погоды на Raspberry Pi 3 с PubNub
- Продвинутая метеостанция v2.0: мониторинг температуры, давления, влажности и высоты в реальном времени
- DIY-консоль управления Photoshop на Arduino Nano RP2040 Connect
- Точные 7-сегментные часы на Arduino Pro Mini и DS1302 RTC
- Портативная метеостанция на Arduino Nano за $10: DHT22, BMP180 и LCD
- eDOT: точные Arduino-часы и метеостанция с встроенным ИК-пультом
- Сборка компактного FM-радио на Arduino Nano и RDA5807M
- Метеостанция на Arduino и ThingSpeak: температура и влажность в облаке