Scene controller based on old x10 remote

  • I retrofitted old x10 remote (Model HR12A - can be had for under $10 on ebay) to work as scene controller for MySensors accompanied Vera setup.

    What I learned with Vera is that some cheap Z-wave remotes will not work with it (yes, I'm talking about you, GE45600) and others can only use "scene on" half of the keyboard. With this custom puppy we have full 36 scene activation combinations.

    I ran out of pins (only weirdos like A6 and A7 left) but there's also possibility to hook up the dial and report the battery status.

    Controller and radio "deep sleep" all the time waking up on interrupt when button is pressed then transmits the code and falls back asleep. I followed LED & voltage regulator disconnection procedures described here so with this in mind the battery should pretty much die of natural causes before discharging. 8M/3.3V chip, obviously only two batteries go in the 4x bay.

    Can't figure out how to post images here so here's the link:
    In last picture note there's 4pin connector to be able to program the remote without taking it apart. Serial pins there are: GND, TX, RX, DTR

    #include <MySensor.h>
    #include <SPI.h>
    #define CHILD_ID 0
    #define PRESSDELAY 200
    // pin assignments (0 terminates the arrays)
    const char
      a_keysHor[] = {A0, A1, A2, A3, A4, A5, 0},
      a_keyVer[] = {8, 7, 6, 0},
      n_irqPin = 3,
      n_ledPin = 4,
      n_pagePin = 5;
    // maps value to code calculated from key's coordinate
    const char
      a_keyMap[] = {1, 2, 4, 5, 3, 6, 8, 7, 10, 9, 11, 12, 15, 17, 18, 13, 14, 16};
    MySensor o_gw;
    MyMessage o_sceneOn(CHILD_ID, V_SCENE_ON);
    void setup()  {
      for (n_horLines = 0; a_keysHor[n_horLines]; n_horLines++) {
        pinMode(a_keysHor[n_horLines], OUTPUT);
        digitalWrite(a_keysHor[n_horLines], HIGH);
      for (n_verLines = 0; a_keyVer[n_verLines]; n_verLines++) {
        pinMode(a_keyVer[n_verLines], INPUT);
        digitalWrite(a_keyVer[n_verLines], HIGH);
      n_pageSize = n_horLines * n_verLines;
      pinMode(n_ledPin, OUTPUT);
      digitalWrite(n_ledPin, LOW);
      pinMode(n_pagePin, INPUT);
      digitalWrite(n_pagePin, HIGH);
      pinMode(n_irqPin, INPUT);
      digitalWrite(n_irqPin, HIGH);
      o_gw.sendSketchInfo("MySensors Remote", "1.0");
      o_gw.present(CHILD_ID, S_SCENE_CONTROLLER);
    void loop() {
      char n_hor, n_key;
      for (n_hor = 0; a_keysHor[n_hor]; n_hor++)
        digitalWrite(a_keysHor[n_hor], LOW);
      o_gw.sleep(1, LOW, 0);
      for (n_hor = 0; a_keysHor[n_hor]; n_hor++)
        digitalWrite(a_keysHor[n_hor], HIGH);
      while (n_key = f_readKey()) {
        digitalWrite(n_ledPin, HIGH);
        digitalWrite(n_ledPin, LOW);
    int f_readKey() {
      char n_hor, n_ver, n_key = 0;
      for (n_hor = 0; a_keysHor[n_hor]; n_hor++) {
        digitalWrite(a_keysHor[n_hor], LOW);
        for (n_ver = 0; a_keyVer[n_ver]; n_ver++) {
          if (digitalRead(a_keyVer[n_ver]) == LOW) {
            n_key = a_keyMap[n_ver + n_hor * n_verLines];
            if (digitalRead(n_pagePin) == HIGH)
              n_key += n_pageSize;
        digitalWrite(a_keysHor[n_hor], HIGH);
        if (n_key)
          return n_key;
      return 0;

    I'll try to answer any questions here.

  • @tigra
    Idiotic question.. That remote had a wireless thingy.. Why not use that?

  • Admin

    @tigra said:

    Can't figure out how to post images here so here's the link:

    Just drag-n-drop the to composer. Max size 2 Mb.

  • @hek
    Sometimes simple is just to complicated in a complicated world. Most of us are used to old forums format 😄

  • @Vladut-Grecu said:

    That remote had a wireless thingy.. W

    Indeed it was RF based remote control, but it was for X10 protocol and it wasn't compatible with my existing system. There's somewhat painful way to hook x10 to Vera via Raspberry running Mochad driver, but I'm getting rid of x10 altogether.

Log in to reply

Suggested Topics