🔬 Разработка мобильной станции экологического мониторинга

Практическая работа | Урок 24 | Прикладная робототехника

🎯 Миссия: Создать цифрового эко-детектива

🤖 Что мы строим сегодня:

Мобильная станция экологического мониторинга — автономный робот, который:

  • 📊 Собирает данные о параметрах окружающей среды
  • 📱 Отображает информацию в реальном времени
  • 📡 Передает данные на компьютер для анализа
  • 🗺️ Может работать в различных точках местности

🔧 Технический стек:

  • Сенсоры: Температура, влажность, освещенность, качество воздуха
  • Обработка: Arduino/ESP32 микроконтроллер
  • Отображение: LCD дисплей с данными
  • Связь: Bluetooth/Wi-Fi передача данных
  • Питание: Автономная работа от аккумулятора

📊 Вспоминаем: Арсенал эко-сенсоров

🌡️ Температура 💧 Влажность ☀️ Освещенность 🌬️ Качество воздуха
DHT22 DHT22 BH1750 MQ-135
-40…+80°C 0-100% RH 0-65535 lx 10-10000 ppm
±0.5°C ±2-5% ±20% CO₂, NH₃, NOₓ
Digital Digital I²C Analog

🎯 Почему именно эти датчики?

  • Точность — подходящая для экомониторинга
  • Надежность — проверенные временем решения
  • Доступность — легко найти и подключить
  • Энергоэффективность — долгая автономная работа

⚙️ Архитектура системы: От сенсора до данных

🔄 Поток данных в системе:

1🔬 Сенсоры → 🧠 Микроконтроллер → 📱 Дисплей
23📡 Беспроводная связь → 💻 Компьютер → 📊 Анализ → 🗂️ База данных

📋 Компоненты системы:

Блок Функция Технология Параметры
Сенсорный Измерение параметров Аналоговые/цифровые датчики 1-4 датчика
Обработки Сбор и обработка данных Arduino Uno/Mega/ESP32 16 МГц, 32 КБ
Отображения Локальная визуализация LCD I2C 16×2/20×4 Подсветка, контраст
Связи Передача данных Bluetooth HC-05/ESP32 WiFi 9600-115200 bps
Питания Автономность Li-ion/Li-Po батарея 7.4-12V, 2000+ мАч

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

Arduino Uno → Датчики:

 1DHT22 (Температура/Влажность):
 2├─ VCC → 5V
 3├─ GND → GND
 4└─ DATA → Pin 2
 5
 6BH1750 (Освещенность):
 7├─ VCC → 3.3V
 8├─ GND → GND
 9├─ SCL → A5
10└─ SDA → A4
11
12MQ-135 (Качество воздуха):
13├─ VCC → 5V
14├─ GND → GND
15└─ AOUT → A0
16
17LCD I2C (Дисплей):
18├─ VCC → 5V
19├─ GND → GND
20├─ SCL → A5
21└─ SDA → A4
22
23HC-05 (Bluetooth):
24├─ VCC → 5V
25├─ GND → GND
26├─ TX → Pin 8
27└─ RX → Pin 9

🔬 Калибровка датчиков: Точность — наше всё

🎯 Зачем нужна калибровка?

Без калибровки:

  • Погрешность до ±10-20%
  • Дрейф показаний со временем
  • Влияние температуры и влажности
  • Различия между экземплярами датчиков

После калибровки:

  • Погрешность ±1-3%
  • Стабильные показания
  • Компенсация внешних факторов
  • Единый стандарт измерений

🧮 Математика калибровки:

Линейная калибровка:

$$V_{calibrated} = V_{measured} \times K + B$$

где:

  • $V_{calibrated}$ — откалиброванное значение
  • $V_{measured}$ — измеренное значение
  • $K$ — коэффициент наклона
  • $B$ — смещение (offset)

Расчет коэффициентов:

$$K = \frac{V_{reference2} - V_{reference1}}{V_{sensor2} - V_{sensor1}}$$

$$B = V_{reference1} - K \times V_{sensor1}$$

🌡️ Практическая калибровка температуры:

Методика:

  1. Точка 1: Комнатная температура (~22°C)
  2. Точка 2: Холодная вода (~5°C)
  3. Точка 3: Теплая вода (~40°C)

Пример расчета:

1Эталон: 22.0°C → Датчик: 21.5°C
2Эталон: 5.0°C → Датчик: 4.8°C
3Эталон: 40.0°C → Датчик: 39.2°C
4
5K = (40.0 - 5.0) / (39.2 - 4.8) = 35.0 / 34.4 = 1.017
6B = 5.0 - 1.017 × 4.8 = 0.118
7
8Формула: T_cal = T_sensor × 1.017 + 0.118

💧 Калибровка влажности:

Калибровочные точки:

  • 0% RH: Сухой силикагель в герметичном контейнере
  • 75% RH: Насыщенный раствор NaCl
  • 97% RH: Дистиллированная вода

Время стабилизации:

  • Минимум 2 часа для каждой точки
  • Температура должна быть стабильной
  • Герметичный контейнер обязателен

💻 Программирование: Код мобильной станции

🔧 Структура программы:

 1// Основные блоки программы
 2void setup() {
 3    // Инициализация датчиков и модулей
 4}
 5
 6void loop() {
 7    // Основной цикл работы
 8    readSensors();      // Чтение датчиков
 9    processData();      // Обработка данных
10    displayData();      // Отображение на LCD
11    sendData();         // Передача по Bluetooth
12    delay(interval);    // Пауза между измерениями
13}

📊 Алгоритм сбора данных:

Фильтрация показаний:

 1// Скользящее среднее для сглаживания
 2float movingAverage(float newValue, float oldAverage, int n) {
 3    return (oldAverage * (n-1) + newValue) / n;
 4}
 5
 6// Медианный фильтр для удаления выбросов
 7float medianFilter(float values[], int size) {
 8    // Сортировка массива
 9    for (int i = 0; i < size-1; i++) {
10        for (int j = i+1; j < size; j++) {
11            if (values[i] > values[j]) {
12                float temp = values[i];
13                values[i] = values[j];
14                values[j] = temp;
15            }
16        }
17    }
18    return values[size/2];  // Возврат медианы
19}

📱 Форматирование данных для дисплея:

 1void displayData() {
 2    lcd.clear();
 3    
 4    // Первая строка: Температура и влажность
 5    lcd.setCursor(0, 0);
 6    lcd.print("T:");
 7    lcd.print(temperature, 1);  // 1 знак после запятой
 8    lcd.print("C H:");
 9    lcd.print(humidity, 0);     // Без дробной части
10    lcd.print("%");
11    
12    // Вторая строка: Освещенность и качество воздуха
13    lcd.setCursor(0, 1);
14    lcd.print("L:");
15    if (lightLevel < 1000) {
16        lcd.print((int)lightLevel);
17    } else {
18        lcd.print(lightLevel/1000.0, 1);
19        lcd.print("k");
20    }
21    lcd.print(" A:");
22    lcd.print(airQuality);
23}

📡 Протокол передачи данных:

JSON-формат для структурированных данных:

 1void sendData() {
 2    String jsonData = "{";
 3    jsonData += "\"timestamp\":" + String(millis()) + ",";
 4    jsonData += "\"temperature\":" + String(temperature, 2) + ",";
 5    jsonData += "\"humidity\":" + String(humidity, 1) + ",";
 6    jsonData += "\"light\":" + String(lightLevel, 0) + ",";
 7    jsonData += "\"airQuality\":" + String(airQuality);
 8    jsonData += "}";
 9    
10    bluetooth.println(jsonData);
11    Serial.println(jsonData);  // Дублирование в консоль для отладки
12}

CSV-формат для простоты обработки:

1void sendDataCSV() {
2    String csvData = String(millis()) + "," +
3                     String(temperature, 2) + "," +
4                     String(humidity, 1) + "," +
5                     String(lightLevel, 0) + "," +
6                     String(airQuality);
7    
8    bluetooth.println(csvData);
9}

📈 Визуализация данных: Компьютерная часть

🐍 Python-скрипт для приема данных:

Структура программы:

 1import serial
 2import matplotlib.pyplot as plt
 3import json
 4from collections import deque
 5import time
 6
 7class EcoMonitor:
 8    def __init__(self, port='COM5', baudrate=9600):
 9        self.serial_connection = serial.Serial(port, baudrate)
10        self.data_buffer = {
11            'time': deque(maxlen=100),
12            'temperature': deque(maxlen=100),
13            'humidity': deque(maxlen=100),
14            'light': deque(maxlen=100),
15            'air_quality': deque(maxlen=100)
16        }
17        
18    def read_data(self):
19        """Чтение данных с Arduino"""
20        if self.serial_connection.in_waiting:
21            raw_data = self.serial_connection.readline().decode().strip()
22            try:
23                # Парсинг JSON или CSV данных
24                data = json.loads(raw_data)
25                return data
26            except:
27                # Fallback для CSV формата
28                values = raw_data.split(',')
29                if len(values) == 5:
30                    return {
31                        'timestamp': int(values[0]),
32                        'temperature': float(values[1]),
33                        'humidity': float(values[2]),
34                        'light': float(values[3]),
35                        'airQuality': int(values[4])
36                    }
37        return None

📊 Real-time графики:

Настройка мультиграфика:

 1def setup_plots(self):
 2    """Настройка графических окон"""
 3    self.fig, self.axes = plt.subplots(2, 2, figsize=(12, 8))
 4    self.fig.suptitle('Мониторинг окружающей среды')
 5    
 6    # Настройка каждого графика
 7    self.axes[0,0].set_title('Температура (°C)')
 8    self.axes[0,0].set_ylim(0, 50)
 9    self.axes[0,0].grid(True)
10    
11    self.axes[0,1].set_title('Влажность (%)')
12    self.axes[0,1].set_ylim(0, 100)
13    self.axes[0,1].grid(True)
14    
15    self.axes[1,0].set_title('Освещенность (lx)')
16    self.axes[1,0].set_yscale('log')  # Логарифмический масштаб
17    self.axes[1,0].grid(True)
18    
19    self.axes[1,1].set_title('Качество воздуха')
20    self.axes[1,1].set_ylim(0, 1023)
21    self.axes[1,1].grid(True)
22    
23    plt.tight_layout()
24    plt.ion()  # Интерактивный режим

🚨 Система предупреждений:

Пороговые значения:

 1THRESHOLDS = {
 2    'temperature': {'min': 18, 'max': 26},      # Комфортная температура
 3    'humidity': {'min': 40, 'max': 60},         # Оптимальная влажность
 4    'light': {'min': 200, 'max': 1000},         # Достаточное освещение
 5    'air_quality': {'min': 0, 'max': 300}       # Приемлемое качество воздуха
 6}
 7
 8def check_alerts(self, data):
 9    """Проверка превышения пороговых значений"""
10    alerts = []
11    
12    for param, value in data.items():
13        if param in THRESHOLDS:
14            threshold = THRESHOLDS[param]
15            if value < threshold['min']:
16                alerts.append(f"⚠️ {param}: {value} ниже нормы ({threshold['min']})")
17            elif value > threshold['max']:
18                alerts.append(f"🚨 {param}: {value} выше нормы ({threshold['max']})")
19    
20    return alerts

🎯 Этапы практической работы

📋 Этап 1: Планирование и роли (5 мин)

👥 Распределение ролей в команде:

Роль Ответственность Основные задачи
🔧 Конструктор Механическая часть Сборка платформы, крепление компонентов
⚡ Электронщик Электроника Подключение датчиков, проводка
💻 Программист Код и алгоритмы Программирование Arduino, отладка
🧪 Тестировщик Качество Калибровка, тестирование, валидация

🎯 Выбор параметров мониторинга:

  • Температура воздуха
  • Влажность воздуха
  • Освещенность
  • Качество воздуха (CO₂, летучие органические соединения)
  • Дополнительно: GPS-координаты, атмосферное давление

📋 Этап 2: Конструирование платформы (10 мин)

🚗 Требования к мобильной платформе:

Механика:

  • Устойчивое шасси для движения по ровной поверхности
  • Защита электроники от механических воздействий
  • Доступ к портам для программирования и зарядки
  • Правильное размещение датчиков для корректных измерений

Размещение компонентов:

  • Датчики: На открытых местах, не загороженные корпусом
  • Контроллер: Защищен, но доступен для подключения
  • Дисплей: Хорошо видимый, защищен от ударов
  • Батарея: Надежно закреплена, легко заменяется

📋 Этап 3: Подключение электроники (15 мин)

⚡ Чек-лист подключений:

1□ DHT22 подключен к Pin 2 (проверить питание 5V)
2□ BH1750 подключен к I2C (SDA/SCL, питание 3.3V)
3□ MQ-135 подключен к A0 (питание 5V, прогрев 24ч)
4□ LCD I2C подключен к I2C (адрес 0x27, питание 5V)
5□ HC-05 подключен к Pin 8/9 (питание 5V)
6□ Все GND соединены с общей землей
7□ Питание подается от стабилизированного источника
8□ Проводка аккуратная, соединения надежные

🔍 Проверка подключений мультиметром:

  • Напряжение питания: 5V ± 0.1V
  • Целостность проводников: сопротивление < 1 Ом
  • Отсутствие коротких замыканий между соседними пинами

📋 Этап 4: Калибровка датчиков (8 мин)

🌡️ Экспресс-калибровка:

Температура:

  • Сравнить с эталонным термометром
  • $K_{temp} = \frac{T_{эталон}}{T_{датчик}}$

Влажность:

  • Использовать гигрометр или справочные значения
  • $K_{hum} = \frac{RH_{эталон}}{RH_{датчик}}$

Освещенность:

  • Сравнить с люксметром или известными источниками
  • $K_{light} = \frac{Lux_{эталон}}{Lux_{датчик}}$

📝 Таблица калибровки:

Датчик Показание Эталон Коэффициент
DHT22 (T) ___ °C ___ °C K = ___
DHT22 (H) ___ % ___ % K = ___
BH1750 ___ lx ___ lx K = ___

💻 Программирование: Пошаговый код

📋 Этап 5: Базовая программа (15 мин)

🚀 Стартовый код (скелет):

 1#include <DHT.h>
 2#include <Wire.h>
 3#include <BH1750.h>
 4#include <LiquidCrystal_I2C.h>
 5#include <SoftwareSerial.h>
 6
 7// Конфигурация пинов
 8#define DHT_PIN 2
 9#define DHT_TYPE DHT22
10#define MQ135_PIN A0
11#define BT_RX 8
12#define BT_TX 9
13
14// Инициализация объектов
15DHT dht(DHT_PIN, DHT_TYPE);
16BH1750 lightMeter;
17LiquidCrystal_I2C lcd(0x27, 16, 2);
18SoftwareSerial bluetooth(BT_RX, BT_TX);
19
20// Переменные данных
21struct SensorData {
22    float temperature;
23    float humidity;
24    float light;
25    int airQuality;
26    unsigned long timestamp;
27};
28
29SensorData currentData;
30
31void setup() {
32    // TODO: Инициализация всех компонентов
33}
34
35void loop() {
36    // TODO: Основной цикл работы
37}

🔧 Функция чтения датчиков:

 1void readSensors() {
 2    // Чтение температуры и влажности
 3    currentData.temperature = dht.readTemperature();
 4    currentData.humidity = dht.readHumidity();
 5    
 6    // Проверка на ошибки DHT22
 7    if (isnan(currentData.temperature) || isnan(currentData.humidity)) {
 8        Serial.println("Ошибка чтения DHT22!");
 9        return;
10    }
11    
12    // Чтение освещенности
13    currentData.light = lightMeter.readLightLevel();
14    
15    // Чтение качества воздуха
16    currentData.airQuality = analogRead(MQ135_PIN);
17    
18    // Временная метка
19    currentData.timestamp = millis();
20    
21    // Применение калибровочных коэффициентов
22    applyCalibration();
23}
24
25void applyCalibration() {
26    // TODO: Применить коэффициенты калибровки
27    currentData.temperature *= TEMP_CALIBRATION;
28    currentData.humidity *= HUMIDITY_CALIBRATION;
29    currentData.light *= LIGHT_CALIBRATION;
30}

📱 Функция отображения:

 1void displayData() {
 2    lcd.clear();
 3    
 4    // Строка 1: T:25.3C H:45%
 5    lcd.setCursor(0, 0);
 6    lcd.print("T:");
 7    lcd.print(currentData.temperature, 1);
 8    lcd.print("C H:");
 9    lcd.print((int)currentData.humidity);
10    lcd.print("%");
11    
12    // Строка 2: L:1250 A:245
13    lcd.setCursor(0, 1);
14    lcd.print("L:");
15    if (currentData.light < 1000) {
16        lcd.print((int)currentData.light);
17    } else {
18        lcd.print(currentData.light/1000, 1);
19        lcd.print("k");
20    }
21    
22    lcd.print(" A:");
23    lcd.print(currentData.airQuality);
24}

📡 Функция передачи данных:

 1void sendData() {
 2    // JSON формат для структурированной передачи
 3    String jsonString = "{";
 4    jsonString += "\"time\":" + String(currentData.timestamp) + ",";
 5    jsonString += "\"temp\":" + String(currentData.temperature, 2) + ",";
 6    jsonString += "\"hum\":" + String(currentData.humidity, 1) + ",";
 7    jsonString += "\"light\":" + String(currentData.light, 0) + ",";
 8    jsonString += "\"air\":" + String(currentData.airQuality);
 9    jsonString += "}";
10    
11    // Отправка через Bluetooth
12    bluetooth.println(jsonString);
13    
14    // Дублирование в Serial для отладки
15    Serial.println(jsonString);
16}

🧪 Тестирование и валидация

📋 Этап 6: Комплексное тестирование (10 мин)

✅ Чек-лист функциональности:

Базовая функциональность:

  • Все датчики дают разумные показания
  • Дисплей отображает актуальные данные
  • Bluetooth соединение устанавливается
  • Данные корректно передаются на компьютер
  • Система работает от батареи > 30 минут

Точность измерений:

  • Температура: отклонение < ±2°C от эталона
  • Влажность: отклонение < ±5% от эталона
  • Освещенность: соответствует визуальной оценке
  • Качество воздуха: реагирует на изменения

🎯 Сценарии тестирования:

Тест 1: Температурный отклик

  • Приблизить датчик к теплому объекту
  • Ожидаемый результат: Рост температуры в течение 10-30 сек

Тест 2: Влажностный отклик

  • Подышать на датчик влажности
  • Ожидаемый результат: Кратковременный скачок влажности

Тест 3: Световой отклик

  • Изменить освещение (включить/выключить лампу)
  • Ожидаемый результат: Соответствующее изменение показаний

Тест 4: Качество воздуха

  • Поднести спиртовой антисептик к датчику
  • Ожидаемый результат: Увеличение показаний MQ-135

📊 Анализ данных в реальном времени:

Проверка на компьютере:

 1# Быстрый тест приема данных
 2import serial
 3import json
 4
 5ser = serial.Serial('COM5', 9600)  # Замените на ваш порт
 6
 7for i in range(10):  # Прочитать 10 измерений
 8    if ser.in_waiting:
 9        data = ser.readline().decode().strip()
10        try:
11            parsed = json.loads(data)
12            print(f"T: {parsed['temp']}°C, "
13                  f"H: {parsed['hum']}%, "
14                  f"L: {parsed['light']}lx, "
15                  f"A: {parsed['air']}")
16        except:
17            print(f"Raw data: {data}")

🎭 Демонстрация проектов: Эко-детективы в действии

📋 Этап 7: Презентация результатов (10 мин)

🎪 Формат демонстрации (2-3 мин на команду):

🔬 “Наша станция умеет…” (60 сек)

  • Покажите работающую станцию
  • Объясните, какие параметры измеряете
  • Продемонстрируйте отклик датчиков на изменения
  • Покажите передачу данных на компьютер

📊 “Точность наших измерений…” (45 сек)

  • Результаты калибровки датчиков
  • Сравнение с эталонными значениями
  • Стабильность показаний во времени
  • Время автономной работы

🚀 “Уникальные особенности…” (30 сек)

  • Что делает вашу станцию особенной?
  • Какие проблемы решили в процессе разработки?
  • Идеи для дальнейшего развития

🏆 Критерии оценки демонстрации:

Критерий Оценка Описание
Функциональность 0-5 Все ли работает как задумано?
Точность измерений 0-5 Насколько данные соответствуют реальности?
Стабильность 0-3 Есть ли сбои, ошибки, зависания?
Автономность 0-3 Время работы от батареи
Презентация 0-4 Качество объяснения и демонстрации

Максимум: 20 баллов

🎯 Интерактивное тестирование:

Общие измерения по классу:

  • Каждая команда измеряет параметры в своей точке класса
  • Строим карту микроклимата помещения
  • Сравниваем показания разных станций
  • Обсуждаем причины различий

Синхронный эксперимент:

  • Все станции одновременно начинают измерения
  • Включаем/выключаем освещение
  • Открываем/закрываем окна
  • Анализируем скорость отклика разных систем

🧠 Рефлексия: От датчиков к пониманию

🔍 Технические открытия:

💡 О сенсорных технологиях:

  • Какой датчик оказался самым точным/чувствительным?
  • Что удивило в процессе калибровки?
  • Какие факторы больше всего влияют на точность измерений?
  • С какими техническими проблемами столкнулись?

📊 О данных и их интерпретации:

  • Как изменялись показания в разных точках класса?
  • Какие закономерности заметили в данных?
  • Насколько быстро датчики реагируют на изменения?
  • Как влияет расположение датчика на результаты?

🌱 Экологические инсайты:

🌍 О микроклимате:

  • Что узнали о климате вашего класса/школы?
  • Какие параметры оказались не в норме?
  • Как можно улучшить экологические условия?
  • Какую роль играет вентиляция и освещение?

🔬 О мониторинге в целом:

  • Зачем нужен постоянный мониторинг окружающей среды?
  • Какие проблемы можно выявить с помощью таких станций?
  • Где еще можно применить подобные системы?
  • Как технологии помогают защищать природу?

🚀 Планы развития:

Ближайшие улучшения:

  • Какие датчики добавили бы в систему?
  • Как повысить точность измерений?
  • Как улучшить автономность работы?
  • Как сделать систему более удобной?

Долгосрочные цели:

  • Создание сети мониторинга в школе
  • Исследовательские проекты с данными
  • Участие в экологических конкурсах
  • Профессиональное развитие в эко-технологиях

🎯 Домашнее задание: Эко-станция 2.0

📋 Обязательная часть:

Технический отчет о мобильной станции

📖 Структура отчета:

  1. Описание системы (1 страница)

    • Назначение и функции станции
    • Перечень используемых датчиков
    • Схема подключения компонентов
  2. Калибровка и тестирование (1 страница)

    • Таблица калибровочных коэффициентов
    • Результаты тестирования точности
    • Время автономной работы
  3. Программная реализация (0.5 страницы)

    • Основные алгоритмы программы
    • Формат передачи данных
    • Особенности программирования
  4. Результаты измерений (0.5 страницы)

    • Примеры собранных данных
    • Анализ изменений параметров
    • Выводы о микроклимате

🌟 Творческая часть:

“Эко-станция будущего”

🚀 Концепция развития:

  • Новые датчики: Какие параметры добавить? (CO₂, PM2.5, УФ-излучение, шум)
  • Улучшенная автономность: Солнечные панели, энергосберегающие режимы
  • Искусственный интеллект: Предсказание изменений, автоматические рекомендации
  • Интернет вещей: Подключение к глобальной сети мониторинга

🌍 План исследования:

  • Выберите экологическую проблему для изучения
  • Определите необходимые датчики и их расположение
  • Составьте план сбора данных на неделю/месяц
  • Предложите гипотезы для проверки

🌟 Заключение: Маленькие роботы — большие изменения

💭 Главное достижение урока:

“Сегодня вы создали не просто робота — вы создали цифрового помощника в защите окружающей среды. Каждый ваш датчик — это окно в мир природы, каждое измерение — шаг к пониманию планеты”

🎯 Что мы освоили:

  • Системное мышление — от датчика до принятия решений
  • Инженерные навыки — проектирование, сборка, программирование
  • Научный подход — калибровка, тестирование, анализ данных
  • Экологическое сознание — понимание важности мониторинга среды

🚀 Куда движемся дальше:

  • Smart cities с повсеместным экомониторингом
  • Персональные эко-помощники для каждого дома
  • Глобальные сети экологических данных
  • AI-предсказания экологических изменений

🌍 Ваши станции — это начало большого пути к технологической экологии!