Введение

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

Программа рассчитана на работу с аналоговыми датчиками:

  • Температурный датчик, подключённый к аналоговому входу A1, используется для получения текущего значения температуры воздуха.
  • Фоторезистор (датчик освещенности), подключённый к A0, позволяет оценить освещённость в окружающей среде — от солнечного света до пасмурной или даже дождливой погоды.

Одной из важных особенностей реализации является использование жидкокристаллического экрана не только для цифрового вывода информации, но и для визуализации погодных условий с помощью символов, созданных вручную в виде пиктограмм. Это делает систему более дружелюбной для пользователя и позволяет быстро оценить обстановку даже без внимательного чтения цифр. Дополнительным удобством является вывод информации в Serial Monitor, что может использоваться для отладки, логирования или последующего анализа.

Подобная погодная станция может применяться:

  • В домашних умных системах (умный дом)
  • В учебных проектах и лабораториях
  • Для наблюдения за условиями хранения в помещении
  • В качестве учебного пособия по работе с сенсорами и дисплеями в Arduino

Программа написана на языке C++ с использованием стандартной библиотеки LiquidCrystal, поставляемой с Arduino IDE. Основное внимание уделено структуре кода, читаемости, логике обработки данных и визуализации информации. Сама реализация демонстрирует навыки работы с аналоговыми сигналами, интерпретацией данных, отображением информации и созданием кастомных символов.

Основные блоки программы:

1. Подключение и инициализация компонентов:

  • Объявление пинов для дисплея и датчиков.
  • Создание объекта LCD с указанием пинов управления.
  • Инициализация дисплея и задание пользовательских символов (градус, солнце, дождь и пр.).

2. Вывод приветственного сообщения:

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

3. Основной цикл работы (loop):

  • Считывание температуры: аналоговое значение преобразуется в напряжение, затем в градусы Цельсия.
  • Считывание освещённости: с аналогового входа считывается значение, которое масштабируется и ограничивается.
  • Интерпретация данных: на основе температуры и уровня света выбираются соответствующие текстовые описания и графические символы.
  • Отображение информации: данные последовательно выводятся на экран LCD в двух разных представлениях:
    • Сначала — текст о погоде и температура.
    • Затем — описание освещенности и повтор температуры.
  • Обновление экрана происходит с интервалом в 2 секунды.
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int temperaturePin = A1;
const int lightPin = A0;

float voltage, degreesC;

char* tempText[] = {
  "Cold weather!",   // < 15
  "Nice weather!",   // 15–25
  "Heat rising!",    // 25–30
  "Hot! Drink water!"// >30
};

char* lightText[] = {
  "Sunny",     // < 85
  "Cloudy",    // 85–170
  "Rainy"      // >170
};

byte smile[8] = {
    0b00000,
    0b01010,
    0b01010,
    0b00000,
    0b10001,
    0b01110,
    0b00000,
    0b00000
};

byte rain[8] = {
    0b00100,
    0b00100,
    0b01010,
    0b01010,
    0b10001,
    0b10001,
    0b10001,
    0b01110
};

byte degrees[8] = {
    0b01110,
    0b01010,
    0b01110,
    0b00000,
    0b00000,
    0b00000,
    0b00000,
    0b00000
};

// Солнце вместо сердечка
byte sun[8] = {
    0b00100,
    0b01010,
    0b11111,
    0b11111,
    0b00100,
    0b00100,
    0b00000,
    0b00000
};

byte sad[8] = {
    0b00000,
    0b01010,
    0b01010,
    0b00000,
    0b01110,
    0b10001,
    0b00000,
    0b00000
};

void setup() {
  Serial.begin(9600);

  lcd.begin(16, 2); // Инициализация LCD
  lcd.createChar(1, degrees);
  lcd.createChar(2, smile);
  lcd.createChar(3, rain);
  lcd.createChar(4, sun);  // Используем солнце вместо сердечка
  lcd.createChar(5, sad);

  lcd.setCursor(0, 0);
  lcd.print("Weather Station:");
  lcd.setCursor(0, 1);
  lcd.print("Weather Monitor");

  delay(1000);  // Задержка перед началом работы
}

void loop() {
  // --- Temperature ---
  voltage = analogRead(temperaturePin) * 0.004882814;
  degreesC = (voltage - 0.5) * 100.0;

  // --- Light ---
  int lightLevel = analogRead(lightPin);
  lightLevel = map(lightLevel, 300, 800, 0, 255);
  lightLevel = constrain(lightLevel, 0, 255);

  // Print data to Serial Monitor
  Serial.print("Temp: ");
  Serial.print(degreesC);
  Serial.print(" °C | Light level: ");
  Serial.println(lightLevel);

  // Text based on temperature
  char* tempTextToDisplay;

  if (degreesC < 15) {
    tempTextToDisplay = tempText[0];
  } else if (degreesC < 25) {
    tempTextToDisplay = tempText[1];
  } else if (degreesC < 30) {
    tempTextToDisplay = tempText[2];
  } else {
    tempTextToDisplay = tempText[3];
  }

  // Text based on light level
  char* lightTextToDisplay;
  byte lightIcon;

  if (lightLevel > 170) {
    lightTextToDisplay = lightText[2];
    lightIcon = 3;
  } else if (lightLevel > 85) {
    lightTextToDisplay = lightText[1];
    lightIcon = 5;
  } else {
    lightTextToDisplay = lightText[0];
    lightIcon = 2;
  }

  // Display temperature and text
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(tempTextToDisplay);
  lcd.setCursor(0, 1);
  lcd.print("Temp: ");
  lcd.print(degreesC, 1);
  lcd.write(byte(1));  // Custom degree symbol
  lcd.print("C");
  delay(2000);

  // Display light information
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(lightTextToDisplay);
  lcd.setCursor(strlen(lightTextToDisplay) + 1, 0);
  lcd.write(lightIcon);
  lcd.setCursor(0, 1);
  lcd.print("Temp: ");
  lcd.print(degreesC, 1);
  lcd.write(byte(1));
  lcd.print("C");
  delay(2000);
}

1. Структура проекта

Цель:
Создать устройство для мониторинга температуры и освещенности с выводом данных на LCD-дисплей и в Serial Monitor.
Основные компоненты:

  • Датчик температуры (аналоговый, подключен к A1).
  • Датчик освещенности (аналоговый, подключен к A0).
  • LCD-дисплей (16×2 символов, управляется через библиотеку LiquidCrystal).

2. Библиотеки и настройка пинов

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
  • Библиотека LiquidCrystal упрощает работу с дисплеем.
  • Пины подключения:
    RS=12EN=11D4=5D5=4D6=3D7=2 (стандартная 4-битная шина данных).

3. Переменные и константы

Аналоговые входы:

const int temperaturePin = A1;  // Датчик температуры
const int lightPin = A0;        // Датчик освещенности

Переменные для данных:

float voltage, degreesC;  // Для температуры
int lightLevel;           // Для освещенности

Текстовые сообщения:

char* tempText[] = {
  "Cold weather!",    // < 15°C
  "Nice weather!",    // 15–25°C
  "Heat rising!",     // 25–30°C
  "Hot! Drink water!" // > 30°C
};

char* lightText[] = {
  "Sunny",   // < 85
  "Cloudy",  // 85–170
  "Rainy"    // > 170
};

Пользовательские символы (8×5 пикселей):

byte smile[8] = { ... };  // Улыбка
byte rain[8] = { ... };   // Дождь
byte degrees[8] = { ... };// Символ °C
byte sun[8] = { ... };    // Солнце
byte sad[8] = { ... };    // Грустный смайл

4. Функция setup()

Инициализация:

void setup() {
  Serial.begin(9600);  // Скорость передачи данных
  lcd.begin(16, 2);    // Инициализация дисплея (16 столбцов, 2 строки)
  
  // Создание пользовательских символов
  lcd.createChar(1, degrees);
  lcd.createChar(2, smile);
  lcd.createChar(3, rain);
  lcd.createChar(4, sun);
  lcd.createChar(5, sad);

  // Приветственное сообщение
  lcd.setCursor(0, 0);
  lcd.print("Weather Station:");
  lcd.setCursor(0, 1);
  lcd.print("Weather Monitor");
  delay(1000);  // Пауза 1 секунда
}

5. Функция loop()

1. Чтение температуры:

voltage = analogRead(temperaturePin) * 0.004882814;  // Преобразование в вольты (5V / 1024)
degreesC = (voltage - 0.5) * 100.0;  // Формула для LM35/TMP36

2. Чтение освещенности:

lightLevel = analogRead(lightPin);
lightLevel = map(lightLevel, 300, 800, 0, 255);  // Нормализация
lightLevel = constrain(lightLevel, 0, 255);      // Ограничение диапазона

3. Определение текста и иконок:

// Для температуры
if (degreesC < 15) tempTextToDisplay = tempText[0];
else if (degreesC < 25) tempTextToDisplay = tempText[1];
else if (degreesC < 30) tempTextToDisplay = tempText[2];
else tempTextToDisplay = tempText[3];

// Для освещенности
if (lightLevel > 170) { lightTextToDisplay = lightText[2]; lightIcon = 3; }
else if (lightLevel > 85) { lightTextToDisplay = lightText[1]; lightIcon = 5; }
else { lightTextToDisplay = lightText[0]; lightIcon = 2; }

4. Вывод на LCD и Serial Monitor:


6. Логика работы

  • Температура:
    • Датчик возвращает напряжение, которое конвертируется в °C.
    • В зависимости от диапазона выбирается текстовое описание.
  • Освещенность:
    • Значение датчика нормализуется до диапазона 0–255.
    • Определяется погодное состояние (солнечно, облачно, дождь).

Заключение

Этот код демонстрирует:

  • Работу с аналоговыми датчиками.
  • Динамическое управление LCD-дисплеем.
  • Использование пользовательских символов.
  • Простую логику классификации данных.
    Идеально подходит для учебных проектов или базовых метеостанций!