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

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

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

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

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

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

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

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

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

🌡️ Температура💧 Влажность☀️ Освещенность🌬️ Качество воздуха
DHT22DHT22BH1750MQ-135
-40…+80°C0-100% RH0-65535 lx10-10000 ppm
±0.5°C±2-5%±20%CO₂, NH₃, NOₓ
DigitalDigitalI²CAnalog

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

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

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

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

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

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

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

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

Arduino Uno → Датчики:

DHT22 (Температура/Влажность):
├─ VCC → 5V
├─ GND → GND
└─ DATA → Pin 2

BH1750 (Освещенность):
├─ VCC → 3.3V
├─ GND → GND
├─ SCL → A5
└─ SDA → A4

MQ-135 (Качество воздуха):
├─ VCC → 5V
├─ GND → GND
└─ AOUT → A0

LCD I2C (Дисплей):
├─ VCC → 5V
├─ GND → GND
├─ SCL → A5
└─ SDA → A4

HC-05 (Bluetooth):
├─ VCC → 5V
├─ GND → GND
├─ TX → Pin 8
└─ 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)

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

Эталон: 22.0°C → Датчик: 21.5°C
Эталон: 5.0°C → Датчик: 4.8°C
Эталон: 40.0°C → Датчик: 39.2°C

K = (40.0 - 5.0) / (39.2 - 4.8) = 35.0 / 34.4 = 1.017
B = 5.0 - 1.017 × 4.8 = 0.118

Формула: T_cal = T_sensor × 1.017 + 0.118

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

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

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

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

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

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

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

// Основные блоки программы
void setup() {
    // Инициализация датчиков и модулей
}

void loop() {
    // Основной цикл работы
    readSensors();      // Чтение датчиков
    processData();      // Обработка данных
    displayData();      // Отображение на LCD
    sendData();         // Передача по Bluetooth
    delay(interval);    // Пауза между измерениями
}

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

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

// Скользящее среднее для сглаживания
float movingAverage(float newValue, float oldAverage, int n) {
    return (oldAverage * (n-1) + newValue) / n;
}

// Медианный фильтр для удаления выбросов
float medianFilter(float values[], int size) {
    // Сортировка массива
    for (int i = 0; i < size-1; i++) {
        for (int j = i+1; j < size; j++) {
            if (values[i] > values[j]) {
                float temp = values[i];
                values[i] = values[j];
                values[j] = temp;
            }
        }
    }
    return values[size/2];  // Возврат медианы
}

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

void displayData() {
    lcd.clear();
    
    // Первая строка: Температура и влажность
    lcd.setCursor(0, 0);
    lcd.print("T:");
    lcd.print(temperature, 1);  // 1 знак после запятой
    lcd.print("C H:");
    lcd.print(humidity, 0);     // Без дробной части
    lcd.print("%");
    
    // Вторая строка: Освещенность и качество воздуха
    lcd.setCursor(0, 1);
    lcd.print("L:");
    if (lightLevel < 1000) {
        lcd.print((int)lightLevel);
    } else {
        lcd.print(lightLevel/1000.0, 1);
        lcd.print("k");
    }
    lcd.print(" A:");
    lcd.print(airQuality);
}

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

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

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

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

void sendDataCSV() {
    String csvData = String(millis()) + "," +
                     String(temperature, 2) + "," +
                     String(humidity, 1) + "," +
                     String(lightLevel, 0) + "," +
                     String(airQuality);
    
    bluetooth.println(csvData);
}

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

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

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

import serial
import matplotlib.pyplot as plt
import json
from collections import deque
import time

class EcoMonitor:
    def __init__(self, port='COM5', baudrate=9600):
        self.serial_connection = serial.Serial(port, baudrate)
        self.data_buffer = {
            'time': deque(maxlen=100),
            'temperature': deque(maxlen=100),
            'humidity': deque(maxlen=100),
            'light': deque(maxlen=100),
            'air_quality': deque(maxlen=100)
        }
        
    def read_data(self):
        """Чтение данных с Arduino"""
        if self.serial_connection.in_waiting:
            raw_data = self.serial_connection.readline().decode().strip()
            try:
                # Парсинг JSON или CSV данных
                data = json.loads(raw_data)
                return data
            except:
                # Fallback для CSV формата
                values = raw_data.split(',')
                if len(values) == 5:
                    return {
                        'timestamp': int(values[0]),
                        'temperature': float(values[1]),
                        'humidity': float(values[2]),
                        'light': float(values[3]),
                        'airQuality': int(values[4])
                    }
        return None

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

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

def setup_plots(self):
    """Настройка графических окон"""
    self.fig, self.axes = plt.subplots(2, 2, figsize=(12, 8))
    self.fig.suptitle('Мониторинг окружающей среды')
    
    # Настройка каждого графика
    self.axes[0,0].set_title('Температура (°C)')
    self.axes[0,0].set_ylim(0, 50)
    self.axes[0,0].grid(True)
    
    self.axes[0,1].set_title('Влажность (%)')
    self.axes[0,1].set_ylim(0, 100)
    self.axes[0,1].grid(True)
    
    self.axes[1,0].set_title('Освещенность (lx)')
    self.axes[1,0].set_yscale('log')  # Логарифмический масштаб
    self.axes[1,0].grid(True)
    
    self.axes[1,1].set_title('Качество воздуха')
    self.axes[1,1].set_ylim(0, 1023)
    self.axes[1,1].grid(True)
    
    plt.tight_layout()
    plt.ion()  # Интерактивный режим

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

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

THRESHOLDS = {
    'temperature': {'min': 18, 'max': 26},      # Комфортная температура
    'humidity': {'min': 40, 'max': 60},         # Оптимальная влажность
    'light': {'min': 200, 'max': 1000},         # Достаточное освещение
    'air_quality': {'min': 0, 'max': 300}       # Приемлемое качество воздуха
}

def check_alerts(self, data):
    """Проверка превышения пороговых значений"""
    alerts = []
    
    for param, value in data.items():
        if param in THRESHOLDS:
            threshold = THRESHOLDS[param]
            if value < threshold['min']:
                alerts.append(f"⚠️ {param}: {value} ниже нормы ({threshold['min']})")
            elif value > threshold['max']:
                alerts.append(f"🚨 {param}: {value} выше нормы ({threshold['max']})")
    
    return alerts

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

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

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

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

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

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

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

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

Механика:

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

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

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

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

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

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

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

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

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

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

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

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

Влажность:

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

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

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

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

ДатчикПоказаниеЭталонКоэффициент
DHT22 (T)___ °C___ °CK = ___
DHT22 (H)___ %___ %K = ___
BH1750___ lx___ lxK = ___

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

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

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

#include <DHT.h>
#include <Wire.h>
#include <BH1750.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

// Конфигурация пинов
#define DHT_PIN 2
#define DHT_TYPE DHT22
#define MQ135_PIN A0
#define BT_RX 8
#define BT_TX 9

// Инициализация объектов
DHT dht(DHT_PIN, DHT_TYPE);
BH1750 lightMeter;
LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial bluetooth(BT_RX, BT_TX);

// Переменные данных
struct SensorData {
    float temperature;
    float humidity;
    float light;
    int airQuality;
    unsigned long timestamp;
};

SensorData currentData;

void setup() {
    // TODO: Инициализация всех компонентов
}

void loop() {
    // TODO: Основной цикл работы
}

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

void readSensors() {
    // Чтение температуры и влажности
    currentData.temperature = dht.readTemperature();
    currentData.humidity = dht.readHumidity();
    
    // Проверка на ошибки DHT22
    if (isnan(currentData.temperature) || isnan(currentData.humidity)) {
        Serial.println("Ошибка чтения DHT22!");
        return;
    }
    
    // Чтение освещенности
    currentData.light = lightMeter.readLightLevel();
    
    // Чтение качества воздуха
    currentData.airQuality = analogRead(MQ135_PIN);
    
    // Временная метка
    currentData.timestamp = millis();
    
    // Применение калибровочных коэффициентов
    applyCalibration();
}

void applyCalibration() {
    // TODO: Применить коэффициенты калибровки
    currentData.temperature *= TEMP_CALIBRATION;
    currentData.humidity *= HUMIDITY_CALIBRATION;
    currentData.light *= LIGHT_CALIBRATION;
}

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

void displayData() {
    lcd.clear();
    
    // Строка 1: T:25.3C H:45%
    lcd.setCursor(0, 0);
    lcd.print("T:");
    lcd.print(currentData.temperature, 1);
    lcd.print("C H:");
    lcd.print((int)currentData.humidity);
    lcd.print("%");
    
    // Строка 2: L:1250 A:245
    lcd.setCursor(0, 1);
    lcd.print("L:");
    if (currentData.light < 1000) {
        lcd.print((int)currentData.light);
    } else {
        lcd.print(currentData.light/1000, 1);
        lcd.print("k");
    }
    
    lcd.print(" A:");
    lcd.print(currentData.airQuality);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

# Быстрый тест приема данных
import serial
import json

ser = serial.Serial('COM5', 9600)  # Замените на ваш порт

for i in range(10):  # Прочитать 10 измерений
    if ser.in_waiting:
        data = ser.readline().decode().strip()
        try:
            parsed = json.loads(data)
            print(f"T: {parsed['temp']}°C, "
                  f"H: {parsed['hum']}%, "
                  f"L: {parsed['light']}lx, "
                  f"A: {parsed['air']}")
        except:
            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-предсказания экологических изменений

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