eDOT:基于 Arduino 的精密时钟与气象站,内置红外遥控
组件与物料
| 组件 | 数量 |
|---|---|
| Microchip 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 |
必要工具与设备
- Flashforge Dreamer 3D 打印机
应用与在线服务
- Arduino IDE
项目详解
eDOT 简介
eDOT 是一款基于 Arduino 的精密时钟与气象站,内置红外接收器和自动亮度调节。设计易于扩展,可加装 Wi-Fi 模块等额外硬件。得益于六块 8x8 点阵 LED 显示屏,可展示内部传感器数据、自定义滚动消息或来自互联网的无线信息(RSS 等)。功耗极低,设计简洁优雅,结合玻璃面板与 3D 打印外壳。项目持续开发中,后续会更新。
3D 打印部件下载:Thingiverse


更多项目请访问我的 YouTube 频道:https://www.youtube.com/channel/UCbIomyFKzBiLHqEb2xv9GHQ
物料清单 (BOM)
- 1× 3D 打印左半身
- 1× 3D 打印右半身
- 1× 3D 打印左盖
- 1× 3D 打印右盖
- 2× 3D 打印脚垫
- 12× 3D 打印显示屏支架
- 1× 磨砂玻璃 240×75×5 mm
- 1× 橙色滤光片
- 6× Adafruit 8x8 点阵显示屏 Luckylight M1603095 (白光)
- 6× MAX7219 驱动板
- 1× USB 引出板
- 1× BME280 引出板
- 1× DS3231 芯片
- 1× IR 接收器 IRM-56384
- 1× 光敏电阻 LDR-07
- 1× ATMEGA328PU (Arduino 定制板)
- 6× OMRON 12mm 轻触开关
eDOTcore PCB
终于拿到 eDOT 控制板的首批原型。

代码
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, tempavg; char tempf[8];
float hum, humavg; char humf[8];
float press, pressavg; char pressf[8];
int screen = 0;
long previousLEDMillis = 0;
long LEDInterval = 5000;
int screenMax = 5;
bool screenChanged = true;
float lightsens, screenBrt = 0, lightsensavg;
Average<float> avetemp(60);
Average<float> avehum(60);
Average<float> avepress(60);
Average<float> avelightsens(40);
// 校准系数
float temp_o = -1.70, temp_s = 1.0, temp_lin;
float hum_o = 2.45, hum_s = 1.0, hum_lin;
float press_o = 0.0, press_s = 1.0, press_lin;
// 亮度传感器修正
float brt_o = -4, brt_s = 1.35;
Schedular Task1;
Schedular Task2;
void setup() {
Task1.start();
Task2.start();
Wire.begin();
bme.begin(0x76);
matrix.setIntensity(screenBrt); // 亮度 0-15
// 设置显示屏旋转方向
for (int i = 0; i <= 7; i++) matrix.setRotation(i, 1);
/* matrix.setRotation(8, 1);
matrix.setRotation(9, 1); */
rtc.begin();
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// rtc.adjust(DateTime(2016, 02, 28, 16, 44, 0));
// Serial.begin(9600);
// eDOT 启动动画
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();
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);
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);
matrix.print(":");
if (outMin < 10) matrix.print("0");
matrix.print(outMin);
matrix.print(":");
if (outSec < 10) matrix.print("0");
matrix.print(outSec);
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);
matrix.print("/");
if (outmonth < 10) matrix.print("0");
matrix.print(outmonth);
matrix.print("/");
matrix.print(outyear);
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指南
- 树莓派 2 搭建户外气象站:接入 ADS‑WS1 串口气象站
- 高级气象站 v2.0:BME280 实时监测温度/气压/湿度/海拔 (Windows 10 IoT Core)
- Arduino POV 时钟:自制视觉暂留 LED 显示器
- 自制大尺寸LED主时钟带闹钟功能 — 12米外清晰可见
- Arduino Due 驱动 3.2″ TFT 实现温度监测与实时时钟
- 自制 10 美元便携 Arduino 气象站 - Nano + DHT22 + BMP180 + LCD
- Arduino Nano 驱动 128x64 OLED 实时运行康威生命游戏 (元胞自动机)
- Arduino + ThingSpeak 实时气象监测站
- 基于 Arduino 与 Google Sheets 的实时 RFID 考勤系统
- 基于Arduino、Windows IoT与Azure云的高级跌倒检测系统
- GPS 授时时钟:低成本高精度的 Arduino 卫星校时方案