433MHz RF communication module

Posted on
  • Even though I have a better - more sophisticated and more potential bearing - solution - LORA (Simple LORA field tests)- and despite my earlier comment of being fed up / done w/ cheapo 433MHz communication devices as shown on 433.92Mhz Transmitter and Receiver, I could not completely let go...

    I could not let it go because it would be nice to see it at least once transmit and receive something successfully, even though it would be only from the left side of the office table to the right side of the office table... But no, nothing at all...

    So here it comes:

    Using the code out of the box / off of the 433.92Mhz Transmitter and Receiver page, I get:

    New interpreter error: FIFO FULL
    

    For every second repeated transmitting the whole seconds modul0 60 with leading 0 as string I used this code:

    // x433tx.js
    var txDev  = require("433");
    var txPin  = B3;   // (PICO.4, 1=GND[USB left], 3=3.3V)
    var sigLED = LED1; // red blinks while xmitting
    function txStr() { // return string "00" .. "59"
      var s = "0" + Math.floor(getTime()) % 60;
      return s.substr(s.length - 2);
    }  
    function tx() {
      if (sigLED) sigLED.set();
      s = txStr;
      txDev.tx(txPin,s, 3, function(){
        if (sigLED) sigLED.reset();
      });
    }
    function onInit() {
      pinMode(txPin,"output");
      txPin.reset();
      setInterval(tx,3000);
    }
    setTimeout(onInit,1000);
    

    What I observed is that for the first of the every second repeated transmits, the red LED1 - indicating transmission time - is on longer...and after a while the LED1 stops coming on. So I power cycled and it worked for another set of transmissions... I did not count how many times it made it until it stopped. The transmiter

    For receiving the two bytes, I used this code:

    // x433rx.js
    var rxDev  = require("433");
    var rxPin  = B3;   // (PICO.4, 1=GND[USB left], 2=VBAT(5V USB), 3=3.3V)
    function rx() {
      try {
        LED2.set();
        LED1.reset();
        rxDev.rx(rxPin, function(d){
          console.log(d);
        });
      } catch(x) {
        LED1.set();
        LED2.reset();
        console.log("X: " + x);
        setTimeout(rx,100);
      }
    }
    function onInit() {
      pinMode(rxPin,"input_pulldown");
      rx();
    }
    setTimeout(onInit,1000);
    

    No matter what I did, I get:

    New interpreter error: FIFO FULL
    

    Initially, I had no try-catch setup, to restart the transmission on a fatal error... but was surprised that this error could not be caught...

    In a nutshell: no communication with the modules what so ever...

    PS: Some test code on both sides - switching transmitter on for 1/2 a second every second and polling / setWatching the data pin on the receiver w/ turning on the red LED1 - showed that both transmitter and receiver sides really worked. I had two full sets of two different brands - the one shown on 433.92Mhz Transmitter and Receiver Espruino site and better ones w/ ICs - f113 (6 pins) and 480R (8 pins) - four (4) transmitters and four (4) receivers - and they could not all be duds... no matter how dud the technologies used...

    Since @DrAzzy was 'successful' according to 433mhz Espruino <-> Arduino - even though he then (later) included Arduino as a communication controller/slave - I ordered for receiver two of his recommended devices: RXB12 (see Selection of 433mhz On/Off Keyed RF transmitter and receivers, with IC SYN470R, 16 pins). Now I had three (3) brands of receivers... and still now results (with 433 module from Espruino.com/modules page).

    (I guess 480R is about the same as 470R..., both SYN from Synoxo - see Synoxo - ASK/OOK RF Products, where SYN113 = f113 can be found...).

    to be continued...

  • To get to the bottom of the issue(s), I 'nlined' the 433 module and began to test with the following - single, generalized code, which behaves according to var xMode: 0= receiver, 1=transmitter```

    // x433.js
    var xMode = 1; // mode of operation: 0=rx, 1=tx
    
    // ----- get 433 module from 'inlined' source:
    
    var xDev  = (function(){
      var exports = {};
    
    /* Copyright (c) 2015 Gordon Williams, Pur3 Ltd. See the file LICENSE for copying permission. */
    /*
    // RX
    setTimeout(function() {
      require("433").rx(B13, console.log);
    }, 100);
    
    // TX
    require("433").tx(B13, "Hello", 5, function() {
      console.log("Sent!");
    });
    
    */
    /* Sends and receives data over simple 433Mhz AM radio links */
    
    
    function decode(w) {
      var l = w.data.length;
      var d = new Uint8Array((l+7)>>3);
      for (var i=0;i<l;i+=8)
        d[i>>3] = parseInt(w.data.substr(i,8),2);
      var data = new Uint8Array(d.buffer,0,d.length-1);
      var chksum = data.reduce(function(a,b){return a^b;},0);
      if (chksum == d[d.length-1])
        w.callback(data);
    }
    
    // The handler that gets called when the signal changes state. Ideally this would be compiled, but the Web IDE won't do that at the moment.
    function sig(w,e) {
     //"compiled";
     var d = 0|10000*(e.time-e.lastTime);
     if (d<1 | d>4) {
      if (w.data.length>20) decode(w);
      w.data="";
     } else if (!e.state) w.data+=0|d>2;
    }
    
    /* Set up to receive, and call the callback with a Uint8Array when something
    is received. */
    exports.rx = function(pin, callback) {
      // rcallback = callback; // aOC *** looks to be not in use?
      var w = {
        data : "",
        callback : callback,
        stop : function() { clearWatch(w.intr); }
      };
      // start listening for a change
      setTimeout(function() {
        // do it after a delay so it doesn't mess up the upload (if there's loads of noise)
        w.intr = setWatch(sig.bind(null,w), pin, {repeat:true, edge:"both"});
      }, 3000);
      return w;
    };
    
    // transmit the data using the given pin, repeated the given amount of times (5 seems good)
    exports.tx = function(pin, data, repeat, callback, logger) {
      var pulses = [];
      var arr = E.toUint8Array(data);
      // compute checksum
      var chksum = arr.reduce(function(a,b){return a^b;},0);
      data = new Uint8Array(arr.length+1);
      data.set(arr);
      data[data.length-1]=chksum;
      // output data, MSB first
      data.forEach(function(byt) {
        for (var b=7;b>=0;b--) {
          pulses.push((byt&128)?0.3:0.1, 0.42);
          byt<<=1;
        }
      });
      // finish up with a 1ms 'finish' pulse
      pulses.push(1);
      var msecs = E.sum(pulses)+1;  
      if (logger) logger.log({msecs:msecs,pulses:pulses});
      // Transmit
      function send() {
        digitalPulse(pin,1,pulses);
        if (repeat-- > 0) {
          // random time gaps between retransmission
          setTimeout(send, msecs+2+Math.random()*10);
        } else if (callback) {
          setTimeout(callback, msecs + 100);
        }
      }
      // one training pulse at the start
      digitalPulse(pin,1,[1]);
      // now start sending data
      setTimeout(send, 1.5);
    };
    
      return exports;
    })();
    
    // var xDev  = require("433");
    var xPin  = B3;   // (PICO.4, 1=GND[USB left], 2=VBAT(5V USB), 3=3.3V)
    
    
    // ----- rx --- xMode=0 -----
    
    function rx() {
      try {
        LED2.set();
        LED1.reset();
        xDev.rx(xPin, function(d){
          console.log(d);
        });
      } catch(x) {
        LED1.set();
        LED2.reset();
        console.log("X2: " + x);
        setTimeout(rx,100);
      }
    }
    
    function rxInit() {
      try {
        pinMode(xPin,"input_pulldown");
        rx();
      } catch(x) {
        console.log("X1: " + x);
        setTimeout(rx,100);
      }
    }
    
    // ----- tx --- xMode=1 -----
    
    var sigLED = LED1; // red blinks while xmitting
    function txStr() { // return string "00" .. "59"
      var s = "0" + Math.floor(getTime()) % 60;
      return s.substr(s.length - 2);
    }  
    function tx() {
      if (sigLED) sigLED.set();
      s = txStr;
      xDev.tx(xPin,s, 3, function(){
        if (sigLED) sigLED.reset();
      }, console);
    }
    function txInit() {
      pinMode(xPin,"output");
      xPin.reset();
      setInterval(tx,3000);
    }
    
    
    // ----- onInit() -----
    
    function onInit() {
      if (xMode) {
        txInit();
      } else {
        rxInit();
      }
    }
    
    setTimeout(onInit,1000);
    

    The only change so far is in the transmitter: logging what pulses will be 'sent' to the transmit device...

    The output (and error) I get in the console is:

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     1v99 (c) 2018 G.Williams
    >
    =undefined
    { "msecs": 370.16,
      "pulses": [ 0.1, 0.42, 0.3, 0.42, 0.3, 0.42, 0.3, 0.42, 0.1, 0.42, 0.3, 0.42, 0.3, 0.42, ....
    0.42, 1 ]
     }
    { "msecs": 370.16,
      "pulses": [ 0.1, 0.42, 0.3, 0.42, 0.3, 0.42, 0.3, 0.42, 0.1, 0.42, 0.3, 0.42, 0.3, 0.42, ....
    0.42, 1 ]
     }
    ERROR: Ctrl-C while processing interval - removing it.
    Execution Interrupted during event processing.
    New interpreter error: CALLBACK,MEMORY
    >
    

    Which tells me that just two (2) transmits made it before Espruino crashed?... weird is the Ctrl-C bla bla, though never did a Ctrl-C...

    I conclude that There is really something wrong in the State of Espruino.

    This is quite possible, since all the fuss about 315/433 communication stuff happened 3+ years ago...

  • You're on the standard 1v99 firmware?

    It seems to be that your biggest issue is:

    function tx() {
      if (sigLED) sigLED.set();
      s = txStr;
      txDev.tx(txPin,s, 3, function(){
        if (sigLED) sigLED.reset();
      });
    }
    

    If you add a console.log(s); to see what you're actually trying to send, you get:

    function () {var s = "0" + Math.floor(getTime()) % 60;
      return s.substr(s.length - 2);}
    function () {var s = "0" + Math.floor(getTime()) % 60;
      return s.substr(s.length - 2);}
    function () {var s = "0" + Math.floor(getTime()) % 60;
      return s.substr(s.length - 2);}
    function () {var s = "0" + Math.floor(getTime()) % 60;
      return s.substr(s.length - 2);}
    function () {var s = "0" + Math.floor(getTime()) % 60;
      return s.substr(s.length - 2);}
    Execution Interrupted during event processing.
    function () {var s = "0" + Math.floor(getTime()) % 60;
      return s.substr(s.length - 2);}
    function () {var s = "0" + Math.floor(getTime()) % 60;
      return s.substr(s.length - 2);}
    

    You missed out a () so instead of calling the function to get the data, you're sending the entire function! The 433 module isn't meant for sending lots of data, so the pulse train ends up being really long. While Espruino is sending all the data it's unable to do anything else (including reading data from the input fifo) so that probably explains the FIFO_FULL.

    For RX, you'd always have got FIFO_FULL on some modules (because if you get random noise, it comes in so fast that Espruino can't process it all fast enough). It just wouldn't have been reported previously.

    It shouldn't be a major issue, since when data starts arriving the noise drops off and Espruino is able to clear the backlog and get all the data that is sent.

    Also, if you want to trap a FIFO_FULL error, see the errorFlag event (http://www.espruino.com/Reference#l_E_errorFlag`) and E.getErrorFlags().

    Errors like FIFO_FULL aren't caused by JS execution, so it doesn't make sense having them as exceptions.

  • ooops! dooooh! ... that's for sure not what my intention was... I'm clear on that the 433 OOK is for small amounts of data only and that it has to be repeated... after all, it is just this single signal over and over sent until, for example, the lights come on or go off... At one time I had it right - in the txDev.tx(...,txStr(),...) transmit call... anyway: thank you for pointing it out.

    And yes, I'm on 1v99.

    I did some more work and worked through the different implementations as out of the box and what @DrAzzy did. There I verified 'down to the dot / pulses' that expected data was sent. I will share it in a next post.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

433MHz RF communication module

Posted by Avatar for allObjects @allObjects

Actions