eDOT: точные Arduino-часы и метеостанция с встроенным ИК-пультом
Компоненты и материалы
| Microchip Technology ATMEGA 328P-PU | 1 |
| MAXIM MAX7219 | 6 |
| BOSCH BME280 — плата GY-BMEP | 1 |
| Adafruit Luckylight 8x8 точечный LED-дисплей — M1603095 | 6 |
| DS3231 (RTC часы) | 1 |
| Arduino Nano R3 | 1 |
| Arduino UNO | 1 |
| eDOTcore (своя плата) | 1 |
Необходимые инструменты и станки
- 3D-принтер Flashforge Dreamer
Приложения и онлайн-сервисы
- Arduino IDE
О проекте
eDOT
— это Arduino-проект точных часов и метеостанции с встроенным ИК-приемником и автоматической регулировкой яркости.
Устройство спроектировано для легкого расширения дополнительным оборудованием, например, Wi-Fi модулем или другими.
Благодаря шести 8x8 точечным LED-дисплеям можно отображать множество типов информации: от внутренних датчиков, пользовательских бегущих строк или беспроводных данных из интернета (RSS и т.д.).
Очень низкое потребление энергии, простой и элегантный дизайн, сочетающий стеклянную лицевую панель и 3D-печатные детали корпуса.
Проект находится в разработке и будет обновляться.
Скачать 3D-детали на Thingiverse.


Смотрите также мой YouTube-канал для других проектов:
https://www.youtube.com/channel/UCbIomyFKzBiLHqEb2xv9GHQ
Спецификация (B.O.M.)
- 1 × 3D-печатная левая половина корпуса
- 1 × 3D-печатная правая половина корпуса
- 1 × 3D-печатная левая крышка
- 1 × 3D-печатная правая крышка
- 2 × 3D-печатная ножка
- 12 × 3D-печатная опора дисплея
- 1 × Полированное стекло 240×75×5 мм
- 1 × Оранжевый фильтр
- 6 × Adafruit 8x8 точечный дисплей Luckylight M1603095 (белый)
- 6 × Плата контроллера MAX7219
- 1 × USB breakout board
- 1 × Плата BME280
- 1 × Чип DS3231
- 1 × ИК-приемник типа IRM-56384
- 1 × Фоторезистор типа LDR-07
- 1 × ATMEGA328PU (пользовательская плата Arduino)
- 6 × Тактильные кнопки OMRON 12 мм
Плата eDOTcore
Наконец, я получил первые прототипы управляющей платы для eDOT.
Перейдите на страницу проекта eDOTcore.

Код
eDOT: универсальная точная метеостанция и часы Arduino
// eDOT: Versatile precision weather station and clock
// HISTORY
// 11/12/2105 Added measurement calibration coefficients
// 09/06/2016 Added automatic display brightness
// 09/06/2016 Added task scheduler
// 07/08/2016 Added eDOT splashscreen
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <Average.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "RTClib.h"
#include <EasyScheduler.h>
Adafruit_BME280 bme; // I2C
RTC_DS3231 rtc;
int pinCS = 10; // CS к этому пину, DIN к MOSI, CLK к SCK (cf https://arduino.cc/en/Reference/SPI)
int numberOfHorizontalDisplays = 7;
int numberOfVerticalDisplays = 1;
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);
#define TEMPERATURE 0
#define HUMIDITY 1
#define PRESSURE 2
#define TIME 3
#define DAY 4
#define DATE 5
float temp;
float tempavg;
char tempf[8];
float hum;
float humavg;
char humf[8];
float press;
float pressavg;
char pressf[8];
int screen = 0; // начальный экран
long previousLEDMillis = 0; // для обновления LED-дисплея
long LEDInterval = 5000; // задержка между экранами
int screenMax = 5; // максимальное количество экранов
bool screenChanged = true; // статус экрана
float lightsens;
float screenBrt = 0;
float lightsensavg;
Average<float> avetemp(60); // Усреднение температуры (60 сэмплов)
Average<float> avehum(60); // Усреднение влажности (60 сэмплов)
Average<float> avepress(60); // Усреднение давления (60 сэмплов)
Average<float> avelightsens(40); // Усреднение освещенности (40 сэмплов)
// Коэффициенты калибровки
float temp_o = -1.70;
float temp_s = 1.0;
float temp_lin;
float hum_o = 2.45;
float hum_s = 1.0;
float hum_lin;
float press_o = 0.0;
float press_s = 1.0;
float press_lin;
// Коррекция датчика яркости
float brt_o = -4;
float brt_s = 1.35;
Scheduler Task1;
Scheduler Task2;
void setup() {
Task1.start();
Task2.start();
Wire.begin(); // Запуск I2C
bme.begin(0x76);
matrix.setIntensity(screenBrt); // Значение от 0 до 15 для яркости
// Настройте под свои нужды
// matrix.setPosition(0, 0, 0); // Первый дисплей в <0, 0>
// matrix.setPosition(1, 1, 0); // Второй дисплей в <1, 0>
matrix.setRotation(0, 1); // Настройка ориентации дисплея
matrix.setRotation(1, 1);
matrix.setRotation(2, 1);
matrix.setRotation(3, 1);
matrix.setRotation(4, 1);
matrix.setRotation(5, 1);
matrix.setRotation(6, 1);
matrix.setRotation(7, 1);
/* matrix.setRotation(8, 1);
matrix.setRotation(9, 1); */
rtc.begin();
// matrix.setRotation(3, 2); // То же для последнего дисплея
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// rtc.adjust(DateTime(2016, 02, 28, 16, 44, 0));
// Serial.begin(9600);
// eDOT SPLASHSCREEN
matrix.fillScreen(0);
matrix.write();
matrix.setCursor(12,0);
matrix.print("eDOT");
for(screenBrt = 0; screenBrt <= 15; screenBrt++) {
delay(25);
matrix.setIntensity(screenBrt);
matrix.write();
}
delay(250);
for(screenBrt = 15; screenBrt >= 0; screenBrt--) {
delay(50);
matrix.setIntensity(screenBrt);
matrix.write();
}
delay(500);
matrix.fillScreen(0);
matrix.write();
delay(1000);
}
void loop() {
Task1.check(acq1, 500);
Task2.check(acq2, 20);
}
void acq1() {
// ПОЛУЧЕНИЕ ДАННЫХ И УСРЕДНЕНИЕ
temp = bme.readTemperature();
avetemp.push(temp);
tempavg = avetemp.mean();
hum = bme.readHumidity();
avehum.push(hum);
humavg = avehum.mean();
press = bme.readPressure();
avepress.push(press);
pressavg = avepress.mean();
DateTime now = rtc.now();
outSec = now.second();
outMin = now.minute();
outHour = now.hour();
outday = now.day();
outmonth = now.month();
outyear = now.year() - 2000;
dow = now.dayOfTheWeek();
}
void acq2() {
lightsens = analogRead(A3);
avelightsens.push(lightsens);
lightsensavg = avelightsens.mean();
screenBrt = constrain(((lightsensavg / 1023.0 * 15) * brt_s + brt_o), 0, 15);
matrix.setIntensity(screenBrt);
// ЛИНЕАРИЗАЦИЯ ДАННЫХ
temp_lin = tempavg * temp_s + temp_o;
hum_lin = humavg * hum_s + hum_o;
press_lin = pressavg * press_s + press_o;
unsigned long currentLEDMillis = millis();
// Serial.println(screenBrt);
if (currentLEDMillis - previousLEDMillis > LEDInterval) {
previousLEDMillis = currentLEDMillis;
screen++;
if (screen > screenMax) screen = 0; // возврат к начальному экрану после цикла
screenChanged = true;
}
// if (screenChanged) // обновление измерений при смене экрана
// {
// screenChanged = false; // сброс для следующей итерации
switch(screen) {
case TEMPERATURE:
dtostrf(temp_lin, 4, 2, tempf); // формат: 5 цифр с 2 десятичными
matrix.setCursor(6, 0);
matrix.setTextSize(1);
matrix.setTextColor(255);
matrix.print(tempf); // вывод температуры
matrix.drawRect(37, 0, 2, 2, 255); // символ градуса
matrix.setCursor(40, 0);
matrix.print("C");
matrix.write(); // запись данных на дисплей
matrix.fillScreen(0); // очистка дисплея
break;
case HUMIDITY:
dtostrf(hum_lin, 4, 2, humf);
matrix.setCursor(6, 0);
matrix.setTextSize(1);
matrix.setTextColor(255);
matrix.print(humf);
matrix.setCursor(37, 0);
matrix.print("%");
matrix.write();
matrix.fillScreen(0);
break;
case PRESSURE:
dtostrf(press_lin, 6, 0, pressf);
matrix.setCursor(0, 0);
matrix.setTextSize(1);
matrix.setTextColor(255);
matrix.print(pressf);
matrix.setCursor(37, 0);
matrix.print("Pa");
matrix.write();
matrix.fillScreen(0);
break;
case TIME:
matrix.setCursor(0, 0);
matrix.setTextSize(1);
matrix.setTextColor(255);
if (outHour < 10) matrix.print("0");
matrix.print(outHour, 0);
matrix.print(":");
if (outMin < 10) matrix.print("0");
matrix.print(outMin, 0);
matrix.print(":");
if (outSec < 10) matrix.print("0");
matrix.print(outSec, 0);
matrix.write();
matrix.fillScreen(0);
break;
case DATE:
matrix.setCursor(0, 0);
matrix.setTextSize(1);
matrix.setTextColor(255);
if (outday < 10) matrix.print("0");
matrix.print(outday, 0);
matrix.print("/");
if (outmonth < 10) matrix.print("0");
matrix.print(outmonth, 0);
matrix.print("/");
matrix.print(outyear, 0);
matrix.write();
matrix.fillScreen(0);
break;
case DAY:
matrix.setCursor(15, 0);
matrix.setTextSize(1);
matrix.setTextColor(255);
matrix.print(daysOfTheWeek[dow]);
matrix.write();
matrix.fillScreen(0);
break;
}
}
Производственный процесс
- DIY солнечная метеостанция на Raspberry Pi
- Сборка уличной метеостанции на Raspberry Pi 2 и ADS‑WS1
- Продвинутая метеостанция v2.0: мониторинг температуры, давления, влажности и высоты в реальном времени
- Arduino POV-часы: сборка дисплея на эффекте сохранения образа
- Создание пользовательских LED-часов с будильником — видно с 12 метров
- Монитор температуры и реальные часы на Arduino Due с TFT-дисплеем 3.2"
- Портативная метеостанция на Arduino Nano за $10: DHT22, BMP180 и LCD
- Клеточный автомат «Жизнь» Конвея на Arduino Nano с OLED 128x64
- Метеостанция на Arduino и ThingSpeak: температура и влажность в облаке
- Система учёта рабочего времени на RFID, Arduino и Google Таблицах