Lámpara de amanecer DIY

Lámpara de amanecer DIY terminada
Lámpara de amanecer DIY terminada

Esta es la construcción de mi lámpara de amanecer. Quería saber si una lámpara que simula el amanecer podía facilitar de verdad el despertarse en las oscuras mañanas de invierno. Como no quería gastar más de 60 euros en una lámpara ya hecha, y además me gusta fabricar cosas, se me ocurrió este diseño.

La idea es que la luz te ayude a despertarte poco a poco, igual que en una mañana de verano, de forma relajada y sin necesidad de una alarma brusca.

Está construida a partir de una lámpara de mesa Ikea Fado y una bombilla LED regulable, utilizando una base impresa en 3D para alojar la electrónica. La unidad final se controla desde mi panel de Node-RED en la Raspberry Pi.



Piezas necesarias para la lámpara de amanecer

  • Lámpara Fado - Ikea
  • Bombilla LED regulable - Ikea
  • WeMos D1 mini
  • Hi-Link 220V AC - 5V DC
  • Regulador PWM RobotDyn
  • Conectores Dupont
  • Base impresa en 3D
Lámpara Fado de Ikea
Lámpara Fado de Ikea
Bombilla LED regulable
Bombilla LED regulable
WeMos D1 mini
WeMos D1 mini
Hi-Link 220V AC - 5V DC
Hi-Link 220V AC - 5V DC
Regulador PWM RobotDyn
Regulador PWM RobotDyn
Base impresa en 3D para la lámpara de amanecer
Base impresa en 3D

Sin contar la impresión 3D, el coste total fue inferior a 25 euros.

Diseño e impresión

Base impresa en 3D para la lámpara de amanecer

Empecé utilizando SketchUp para diseñar una base que sujetara la electrónica encargada de controlar la lámpara.

El diseño puede descargarse en Thingiverse.

Imprimí con un 20 % de relleno y 3 perímetros para la base y las paredes. Así se consigue una pieza bastante sólida. Con los ajustes que utilicé, el tiempo de impresión supera las 12 horas.

Base impresa en 3D para la lámpara de amanecer lista para montar

La lámpara no se asienta completamente en la base impresa debido al estrechamiento de su parte inferior. No era mi intención, pero apenas se nota y, además, los cuatro pequeños huecos que quedan ayudan a disipar el calor.

Huecos visibles en el montaje de la lámpara de amanecer

Preparación y montaje

Añadiendo la electrónica a la base

Recortar el disipador térmico

Es necesario reducir la altura del disipador del regulador PWM RobotDyn para que quepa bajo la base de la lámpara.

Con una sierra para metal recorté 10 mm de la parte superior del disipador.

Recortar el disipador térmico

No suelo recomendar reducir el tamaño de un disipador, pero como la lámpara solo funcionará unos 45 minutos al día, la acumulación de calor debería ser mínima.

Soldar los pines del WeMos D1 mini

Utilicé dos grupos de pines, uno de 2 y otro de 4, tal y como se ve en la imagen.

  • Pines: 5V y G
  • Pines: D6, D7, D8 y 3.3V
Soldadura de pines en el D1 mini

Insertar y conectar los componentes

La electrónica queda sujeta con un poco de cola caliente.

He acortado cables Dupont estándar. La verdad es que debería invertir en una crimpadora, porque me ahorraría tiempo y el acabado sería mucho mejor.

Cableado de la lámpara de amanecer

Conexiones de cableado

  1. Alimentación AC del Hi-Link.
  2. Alimentación AC del Hi-Link.
  3. Conexión negativa DC empalmada al pin GND del WeMos.
  4. Conexión positiva DC al pin 5V del WeMos.
  5. Pin GND del regulador empalmado al pin G del WeMos.
  6. Pin VCC del regulador conectado al pin 3.3V del WeMos.
  7. Pin Z-C del regulador conectado al pin D6 del WeMos.
  8. Pin PWM del regulador conectado al pin D7 del WeMos.

Corta el cable de alimentación de la lámpara de forma que queden unos 100 mm en el lado de la bombilla. Estaña los extremos con una pequeña cantidad de soldadura, suelda también los cables AC del Hi-Link al cable de alimentación y fija todo en las bornas del regulador, tal como se muestra.

Cableado final de la lámpara de amanecer
Cableado final de la lámpara de amanecer

Puesta en marcha

Programando el WeMos D1 mini

Ya utilizo Node-RED y MQTT en mi Raspberry Pi para controlar varios dispositivos de la casa, así que quería integrar esta lámpara de amanecer DIY en el mismo sistema.

La parte principal del código que controla la placa reguladora procede de la página de GitHub de Nassir Malik aquí. Le agradezco mucho su trabajo, porque me sirvió de gran ayuda.

Añadí compatibilidad con Wi-Fi y MQTT, además de una rutina que incrementa progresivamente el brillo de la lámpara durante un periodo de 30 minutos.

#include "hw_timer.h"
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "Your SSID";
const char* password = "Your Password";
// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "MQTT Server IP Address";
// Initializes the espClient. You should change the espClient name if you have multiple ESPs running in your home automation system
WiFiClient sunrise;
PubSubClient client(sunrise);

const byte zcPin = 12;
const byte pwmPin = 13;

byte fade = 1;
byte state = 1;
byte tarBrightness = 5;
byte curBrightness = 0;
byte zcState = 0; // 0 = ready; 1 = processing;

void ICACHE_RAM_ATTR zcDetectISR ();
void ICACHE_RAM_ATTR dimTimerISR ();
int val = 1;
int tim = 1;
String lampState = "off";

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected - ESP IP address: ");
  Serial.println(WiFi.localIP());
}
void callback(String topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;

  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();
  if (topic == "sunriseLamp/state") {
    Serial.print("Turning on Outside light ");
    if (messageTemp == "on") {
      lampState = "on";
      Serial.print("On");
    }
    else if (messageTemp == "off") {
      lampState = "off";
      Serial.print("Off");
    }
  }
  Serial.println();
}
// This functions reconnects your ESP8266 to your MQTT broker
// Change the function below if you want to subscribe to more topics with your ESP8266
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("D1Mini_sunriseLamp")) {
      Serial.println("connected");
      // Subscribe or resubscribe to a topic
      // You can subscribe to more topics (to control more LEDs in this example)
      client.subscribe("sunriseLamp/state");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  pinMode(zcPin, INPUT_PULLUP);
  pinMode(pwmPin, OUTPUT);
  attachInterrupt(zcPin, zcDetectISR, RISING);    // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
  hw_timer_init(NMI_SOURCE, 0);
  hw_timer_set_func(dimTimerISR);
}
void mqttCheck() {
  if (!client.connected()) {
    reconnect();
  }
  if (!client.loop())
    client.connect("D1Mini_sunriseLamp");
}
void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    delay(1);
    setup_wifi();
    return;
  }
  mqttCheck();
  if (lampState == "off") state = 0;
  if (lampState == "on") {
    val = 1;
    state = 1;
    for (val <= 250; val++;) {
      tarBrightness = val;
      mqttCheck();
      if (lampState == "off") {
        state = 0;
        Serial.println(lampState);
        break;
      }
      delay(7200);
    }
  }
}
void dimTimerISR() {
  if (fade == 1) {
    if (curBrightness > tarBrightness || (state == 0 && curBrightness > 0)) {
      --curBrightness;
    }
    else if (curBrightness < tarBrightness && state == 1 && curBrightness < 255) {
      ++curBrightness;
    }
  }
  else {
    if (state == 1) {
      curBrightness = tarBrightness;
    }
    else {
      curBrightness = 0;
    }
  }
  if (curBrightness == 0) {
    state = 0;
    digitalWrite(pwmPin, 0);
  }
  else if (curBrightness == 255) {
    state = 1;
    digitalWrite(pwmPin, 1);
  }
  else {
    digitalWrite(pwmPin, 1);
  }
  zcState = 0;
}
void zcDetectISR() {
  if (zcState == 0) {
    zcState = 1;

    if (curBrightness < 255 && curBrightness > 0) {
      digitalWrite(pwmPin, 0);

      int dimDelay = 30 * (255 - curBrightness) + 400;//400
      hw_timer_arm(dimDelay);
    }
  }
}

Configuración en Node-RED

Estoy utilizando tres nodos en este flujo.

  • Big Timer Node - para más información, consulta Scargill’s Big-Timer
  • Switch Node - utilizado como anulación manual
  • Mqtt Output Node
Captura de pantalla del flujo de Node-RED
Captura de pantalla del flujo de Node-RED

He estado usando la lámpara de amanecer DIY durante unos días y, aunque la luz no me despierta siempre, es agradable no estar completamente a oscuras cuando mi Google Home Mini empieza a reproducir música.

Lámpara de amanecer terminada y lista para usar
Lámpara de amanecer terminada