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: https://imgur.com/a/7EIqx
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};
char
n_horLines,
n_verLines,
n_pageSize;
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.begin();
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()) {
o_gw.send(o_sceneOn.set(n_key));
digitalWrite(n_ledPin, HIGH);
delay(PRESSDELAY);
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;
break;
}
}
digitalWrite(a_keysHor[n_hor], HIGH);
if (n_key)
return n_key;
}
return 0;
}
I'll try to answer any questions here.