Метеостанция для записи температуры, атмосферного давления и влажности
Проекты на Arduino Uno и Slot Shield
Что должна уметь настоящая метеостанция? Измерять температуру и влажность в помещении, определять температуры за окном и атмосферное давление. А в идеале ещё и сохранять всё это в лог-файл.
Для хранения данных используем картридер для micro-SD. Данные сохранятся на карточки в виде текстового файла, который без проблем открывается на любом компьютере.
В остальном — это обычная метеостанция на Ардуино. Управляющая плата — оригинальная Arduino Uno. За температуру и влажность отвечает цифровой метеосенсор. Температуру на улице мы определяем с помощью герметичного термометра DS18B20. Атмосферное давление показывает барометр.
- Язык программирования: Arduino (C++)
Что потребуется
Полный сет компонентов проекта. В сет входят:
- цифровой метеодатчик
- четырёхразряный индикатор Quad Display
- SD картридер и карта форматаmicro-SD
Видеоинструкция
Как собрать
Установите Troyka Slot Shield на Arduino Uno
Подключите метеодатчик к пинам I²C разъёма A
.
Вставьте Quad Display в разъёмы E
и F
. Пин CS
подключите к 10
пину Arduino.
Барометр вставьте в пины I²C
разъёма B
.
Подключите термометр DS18B20 к пину 4
слота C
. Для этого используйте модуль подтяжки.
Установите SD картридер в слот D
и подключите к пину 8
.
Скетч
Прошейте контроллер скетчем через Arduino IDE.
- weather-station.ino
// библиотека для работы I²C #include <Wire.h> // библиотека для работы с метеосенсором #include <TroykaMeteoSensor.h> // Подключаем библиотеку для работы с дисплеем #include <QuadDisplay2.h> // библиотека для работы с модулями IMU #include <TroykaIMU.h> // библиотека для работы с протоколом 1-Wire #include <OneWire.h> // библиотека для работы с датчиком DS18B20 #include <DallasTemperature.h> // библиотека для работы с SPI #include <SPI.h> // библиотека для работы с SD-картами #include <SD.h> // сигнальный пин датчика DS18B20 #define ONE_WIRE_BUS 5 // даём разумное имя для CS пина microSD-карты #define SD_CS_PIN 8 // создаём объект для работы с метеосенсором TroykaMeteoSensor meteoSensor; // создаём объект класса QuadDisplay, передаём номер пина CS, включаем режим работы с SPI QuadDisplay qd(10, true); // создаём объект для работы с барометром Barometer barometer; // создаём объект для работы с библиотекой OneWire OneWire oneWire(ONE_WIRE_BUS); // создадим объект для работы с библиотекой DallasTemperature DallasTemperature sensor(&oneWire); // перечисляем имена операций, которые мы будем выводить на дисплей enum { SAVE_SD, // имя для операции, которая записывает на SD данные IN, // имя для операции, которая выводит на дисплей надпись "In" TEMP_IN, // имя для операции, которая выводит на дисплей температуру с метеосенсора CEL, // имя для операции, которая выводит на дисплей символ °C HUM_IN, // имя для операции, которая выводит на дисплей влажность с метеосенсора PPM, // имя для операции, которая выводит на дисплей символ % BAR_IN, // имя для операции, которая выводит на дисплей давление с барометра в миллиметрах ртутного столба MER, // имя для операции, которая выводит на дисплей надпись "Hg" EMPTY, // имя для операции, которая очищает дисплей OUT, // имя для операции, которая выводит на дисплей надпись "Out" TEMP_OUT // имя для операции, которая выводит на дисплей температуру с датчика DS18B20 }; // создаем массив, в котором будем хранить последовательность операций int chain[] = { IN, TEMP_IN, CEL, HUM_IN, PPM, BAR_IN, MER, EMPTY, OUT, TEMP_OUT, CEL, EMPTY, SAVE_SD }; // создаем объект класса long для хранения счетчика unsigned long respite_Time = 0; // создаем объект для регулировки времени показа значений на экране int slowdown_qd = 1000; // создаем объект для хранения номера выполняемой операции int number_qd = 0; // создаем объект для записи данных на SD строкой String dataString = ""; void setup() { // инициализация дисплея qd.begin(); // инициализируем метеосенсора meteoSensor.begin(); // инициализация барометра barometer.begin(); // инициализируем работу с датчиком DS18B20 sensor.begin(); // устанавливаем разрешение датчика от 9 до 12 бит sensor.setResolution(12); // инициализируем карту памяти SD.begin(SD_CS_PIN); // собираем верхнюю строчку с наименованием данных dataString = "TEMP_IN (ºC)\tHUM_IN (%)\tBAR_IN (mmHg)\tTEMP_OUT (ºC)"; // вызываем функцию сохранения данных на SD saveSD(dataString); } void loop() { // запускаем бесконечный счетчик. Его содержимое будет обрабатываться с периодом равным slowdown_qd if (millis() - respite_Time > slowdown_qd) { // запускаем процесс, который будет выполнять операции согласно последовательности в chain switch (chain[number_qd]) { case IN: qd.displayDigits(QD_I, QD_n, QD_NONE, QD_NONE); break; case TEMP_IN: showData(meteoSensor.getTemperatureC()); break; case CEL: qd.displayDigits(QD_NONE, QD_NONE, QD_DEGREE, QD_C); break; case HUM_IN: showData(meteoSensor.getHumidity()); break; case PPM: qd.displayDigits(QD_NONE, QD_NONE, QD_DEGREE, QD_UNDER_DEGREE); break; case BAR_IN: qd.displayInt(barometer.readPressureMillimetersHg()); break; case MER: qd.displayDigits(QD_NONE, QD_NONE, QD_H, QD_9); break; case EMPTY: qd.displayClear(); break; case OUT: qd.displayDigits(QD_O, QD_u, QD_t, QD_NONE); break; case TEMP_OUT: // переменная для хранения температуры float temperature; // отправляем запрос на измерение температуры sensor.requestTemperatures(); // выводим значение с датчика DS18B20 на экран qd.displayFloat(sensor.getTempCByIndex(0), 1); break; case SAVE_SD: // собираем в строку сначала температура с метеосенсора dataString = String(meteoSensor.getTemperatureC()) + "\t"; // потом влажность dataString += String(meteoSensor.getHumidity()) + "\t"; // давление dataString += String(barometer.readPressureMillimetersHg()) + "\t"; // и температура с датчика DS18B20 dataString += String(sensor.getTempCByIndex(0)) + "\t"; // вызываем функцию сохранения данных на SD saveSD(dataString); break; } number_qd++; // проверяем не превысил ли номер операции количество операций if (number_qd > sizeof(chain) / sizeof(int) - 1) number_qd = 0; respite_Time = millis(); } } // функция работы датчика температуры и влажности void showData(float data) { // считываем данные с датчика int stateSensor = meteoSensor.read(); switch (stateSensor) { // выводим показания на дисплей case SHT_OK: qd.displayFloat(data, 1); break; // выводим сообщение "Errd", если ошибка данных или сенсор не подключён case SHT_ERROR_DATA: qd.displayDigits(QD_E, QD_r, QD_r, QD_d); // выводим сообщение "ErrC", если ошибка контрольной суммы case SHT_ERROR_CHECKSUM: qd.displayDigits(QD_E, QD_r, QD_r, QD_C); break; } } // функция сохранения данных на карту памяти void saveSD(String data) { // создаем файл для записи данных File dataFile = SD.open("datalog.txt", FILE_WRITE); // если файл существует и открылся if (dataFile) { // сохраняем данные dataFile.println(data); // закрываем файл dataFile.close(); } else { // если файл не доступен выводим ошибку на дисплей qd.displayDigits(QD_E, QD_r, QD_r, QD_S); } }
Часто задаваемые вопросы
Где скачать необходимые библиотеки и как их установить?
У моего модуля QuadDisplay всего три ноги и расположены они слева. Можно ли использовать его в этом проекте?
У вас предыдущая версия модуля. Она снята с производства пару лет назад. С этим скетчем, библиотекой и схемой сборки модуль работать не будет.