Reloj con Arduino y DHT11 en OLED

Otro proyecto de reloj Arduino con una pantalla OLED i2c 128×64 y un sensor de temperatura y humedad DHT11 (que puede ser sustituido por un sensor de presión BMP180). Hemos colocado dos variantes a la vez: con módulo de reloj en tiempo real RTC (la hora sólo puede ajustarse en el propio software) y sin módulo RTC (la hora puede ajustarse en cualquier momento). Ambas variantes tienen una función de alarma.

Para esta actividad necesitaremos:

  • Arduino Uno / Arduino Nano / Arduino Mega
  • pantalla OLED 0.96 128×64 i2c;
  • sensor DHT11 y módulo DS1302;
  • zumbador y pulsadores;
  • cables de conexion;
  • librerias OLED_I2C.h, DHT.h y iarduino_RTC.h

Reloj Arduino en OLED 128×64 y DHT11

EReloj Arduino en OLED y DHT11
El circuito eléctrico – Reloj Arduino en OLED y DHT11
OLED i2c 0,96 Arduino Uno Arduino Nano Arduino Mega
GND GND GND GND
VDD 5V 5V 5V
SDA A4 A4 20
SCL A5 A5 21

La imagen de arriba muestra el diagrama de construcción del proyecto y la tabla muestra los pines para conectar el OLED a la placa Arduino. La biblioteca OLED_I2C.h es necesaria para la pantalla y DHT.h para el sensor de temperatura. El archivo con las bibliotecas puede descargarse de nuestro sitio web. Después de montar el circuito e instalar las librerías necesarias, carga el siguiente programa en el microcontrolador Arduino Uno.

Programa Arduino para reloj en OLED sin módulo RTC

#include "DHT.h"
DHT dht(2, DHT11);

#include "OLED_I2C.h"
OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t BigNumbers[];

byte SEC = 0;
byte MIN = 59;
byte HOUR = 7;
byte MIN_A = 0;
byte HOUR_A = 8;
unsigned long timer;

boolean button1WasUp = true;
boolean button2WasUp = true;
boolean button1IsUp;
boolean button2IsUp;

boolean alarm = true;
byte w, i;

void setup() {
  pinMode(9, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(5, OUTPUT);
  dht.begin();
  myOLED.begin();
  timer = millis();
}

void loop() {
   int h = dht.readHumidity();
   int t = dht.readTemperature();
  
  button1IsUp = digitalRead(9);
  button2IsUp = digitalRead(8);

  if (button1WasUp && !button1IsUp) {
    delay(10); button1IsUp = digitalRead(9);
    if (!button1IsUp) { SEC = 0; w = 1; } }
  button1WasUp = button1IsUp;
 
  if (button2WasUp && !button2IsUp) {
    delay(10); button2IsUp = digitalRead(8);
    if (!button2IsUp) { alarm = !alarm; } }
  button2WasUp = button2IsUp;

  if (millis() - timer > 1000) {
    timer = millis(); SEC++;
    if (SEC > 59) { SEC = 0; MIN++; }
    if (MIN > 59) { MIN = 0; HOUR++; }
    if (HOUR > 23) { HOUR = 0; }
    if (alarm == true && HOUR == HOUR_A && MIN == MIN_A && i < 60) {
      tone(5, 50); i++;
    }
    if (i >= 60) {
      noTone(5); alarm == false; i = 0;
    }

    myOLED.clrScr();
    myOLED.setFont(BigNumbers);
    
    if (HOUR < 10) { myOLED.print("0" + String(HOUR) + "-", 8, 20); }
    if (HOUR >= 10) { myOLED.print(String(HOUR) + "-", 8, 20); }
    if (MIN < 10) { myOLED.print("0" + String(MIN) + "-", 50, 20); }
    if (MIN >= 10) { myOLED.print(String(MIN) + "-", 50, 20); }
    if (SEC < 10) { myOLED.print("0" + String(SEC), 92, 20); }
    if (SEC >= 10) { myOLED.print(String(SEC), 92, 20); }
  
    myOLED.setFont(SmallFont);
    
    if (alarm == true) { myOLED.print("on ", RIGHT, 3); }
    if (alarm == false) { myOLED.print("off", RIGHT, 3); }
    
    myOLED.print(String(t) + "' / " + String(h) + "% ", RIGHT, 55);
    myOLED.update();
    noTone(5);
  }

  while (w == 1) {
    myOLED.clrScr();
 
    myOLED.setFont(BigNumbers);
    if (HOUR > 23) { HOUR = 0; }
    if (HOUR < 10) { myOLED.print("0" + String(HOUR) + "-", 8, 20); }
    if (HOUR >= 10) { myOLED.print(String(HOUR) + "-", 8, 20); }
    if (MIN < 10) { myOLED.print("0" + String(MIN) + "-", 50, 20); }
    if (MIN >= 10) { myOLED.print(String(MIN) + "-", 50, 20); }
    myOLED.print("00", 92, 20);
    
    myOLED.setFont(SmallFont);
    if (alarm == true) { myOLED.print("on ", RIGHT, 3); }
    if (alarm == false) { myOLED.print("off", RIGHT, 3); }
    myOLED.print("HOUR SETTING", CENTER, 55);
    myOLED.update();

    button1IsUp = digitalRead(9);
    button2IsUp = digitalRead(8);
    if (button1WasUp && !button1IsUp) {
      delay(10); button1IsUp = digitalRead(9);
      if (!button1IsUp) { w = 2; } }
    button1WasUp = button1IsUp;
    if (button2WasUp && !button2IsUp) {
      delay(10); button2IsUp = digitalRead(8);
      if (!button2IsUp) { HOUR++; } }
    button2WasUp = button2IsUp;
  }

  while (w == 2) {
    myOLED.clrScr();
 
    myOLED.setFont(BigNumbers);
    if (MIN > 59) { MIN = 0;}
    if (HOUR < 10) { myOLED.print("0" + String(HOUR) + "-", 8, 20); }
    if (HOUR >= 10) { myOLED.print(String(HOUR) + "-", 8, 20); }
    if (MIN < 10) { myOLED.print("0" + String(MIN) + "-", 50, 20); }
    if (MIN >= 10) { myOLED.print(String(MIN) + "-", 50, 20); }
    myOLED.print("00", 92, 20);

    myOLED.setFont(SmallFont);
    if (alarm == true) { myOLED.print("on ", RIGHT, 3); }
    if (alarm == false) { myOLED.print("off", RIGHT, 3); }
    myOLED.print("MINUTE SETTING", CENTER, 55);
    myOLED.update();

    button1IsUp = digitalRead(9);
    button2IsUp = digitalRead(8);
    if (button1WasUp && !button1IsUp) {
      delay(10); button1IsUp = digitalRead(9);
      if (!button1IsUp) { w = 3; } }
    button1WasUp = button1IsUp;
    if (button2WasUp && !button2IsUp) {
      delay(10); button2IsUp = digitalRead(8);
      if (!button2IsUp) { MIN++; } }
    button2WasUp = button2IsUp;
  }

  while (w == 3) {
    myOLED.clrScr();
 
    myOLED.setFont(BigNumbers);
    if (MIN_A > 59) { MIN_A = 0; HOUR_A++; }
    if (HOUR_A > 23) { HOUR_A = 0; }
    if (HOUR_A < 10) { myOLED.print("0" + String(HOUR_A) + "-", 8, 20); }
    if (HOUR_A >= 10) { myOLED.print(String(HOUR_A) + "-", 8, 20); }
    if (MIN_A < 10) { myOLED.print("0" + String(MIN_A) + "-", 50, 20); }
    if (MIN_A >= 10) { myOLED.print(String(MIN_A) + "-", 50, 20); }
    myOLED.print("00", 92, 20);

    myOLED.setFont(SmallFont);
    if (alarm == true) { myOLED.print("on ", RIGHT, 3); }
    if (alarm == false) { myOLED.print("off", RIGHT, 3); }
    myOLED.print("ALARM SET HOUR", CENTER, 55);
    myOLED.update();
 
    button1IsUp = digitalRead(9);
    button2IsUp = digitalRead(8);
    if (button1WasUp && !button1IsUp) {
      delay(10); button1IsUp = digitalRead(9);
      if (!button1IsUp) { w = 4; } }
    button1WasUp = button1IsUp;
    if (button2WasUp && !button2IsUp) {
      delay(10); button2IsUp = digitalRead(8);
      if (!button2IsUp) { HOUR_A++; } }
    button2WasUp = button2IsUp;
  }

  while (w == 4) {
    myOLED.clrScr();
 
    myOLED.setFont(BigNumbers);
    if (MIN_A > 59) { MIN_A = 0; HOUR_A++; }
    if (HOUR_A > 23) { HOUR_A = 0; }
    if (HOUR_A < 10) { myOLED.print("0" + String(HOUR_A) + "-", 8, 20); }
    if (HOUR_A >= 10) { myOLED.print(String(HOUR_A) + "-", 8, 20); }
    if (MIN_A < 10) { myOLED.print("0" + String(MIN_A) + "-", 50, 20); }
    if (MIN_A >= 10) { myOLED.print(String(MIN_A) + "-", 50, 20); }
    myOLED.print("00", 92, 20);
 
    myOLED.setFont(SmallFont); 
    if (alarm == true) { myOLED.print("on ", RIGHT, 3); }
    if (alarm == false) { myOLED.print("off", RIGHT, 3); }
    myOLED.print("ALARM SET MINUTE", CENTER, 55);
    myOLED.update();
 
    button1IsUp = digitalRead(9);
    button2IsUp = digitalRead(8);
    if (button1WasUp && !button1IsUp) {
      delay(10); button1IsUp = digitalRead(9);
      if (!button1IsUp) { w = 0; } }
    button1WasUp = button1IsUp;
    if (button2WasUp && !button2IsUp) {
      delay(10); button2IsUp = digitalRead(8);
      if (!button2IsUp) { MIN_A++; } }
    button2WasUp = button2IsUp;
  }

}

Explicación del código para reloj en OLED sin RTC:

  1. la hora y el despertador se pueden ajustar en el código del software;
  2. la hora y el despertador se pueden cambiar al principio del programa.

La segunda variante de reloj utiliza el módulo de reloj en tiempo real RTC basado en el chip DS1302/DS1307 utilizando la biblioteca iarduino_RTC.h. El diagrama de conexión del módulo y la pantalla OLED i2c de 128×64 al Arduino se muestra en la imagen superior. La configuración de la fecha y la hora en el programa se realiza con la función watch.settime(); sólo se puede configurar el reloj de alarma con los botones.

El circuito eléctrico - Reloj en OLED con RTC y DHT11
El circuito eléctrico – Reloj en OLED con RTC DS1302 y DHT11

Programa Arduino para reloj en OLED y RTC DS1302

#include "DHT.h"
DHT dht(2, DHT11);

#include "OLED_I2C.h"
OLED  myOLED(SDA, SCL, 8);

#include "Wire.h"
#include "iarduino_RTC.h"
iarduino_RTC watch(RTC_DS1302, 5, 6, 7); // RTC DS1302, RST, CLK, DAT
//  iarduino_RTC watch(RTC_DS1307);      // RTC DS1307 I2C
//  iarduino_RTC watch(RTC_DS3231);      // RTC DS3231 I2C

extern uint8_t SmallFont[];
extern uint8_t BigNumbers[];

byte MIN_A = 0;
byte HOUR_A = 8;
unsigned long timer;

boolean button1WasUp = true;
boolean button2WasUp = true;
boolean button1IsUp;
boolean button2IsUp;

boolean alarm = true;
byte w, i;

void setup() {
  pinMode(9, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(3, OUTPUT);
  dht.begin();
  myOLED.begin();
  timer = millis();
  watch.begin();

  watch.settime(0, 59, 7, 16, 02, 22, 3);
}

void loop() {
   int h = dht.readHumidity();
   int t = dht.readTemperature();

  button1IsUp = digitalRead(9);
  button2IsUp = digitalRead(8);

  if (button1WasUp && !button1IsUp) {
    delay(10); button1IsUp = digitalRead(9);
    if (!button1IsUp) { w = 1; } }
  button1WasUp = button1IsUp;
  if (button2WasUp && !button2IsUp) {
    delay(10); button2IsUp = digitalRead(8);
    if (!button2IsUp) { alarm = !alarm; } }
  button2WasUp = button2IsUp;

  if (millis() - timer > 1000) {
    timer = millis();
    if (alarm==true && watch.Hours==HOUR_A && watch.minutes==MIN_A && i<60) {
      tone(3, 50); i++;
    }
    if (i >= 60) {
      noTone(3); alarm == false; i = 0;
    }

    myOLED.clrScr();
    
    myOLED.setFont(BigNumbers);
    myOLED.print(watch.gettime("H-i-s"), CENTER, 20);
  
    myOLED.setFont(SmallFont);
    if (alarm == true) {
      myOLED.print(String(t) + "' / " + String(h) + "% / on ", RIGHT, 3);
    }
    if (alarm == false) {
      myOLED.print(String(t) + "' / " + String(h) + "% / off", RIGHT, 3);
    }
    myOLED.print(watch.gettime("d.m.Y, D"), CENTER, 55);
    myOLED.update();
    noTone(3);
  }

   while (w == 1) {
    myOLED.clrScr();
 
    myOLED.setFont(BigNumbers);
    if (MIN_A > 59) { MIN_A = 0; HOUR_A++; }
    if (HOUR_A > 23) { HOUR_A = 0; }
    if (HOUR_A < 10) { myOLED.print("0" + String(HOUR_A) + "-", 8, 20); }
    if (HOUR_A >= 10) { myOLED.print(String(HOUR_A) + "-", 8, 20); }
    if (MIN_A < 10) { myOLED.print("0" + String(MIN_A) + "-", 50, 20); }
    if (MIN_A >= 10) { myOLED.print(String(MIN_A) + "-", 50, 20); }
    myOLED.print("00", 92, 20);

    myOLED.setFont(SmallFont);
    if (alarm == true) { myOLED.print("on ", RIGHT, 3); }
    if (alarm == false) { myOLED.print("off", RIGHT, 3); }
    myOLED.print("ALARM SET HOUR", CENTER, 55);
    myOLED.update();
 
    button1IsUp = digitalRead(9);
    button2IsUp = digitalRead(8);
    if (button1WasUp && !button1IsUp) {
      delay(10); button1IsUp = digitalRead(9);
      if (!button1IsUp) { w = 2; } }
    button1WasUp = button1IsUp;
    if (button2WasUp && !button2IsUp) {
      delay(10); button2IsUp = digitalRead(8);
      if (!button2IsUp) { HOUR_A++; } }
    button2WasUp = button2IsUp;
  }

  while (w == 2) {
    myOLED.clrScr();
 
    myOLED.setFont(BigNumbers);
    if (MIN_A > 59) { MIN_A = 0; HOUR_A++; }
    if (HOUR_A > 23) { HOUR_A = 0; }
    if (HOUR_A < 10) { myOLED.print("0" + String(HOUR_A) + "-", 8, 20); }
    if (HOUR_A >= 10) { myOLED.print(String(HOUR_A) + "-", 8, 20); }
    if (MIN_A < 10) { myOLED.print("0" + String(MIN_A) + "-", 50, 20); }
    if (MIN_A >= 10) { myOLED.print(String(MIN_A) + "-", 50, 20); }
    myOLED.print("00", 92, 20);
 
    myOLED.setFont(SmallFont); 
    if (alarm == true) { myOLED.print("on ", RIGHT, 3); }
    if (alarm == false) { myOLED.print("off", RIGHT, 3); }
    myOLED.print("ALARM SET MINUTE", CENTER, 55);
    myOLED.update();
 
    button1IsUp = digitalRead(9);
    button2IsUp = digitalRead(8);
    if (button1WasUp && !button1IsUp) {
      delay(10); button1IsUp = digitalRead(9);
      if (!button1IsUp) { w = 0; } }
    button1WasUp = button1IsUp;
    if (button2WasUp && !button2IsUp) {
      delay(10); button2IsUp = digitalRead(8);
      if (!button2IsUp) { MIN_A++; } }
    button2WasUp = button2IsUp;
  }

}

Explicación del código para reloj en OLED y RTC DS1302:

  1. después de flashear el módulo RTC y ajustar la fecha y la hora correctamente, comenta o borra la línea watch.settime(); en el programa y carga el código en el Arduino;
  2. esta versión de firmware no permite ajustar la hora con los pulsadores, sólo se puede ajustar el despertador.

Conclusión. Hemos presentado dos versiones del reloj OLED a la vez: con y sin el módulo RTC. También puede encontrar un programa de ejemplo con un esquema del reloj LCD 16×02 en nuestra página web. Si estás usando la placa Arduino Mega, en esta placa los puertos SDA y SCL se encuentran en los pines 20 y 21. La placa Nano tiene el mismo pinout que la placa Uno y la pantalla se conecta a los puertos A4 (SDA) y A5 (SCL).


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *