Sunrise lamp add-on for nixie alarm clock.

IMG_0848Finnish winter days are dark and cold. The sun rises only for short moment, and even then it is often cloudy, or the sun is so low that it can rarely be seen. A circadian clock is synchronized with daylight changes, and so without external stimulus from sunlight, my daily rhythm started to lag and spin around. Waking at morning was difficult task.

There is a ready-made solution for this, e.g. Philips does sell alarm clocks with build in wake-up lamps, that turn on at morning to artificially sync humans internal clock. Me being hacker, I had to make my own solution, as usual.

IMG_0857I already had my nice nixie alarm clock, that still by the way works perfectly and is daily use, so I only needed a way to control lights with wake up alarm. I bought cheap remote controlled sockets from hardware store. These use 433Mhz ASK coded rf remotes to activate relays in socket unit.

Luckily, these use fairly standard implementation, and eBay is full of 433Mhz transmitter+receiver kits due popularity of 433Mhz ISP radio band. There is also a ready-made ASK library for the arduino to control these remote outlets, and all sorts of home automation things. I connected the receiver module to the arduino, and fired up example sketch from library. This allowed me to capture rf data coming to remote.


Outlet 1 on
Decimal: 83029 (24Bit) Binary: 000000010100010001010101 Tri-State: 000FF0F0FFFF PulseLength: 351 microseconds Protocol: 1
Raw data: 10904,272,1120,276,1120,276,1120,276,1124,272,1120,276,1120,276,1132,204,592,64,1236,84,760,192,816,208,896,100,1812,208,464,160,2164,236,552,436,804,172,1692,352,88,52,208,564,228,716,104,272,128,380,364,

Outlet 1 off
Decimal: 83028 (24Bit) Binary: 000000010100010001010100 Tri-State: 000FF0F0FFF0 PulseLength: 351 microseconds Protocol: 1
Raw data: 10896,276,1128,268,1132,264,1124,276,1124,268,1124,276,1120,276,1116,976,420,976,432,964,428,964,428,968,432,964,420,976,420,280,1120,272,1128,272,1128,964,428,276,1124,968,424,272,1124,972,424,272,1132,964,424,

Outlet 2 on
Decimal: 86101 (24Bit) Binary: 000000010101000001010101 Tri-State: 000FFF00FFFF PulseLength: 351 microseconds Protocol: 1
Raw data: 10900,272,1124,272,1124,272,1120,276,1120,276,1124,272,1120,276,1120,972,428,268,1124,972,428,268,1132,964,420,276,1124,272,432,264,1124,272,1132,264,1124,972,420,276,1136,960,436,264,1124,968,428,272,1120,972,428,

Outlet 2 off
Decimal: 86100 (24Bit) Binary: 000000010101000001010100 Tri-State: 000FFF00FFF0 PulseLength: 351 microseconds Protocol: 1
Raw data: 10892,280,1124,272,1124,272,1120,280,1116,280,1116,280,1120,276,1124,968,428,268,1128,968,424,276,1120,972,432,264,1124,276,1120,276,1120,276,1120,276,1120,972,424,276,1116,976,428,268,1120,128,2904,96,156,36,88,

Outlet 3 on
Decimal: 70741 (24Bit) Binary: 000000010001010001010101 Tri-State: 000F0FF0FFFF PulseLength: 351 microseconds Protocol: 1
Raw data: 10900,272,1124,272,1128,264,1128,268,1120,276,1132,264,1124,272,1124,972,428,268,1120,276,1124,272,1120,976,420,276,1124,972,420,276,1124,272,1120,276,1120,972,424,276,1124,968,428,40,88,40,1332,216,1124,968,428,

Outlet 3 off
Decimal: 70740 (24Bit) Binary: 000000010001010001010100 Tri-State: 000F0FF0FFF0 PulseLength: 351 microseconds Protocol: 1
Raw data: 10896,280,1120,276,1120,276,1120,280,1116,280,1124,272,1120,276,1116,976,420,276,1124,276,1120,272,1124,968,424,276,416,280,416,980,424,272,1120,280,1128,268,1128,964,428,272,1124,968,432,232,600,56,108,160,744,

Outlet 4 on
Decimal: 21589 (24Bit) Binary: 000000000101010001010101 Tri-State: 0000FFF0FFFF PulseLength: 351 microseconds Protocol: 1
Raw data: 10904,272,1120,276,1120,276,1116,280,1116,280,1120,276,1120,276,1116,280,1124,272,1116,980,424,272,1120,976,424,272,1120,972,424,276,1120,272,1120,280,1120,972,420,280,1120,972,424,272,1120,976,428,472,176,968,424,

Outlet 4 off
Decimal: 21588 (24Bit) Binary: 000000000101010001010100 Tri-State: 0000FFF0FFF0 PulseLength: 351 microseconds Protocol: 1
Raw data: 10900,276,1124,272,1124,272,1124,272,1120,276,1124,272,1120,276,1128,272,1120,276,1120,972,424,972,428,968,420,976,428,964,428,272,1132,264,1132,264,1124,972,424,272,1120,976,420,276,1124,972,428,268,1124,972,432,

 Now I had the data needed to send  rf commands to switch these outlets on and off. I had to make small board housing AVR attiny44 MCU and 433MHz transmitter module.IMG_0852Bit of a wire spaghetti and deadbug style soldering to prototype board. I need to start make my own PCB’s as we have CNC-milling machine at Tampere Hacklab that is perfect for making our own MCB’s, Milled Circuit Board that is.IMG_0851Transmitter module just plugs into the board, and there is couple of jumpers to change settings without need of reprogramming whole board. I was kinda clever, and as my clock has ISP port in back panel, I used it to transfer signal from alarm clock to this module thing. I can program both devices just plugin them into usbasp programmer, and connect them together with just normal 10 pin AVR ISP cable.

I used arduino to code small firmware to attiny44. I’m amazed how much even smallest mcu can do, run whole arduino sketch with libraries etc.

/*Alarm clock light control
 * *BACKUP!!! Error loading code from git!*

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

const int alarmsig = 6;     // Pin goes high when alarm is sound/snooze is on
const int rcPin = 3;        // Pin where transmitter is connected
const int dip1Pin = 0;      // Selects if outlets are turned off when alarm is muted
const int dip2Pin = 1;      // Selects if delay is applied when turning of lights
const int32_t ondelay = 600000;  // 10 min (600000ms) delay before lights are turned off
int alarmState = 0;         // current state of the Alarm
int alarmLastState = 0;     // previous state of the Alarm

void setup() {
  pinMode(alarmsig, INPUT);
  pinMode(dip1Pin, INPUT_PULLUP);
  pinMode(dip2Pin, INPUT_PULLUP);


void loop() {
  alarmState = digitalRead(alarmsig);
  if (alarmState != alarmLastState) {
    if (alarmState == HIGH) {
    else if (digitalRead(dip1Pin) == HIGH) {
       if (digitalRead(dip2Pin) == HIGH){

    delay(50);    // Delay a little bit to avoid bouncing   
  alarmLastState = alarmState;

void switchOutlet(int dev, int state) { //switchOutlet(device address [0-3],on/off)
  int32_t code[] = {83028, 86100, 70740, 21588}; // For BILTEMA remote outlets
  mySwitch.send(code[dev] + state,24);

This sends codes to outlets when state of SCK pin in ISP port changes. I made small modifications to nixie clocks firmware, just one line  that toggles SCK pin, when alarm goes off or snooze is on. I left option to change behavior of lights with jumpers on board, so I can enable turn off commands, and delay for those. In use I found out that actually I want lights to stay turned on after alarm, as anyway I will wake up and it is nice to have some light during day.


Plugged in to the back of nixie clock and some outlets connected to lights, I can now turn on lights when wakeup alarm goes off. Of course this solution was not as subtle as real wake-up lamps, as there is no brightness control or smooth ramp up before actual alarm, but they do wake me up much better than just piercing beeping in the dark. I probably could sleep over nuclear war, when I’m in deep sleep no sound can wake me up, but with these lights, after third snooze I’m able to wake up kinda alert.

Conclusion: This was useful and needed project, and first step for home automation. Sending rf commands to remote outlets works really well with cheap transmitter module and avr mcu, and this can be extended to other 433mhz device too. In the future, good improvement would be using dimmable outlets, and start ramping up brightness before auditory signal. At this moment I have 3 on/off outlets connected to lights on my nightstand, besides soffa and red led strip behind my computer desk. It would be nice also to get ceiling light behind remote-controlled dimmer. This system could be extended to full home automation system where I can control lights and devices from smart device or central control panel.

You should put your comment here!

This site uses Akismet to reduce spam. Learn how your comment data is processed.