I originally found MySensors while looking for a way to control 433mhz outlets with my Vera. Being frugal, I did not want to spend money on RFXtrx or similar device to control cheap outlets. My first sensor node was a nano with a 433mhz transmitter which controls several plugin outlets around my house. I later modified it to include the receiver which I used to intercept my neighbors weather station data. Unexpectedly, his weather station disappeared a few months ago and I stopped getting his data. I don't know if he took it down or it fell off his roof or was stolen. I waited a week and then sadly deleted the child devices on my Vera. Recently I decided to move on and find more uses for the 433mhz node, especially the reciever and stumbled upon some really cheap Chinese gadgets on Ebay/Ali and thought I would share some of what I found out.
First of all, the cheap Rx/Tx pair listed in the MySensors store is really cheap ($0.69?) but are not very good. The transmitter operates fine but the receiver is terrible. Both have acceptable range but I found I could not use the receiver with most of the available libraries due to the very poor signal/noise ratio. I had to 'sniff' most signals down to their binary level and re-encode this mess into a sketch for retransmission. Reception was also hit or miss. I recently upgraded to the superheterodyne Tx/Rx modules and like magic, all the libraries suddenly work, range seems slightly better but most noticeably, missed transmissions are gone.
I also recently bought this cheap rf LED strip controller for ~$1.80.
Surprisingly it actually works but the included remote has a range of only a few meters. So I sniffed the codes with the RCSwitch Library and wrote a sketch to test it with MySensors. Primarily I wanted to explore the dimming functionality and ran into a few problems. The unit dims the LED strip in very noticeable steps which cause the light to blink slightly as it dims, not very elegant but not a deal breaker (19 steps from 5-100%). The device is not individually addressable so if you have multiples, they will all follow the same commands. The fatal flaw of this device is the power on/off command is toggled which means the same code turns it off as turns it back on. I ran this for about 2 days and it missed a power on command (or a power off, I don't know). Once it got out of phase, it had to be manually corrected with the remote or remain out of phase until another missed command.
Another cheap chinese gadget I tested was this learning remote.
It has four buttons which can each be programed with any 433mhz code you want and store the code in memory to retransmit. I made up some codes which were similar in structure and pulse length as my 433mhz outlets use, made a simple sketch to broadcast the codes so I could 'program' the keychain remote. With 4 unique codes in the keychain, I modified my 433mhz sensor node sketch to include a scene controller sketch which toggles 4 scenes on and off (I used AWI's toggle scene controller sketch for the pertinent code-fu.). Unlike the rf LED controller, the scene state is stored in the arduino which makes it more dependable. Perhaps not as reliable as nrf , z-wave or zigbee, but for a $2 portable scene controller....not bad.
Attached is my sketch for toggling on an off four 433mhz outlets and a scene controller. The hardware is simple. I have a nano on mains power with the superheterodyne Rx on pin #2 and the Tx on pin #3. Both are power by 5V separately from the nano and have 17cm antenna soldered on.
#include <MySensor.h>
#include <SPI.h>
#include <EEPROM.h>
#include <MyTransportNRF24.h>
#include <MyHwATMega328.h>
#include <RemoteReceiver.h>
#include <RemoteTransmitter.h>
#include <InterruptChain.h>
#define NUMBER_OF_OUTLETS 4
#define SN "433mhz Bridge"
#define SV "1.3"
const byte SC_CHILD_ID = 0 ;
unsigned long receivedCode = 0 ;
int key=0;
// Setup arrays with the unique button codes sniffed using ShowReceivedCode.ino from the RemoteSwitch library
// These are outgoing codes, one array for 'switch on' and one for 'switch off'
long rfCodeON [] = {492004, 492022, 491914, 491752};
long rfCodeOFF [] = {492006, 492024, 491916, 491754};
int pulse = 185; //The average pulse length of the codes, needed for the RemoteTransmitter sendCode function
// Setup an array of the expected incoming codes from the KeyFob transmitter
unsigned long sceneCode [] = {491266, 491268, 491275, 491277};
byte keyState[4] ;
MySensor gw;
MyMessage scene_on(SC_CHILD_ID, V_SCENE_ON);
MyMessage scene_off(SC_CHILD_ID, V_SCENE_OFF);
void setup() {
Serial.begin(115200);
gw.begin(incomingMessage, 15, true);
gw.sendSketchInfo(SN, SV);
// Create a child device for each outlet
for (int sensor=1; sensor<=NUMBER_OF_OUTLETS; sensor++){
gw.present(sensor, S_LIGHT);
delay(2);
}
// Create a child device for the scene controller and load last Scenestates from EEPROM
gw.present(SC_CHILD_ID, S_SCENE_CONTROLLER);
for (int i=0 ; i < sizeof(sceneCode); i++){
keyState[i] = gw.loadState(i) ;
}
// Initialize receiver on interrupt 0 (= digital pin 2), calls the function "incomingCode"
RemoteReceiver::init(0, 2, incomingCode);
InterruptChain::addInterruptCallback(0, RemoteReceiver::interruptHandler);
}
void loop() {
gw.process();
}
// Function for when a code has been received from rF KeyFob transmitter
void incomingCode(unsigned long receivedCode, unsigned int period) {
//Disable the 433mhz Reciever to prevent additional interupts from incoming signals
RemoteReceiver::disable();
//Enable interupts to allow gw.wait
interrupts();
// Print the received code.
Serial.print("Code: ");
Serial.print(receivedCode);
Serial.print(", period: ");
Serial.print(period);
Serial.println("us.");
// check the recieved code against the array of expected codes
for (byte i = 0 ; i < 4 ; i++){
if(receivedCode == (sceneCode[i])) key=i+1;// set key if a valid code is recieved
}
// Print the scene number
Serial.print("Scene #: ");
Serial.println(key);
if (key > 0){
boolean keyVal = !gw.loadState(key-1); // use lastState from EEPROM and toggle
gw.saveState(key-1, keyVal); // save new state to EEPROM
if (keyVal) gw.send(scene_on.set(key-1)); // set the Scene On or Off
else gw.send(scene_off.set(key-1));
gw.wait(500);
key = 0; // reset key
receivedCode = 0 ; // reset code
RemoteReceiver::enable(); // turn 433mhz receiver back on
}
}
// Function for when a command has been received from gateway
void incomingMessage(const MyMessage &message)
{
{
if (message.type==V_LIGHT)
{
Serial.print("Outlet #: ");
Serial.println(message.sensor);
Serial.print("Command: ");
Serial.println(message.getBool());
// Turn off 433mhz receiver to prevent reception of outgoing 433mhz broadcast
RemoteReceiver::disable();
// Send out the code stored in the arrays based on which child id and command is recieved.
// Syntax is (pin 3, code to be transmitted, pulse length, transmit repetitions ~2^3 or 8 times)
RemoteTransmitter::sendCode(3,message.getBool()? rfCodeON[message.sensor - 1]: rfCodeOFF[message.sensor - 1], pulse, 3);
}
delay(50);
}
// Turn the 433mhz Receiver back on
RemoteReceiver::enable();
}