eDOT: Reloj Preciso y Estación Meteorológica Arduino con Control IR Integrado
Componentes y suministros
| Microchip ATMEGA 328P-PU | ×1 |
| MAXIM MAX7219 | ×6 |
| BOSCH BME280 (placa GY-BMEP) | ×1 |
| Pantalla LED matriz de puntos 8x8 Adafruit Luckylight M1603095 | ×6 |
| DS3231 (RTC) | ×1 |
| Arduino Nano R3 | ×1 |
| Arduino UNO | ×1 |
| PCB eDOTcore | ×1 |
Herramientas y máquinas necesarias
- Impresora 3D Flashforge Dreamer
Aplicaciones y servicios en línea
- Arduino IDE
Sobre el proyecto
eDOT
Es un reloj de precisión y estación meteorológica basado en Arduino con receptor IR integrado y ajuste automático de brillo. Diseñado para expandirse fácilmente con módulos WiFi u otro hardware. Gracias a sus seis matrices LED 8x8 puede mostrar información de sensores internos, mensajes personalizados o datos de internet (RSS, etc.). Tiene consumo muy bajo, diseño elegante combinando frontal de vidrio y cuerpo impreso en 3D. El proyecto está en desarrollo y se irá actualizando.
Descarga las piezas 3D en Thingiverse.


Ver más proyectos en mi canal de YouTube: https://www.youtube.com/channel/UCbIomyFKzBiLHqEb2xv9GHQ
Lista de materiales (B.O.M.)
- 1× Mitad izquierda del cuerpo (impresa 3D)
- 1× Mitad derecha del cuerpo (impresa 3D)
- 1× Tapa izquierda (impresa 3D)
- 1× Tapa derecha (impresa 3D)
- 2× Patas (impresas 3D)
- 12× Soportes para displays (impresos 3D)
- 1× Vidrio bruñido 240×75×5 mm
- 1× Filtro naranja
- 6× Pantallas matriz 8x8 Adafruit Luckylight M1603095 (blanco)
- 6× Placas controlador MAX7219
- 1× Placa breakout USB
- 1× Placa breakout BME280
- 1× Chip DS3231
- 1× Receptor IR tipo IRM-56384
- 1× Fotorresistencia tipo LDR-07
- 1× ATMEGA328PU (placa Arduino personalizada)
- 6× Pulsadores táctiles OMRON 12mm
PCB eDOTcore
Por fin tengo los primeros prototipos de la placa de control para eDOT.
Visita la página del proyecto eDOTcore.

Código
eDOT: Estación meteorológica y reloj versátil de precisión
// eDOT: Versatile precision weather station and clock
// HISTORIAL
// 11/12/2105 Coeficientes de calibración de medición
// 09/06/2016 Brillo automático de pantalla
// 09/06/2016 Planificador de tareas
// 07/08/2016 Pantalla de inicio eDOT
#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 en pin 10, DIN en MOSI, CLK en SCK
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);
// Coeficientes de calibración
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;
// Corrección sensor brillo
float brt_o = -4, brt_s = 1.35;
Schedular Task1, Task2;
void setup() {
Task1.start(); Task2.start();
Wire.begin();
bme.begin(0x76);
matrix.setIntensity(screenBrt); // 0-15
// Configuración orientación displays
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);
rtc.begin();
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Descomenta para ajustar hora
// Pantalla de inicio 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() {
// ADQUISICIÓN Y PROMEDIADO
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*15)*brt_s + brt_o), 0, 15);
matrix.setIntensity(screenBrt);
// LINEARIZACIÓN
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,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;
}
}
Proceso de manufactura
- Estación meteorológica solar DIY con Raspberry Pi
- Construcción de una estación meteorológica exterior con Raspberry Pi 2 y ADS‑WS1
- Estación Meteorológica Avanzada v2.0: Monitorización en Tiempo Real de Temperatura, Presión, Humedad y Altitud
- Reloj POV con Arduino: Construye una pantalla LED de persistencia de visión
- Construye un Reloj Maestro LED Personalizado con Alarma – Visible desde 12 Metros
- Monitor de Temperatura y Reloj en Tiempo Real con Arduino Due y Pantalla TFT 3.2"
- Estación Meteorológica Portátil Arduino por $10 – Nano, DHT22, BMP180 y LCD
- Autómatas Celulares en Tiempo Real con Arduino y Pantalla OLED 128x64
- Monitorización Meteorológica en Tiempo Real con Arduino y ThingSpeak IoT
- Sistema de control de asistencia RFID en tiempo real con Arduino y Google Sheets
- Sistema Avanzado de Detección de Caídas con Arduino, Windows IoT y Azure Cloud