Experimenting with cheap 433mhz gadgets



  • 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.
    IMG_20151029_171728.jpg

    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.
    IMG_20151029_171647.jpg

    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();
    }    
      
    

  • Admin

    Wow, cool.



  • @Dwalt Just curious if you added an antenna to your original transmitter.
    they helped my range a great deal.
    http://www.ebay.com/itm/10pcs-433MHz-antenna-Helical-antenna-Remote-Control-for-Arduino-Raspberry-pi-/371200245857?hash=item566d424061:g:kf0AAOxyBPZTgvGe

    should help even on your new ones


  • Contest Winner

    I added an antenna to my 433mhz sender and discovered that my mySensors node had had twice the distance of the remote that went the original 433Mhz. Such antennas can be be easily made but .i bought one for like €0,75.

    Even though I really like the 433mhz equipment I wouldn't use it for the more delicate sensors. Just because they can be sniffed really easy. But great work!



  • @mvader said:

    @Dwalt Just curious if you added an antenna to your original transmitter.
    they helped my range a great deal.
    I used 17cm straight wire to make homemade antennae on all my Rx/Tx modules. Those that you posted are nice (very compact) and are probably much better than my homemade fix. My original Tx range was pretty good and I don't know if the new module has significantly improved range, but I have not noticed as many missed transmissions as the older, cheaper module. The big improvement is the Rx module. Previously the signal was so noisy, the libraries could not decipher the signals on their own and I had to sniff the signals 'manually'.

    @TheoL said:

    Even though I really like the 433mhz equipment I wouldn't use it for the more delicate sensors. Just because they can be sniffed really easy. But great work!

    I agree, I am replacing one 433mhz outlet at a time from my setup as finances allow. It is just hard to resist hacking the cheap stuff. 😄



  • I've been wanting to incorporate some 433mhz weather sensors. I'll be using this!



  • Hello,
    after many test to command my chacon rf433 wall plugs i am really pleased about this feature; its cheap and i have a sketch which is ok to command 4 plugs but now i want to receive my rf433 codes from a remote but i cant do myself a sketch for mysensors ; with a example arduino sketch i can read codes but i don't know how to make a sketch to send a message in mysensors for my jeedom controller. (with the codes i want to trigger a scenario)
    I understant that Walt seems to have done this: is it possible to have the code for this ? Thanks for your help


  • Hero Member

    @Dwalt great post!
    I too played with some cheap 433 receivers and PIR units... the result was rubbish! Looks like I need a better receiver - so thanks for the post!



  • @bigjimjeedom

    The sketch I posted above should be able to be adapted for your needs. The sketch controls four rf433 wall plugs and listens for codes from a rf433 remote and sends them to my controller as a scene controller. My controller is Vera. I am not familiar with jeedom but if it can handle a S_SCENE_CONTROLLER type sensor, then the sketch should work with little modification.

    What type of rf433 remote are you using? and what library (if any) are you using to sniff the codes?

    @gregl The superheterodyne receiver made all the difference for me.



  • Hello Dwalt ! thanks for your quick answer !
    My remote is an old style Chacon with 8 buttonsChacon-Télécommande-face.jpg
    [This remote has a 4 positions dip switch on the back (group 1 2 3 4) so i plan to put my 4 wall plugs on group 1 and my remote on group 2; with that, the plugs will be commuted by the mysensors rf433 emitter and the remote will send codes to my receiver mysensors without communicating directly with plugs]
    And my receiver is a "cheap" one but i will have a sperheterodyne in a few days (according yours tests)

    To receive my codes i use RCswitch library and this code:

    #include <RCSwitch.h>
    
    
    * RCSwitch mySwitch = RCSwitch();
    
    void setup() {
      Serial.begin(9600);
      mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2
    }
    
    void loop() {
      if (mySwitch.available()) {
        output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(),mySwitch.getReceivedProtocol());
        mySwitch.resetAvailable();
      }
    }
    

    With this i can read rf433 codes on serial but it don't send in mysensors..

    thanks for your help, i wil try to understand how to modify your code


Log in to reply
 

Suggested Topics

69
Online

11.4k
Users

11.1k
Topics

112.7k
Posts