Avatar for Eric

Eric

Member since Jan 2015 • Last active Jul 2017
  • 3 conversations
  • 34 comments

Brit living in Spain.
Writes web based software for a UK audio company.
Interest in electronics, solar & wind power generation & good beer.

Most recent activity

  • in Puck.js
    Avatar for Eric

    Thanks for the really helpful comments Gordon.

    The strings conversions was principally to overcome floating point numbers from the temperature readings (- minus values) and decimal points in voltage readings, but I guess I should move on and byte convert the values as much of the ble specification is set up as. Most coding is based on a quick and dirty work around. I had to write some code in node-red to convert strings to floats (see the flows attached in my last post) but I actually like the idea of compressing it all into bytes.

    I will need to think about priority queuing, but I am sure using a setWatch() function and increment counter as you suggest, I would get a really solid working model. I actually forgot that I had written some code years ago that counted the motion events over time, and only reacted if the value exceed a threshold. This reduced the noise you get when wind occasionally set the PIR detector.

    OK, V2 is now under way using an array of bytes with some code to convert values back. At worst I can use one advertising command for motion and a less frequent less important advert for cumulative data.

  • in Puck.js
    Avatar for Eric

    Would a simple vibration detector be suitable for zero battery drain option at a push?
    Not sure how sensitive they are, but worth playing with. Possibly coupled with magnetometer variances followed by a vibration signal to indicate a motion followed by a sudden stop.

    Another method could be based on a magnet mounted on rubber bands that would oscillate following a abrupt stop. Use the magnetometer to learn the polarity variances following various motions.

    Not as solid state but may have some experimental legs in it?

  • in Puck.js
    Avatar for Eric

    All what you say makes sense Gordon following on from my recent tests.

    I may help to make it clear what I am attempting and how I am progressing so far.

    The project is to set a range of Puck's to broadcast primarily motion detection but also temperature, light level, magnetometer, voltage readings and battery condition. The target uses are:

    a) Motion detection to turn lights on and off and act as intrusion detection.

    b) Pool water level detection and temperature using a floating magnet in the pool skimmer and a waterproof remote temperature IC. (Currently working using a Photon device and a solar panel / battery circuit)

    c) Soil moisture detection to trigger irrigation and monitor soil moisture over time.

    All of this was to be monitored, recorded and acted on using an externally situated Pi3 running node-red. Trigger actions are handled with a combination of IFTTT event handlers and notifications, and data logging using an SQL database.

    I must say that I am very happy with what has been achieved so far and most of the elements are working very well, but I feel it's not fully optimised yet.

    Initially I experimented with code that you posted to set up advertising a simple value:

    setInterval(function() {
      NRF.setAdvertising({
        0x1809 : [Math.round(E.getTemperature())]
      });
    }, 30000);
    

    It's clear now that this will set broadcasting up continuously the temperature reading, and update it every 30 seconds. All very good.

    I modified the code to send a second parameter to see if it was possible to send multiple sensors in the same broadcast command. For example:

    setInterval(function() {
      NRF.setAdvertising({
        0x1809 : [Math.round(E.getTemperature())],
        0x2a00 : [Math.floor((Math.random() * 10) + 1)]
      });
    }, 30000);
    

    Setting up a /ble/advertise/fd:f9:15:7f:43:07/# MQTT listener showed both values correctly and were also filterable using /0X809 and /0x2a00 in the filter.

    Adding a third or fourth value also worked until I more data to the array like a string of characters to represent the mag array, or just a random "Hello world" string. This broke the advertisement and threw an error in the Puck console. I believe it was a ble size error.

    Removing some of the data lines or shortening the strings sent fixed the error and all was good once more.

    To get around the problem, I divided the messaging up into multiple advertisements delayed by 5 seconds using setTimeout() functions. All these were wrapped in a 60 second setInterval() function to refresh the data readings.

    One other important discovery was that if you want to advertise an important event, you must stop other events from being advertised, or at least being refreshed, otherwise the event may be lost. This was the case for a motion detect event. To handle this I recorded state of the motion detector to suppress broadcasting of other data.

    Motion detection was also set up to be broadcast on a state change using a setWatch() function. This was the number one priority broadcast event so had to broadcast as soon as it occurred.

    Using this method led me to believe there is an advertise period (backed up by some NRF documents). The fully working code I used is:

    //7f:9a Motion detector code
    digitalPulse(LED1,true,1000);
    pinMode(D1, 'input_pulldown');
    pinMode(D30, 'input');
    var state =0;
    var zero = Puck.mag();
    
    NRF.setTxPower(4); // Full Power advertising
    
    
    function motion(){
      digitalPulse(LED3,true,100);
      advertise(1);
    }
    
    function reset(){
      digitalPulse(LED2,true,100);
      advertise(0);
    }
    
    function advertise(pinState){
      state = pinState;
      NRF.setAdvertising({
              0x2a00 : [state]
          });
      
    }
    
    setWatch(motion, D1, {repeat:true,edge:'rising',debounce:100}­);
    setWatch(reset, D1, {repeat:true,edge:'falling',debounce:100­});
    
    setInterval(function () {
      
      
      setTimeout(function(){
        if(state === 0){
          NRF.setAdvertising({
            0x2a01 : [String(E.getTemperature())]
          });
        }
      },1);
    
        setTimeout(function(){
          var volts = analogRead(D30)*6.6;
              volts = Math.round(volts * 100) / 100;
         if(state === 0){
          NRF.setAdvertising({
            0x2a02 : [String(volts)]
          });
         }
        },5000);
    
       setTimeout(function(){
          if(state === 0){
            NRF.setAdvertising({
              0x180f : [Puck.getBatteryPercentage()]
            });
          }
        },10000);
      
      setTimeout(function(){
          if(state === 0){
            NRF.setAdvertising({
              0x2a03 : [String(NRF.getBattery())]
            });
          }
        },15000);
      
        setTimeout(function(){
          if(state === 0){
            NRF.setAdvertising({
              0x2a04 : [String(Puck.light())]
            });
          }
        },20000);
      
        setTimeout(function(){
         if(state === 0){
          NRF.setAdvertising({
            0x2a05 : [String(getMag())]
          });
         }
        },25000);
    
    
    },60000);
    
    function getMag(){
      p = Puck.mag();
      p.x -= zero.x;
      p.y -= zero.y;
      p.z -= zero.z;
      var s = Math.sqrt(p.x*p.x + p.y*p.y + p.z*p.z);
       return Math.round(s * 100 ) / 100;
    }
    

    If anyone would like to see the node-red flow and view some of the output data I have attach then to this post.

    Finally a note about the battery life. If you simply watch all events from a Puck, you see a stream of RSSI adverts with the puck name:

    9/01/2017, 11:06:3194b19651.0be4b8
    /ble/advertise/fd:f9:15:7f:43:07 : msg.payload : string [34]
    {"rssi":-99,"name":"Puck.js 4307"}
    19/01/2017, 11:06:3194b19651.0be4b8
    /ble/advertise/fd:f9:15:7f:43:07/rssi : msg.payload : string [3]
    -99

    These occur continously, so the thought of of being able to have a multiplexing array of adverts that use the same broadcast stream would be really cool. Having it all handled in the command NRF.setAdvertising({id,[payload1]},{id,[­payload2]},id{id,[payload3]}, options) whoud be a simple way to set up non colliding event data as you suggested. Further options could be added to have a priority flag that ensured a motion event could be prioritised over another to be re-advertised on change.

    My current Puck battery life is holding out apart from initial uploading hundreds of times the code, but when left to advertise, appears to be steady. Temperature does effect the battery readings so you do have to watch trends over time.
    All food for thought and possibly outside the normal methods of ble data coms.

  • in Puck.js
    Avatar for Eric

    OK Thanks Gordon,

    I have tested that the advertising does indeed continue. The data doesn't change until you call the function again.

    What appears to be crucial to ensure the data has a fair chance of being picked up is to stagger the advertising interval and different setTimeout() periods that do not overlap too much. Setting them to the same interval tends to block each other.

    I remember reading in some NRF documentation that there is a random figure deployed in the advertising and switching of one of the three advertising channels to avoid collisions. I am also sure there was a duration setting as well to stop the advertising after a period of time.

    What would be the method to stop any previous advertising setup to reduce power and reduce the possibility of collisions if any?

    One other method to achieve this would be in the payload data rather than the channel as in a key pair payload. This would reduce the data allowed but for telemetry data should be fine.

  • in Puck.js
    Avatar for Eric

    I am using the Puck to advertise multiple sensors and to do this I set up a delay to sequence each sensor value. When monitored on node-red it would appear that the advertised value is only sent once or again if the value changes in the time before the next sensor value is advertised.

    This is OK for most uses, but if the Pi misses an advertisement data can be lost, like a motion sensor pulse.

    The question I have is, is an advertise duration option available? I know the advertise interval is, but how long it advertises for the set interval before it stops I am not sure.

    When you monitor RSSI it appears to be a constant stream of advertisements. Is this possible to set up with NRF.

    Perhaps it is set to only re-advertise onChange()?

  • in Puck.js
    Avatar for Eric

    Forgot to add that the Pucks are on the same table as the Pi's. All within a metre or two. One thing did come to mind in that in the scan there are around 10 advertising devices near the Pi. If there are so many, could they be delaying the responses, or blocking the responses from the Puck that is trying to respond?

    Perhaps I should increase the power to 0dBm to see if it improves the results?

    Also, having the EspruinoHub report the results of the scan does seem an additional overhead in the timing. I wonder if it's possible to mute the scan results to see if the writing to console may be making a difference?

  • in Puck.js
    Avatar for Eric

    It's a bit of a mix of fortunes really.
    Raspian has been shipping node-red for some time and it comes with node 0.10.29 pre-installed. The Rpi3 compiled and ran using v0.10.27 but the disconnection errors were creating problems as reported in the other thread.

    The older Rpi2 would not compile EspruinoHub using v0.10.27 hence the drive to go up in revision. Now its on node v4.7.2 everything compiles and works in read mode, but not write. I still think you may have something about the dongle drivers etc. I think it's worth getting a second BLE dongle and re-try.

    Thank you for all your efforts. It must be a nightmare trying to juggle so many OS versions and hardware revisions.

    FYI When we spoke about this during the Kickstarter funding, I did ask about doing this as a bridge to get the Pucks into an IoT system that is web connected. node-red does a good job at bridging this technology, but you also recommended backing the new Onion project, which I did. I expect my Onion to be in Spain next week, so am intrigued to know if EspruinoHub will work for the Onion also.

  • in Puck.js
    Avatar for Eric

    Hi @Gordon,
    The new build for the Rp2 I have, reports:

    Error Connecting: Error: Command Disallowed

    The Rp3 build using exactly the same OS and versions of node etc, does not return an error as it does connect OK, but is still very flakey.

    The scan stopped and scan started messages are displayed as you hinted to, but it will possibly work once on first launch, but after a few unsuccessful attempt to write, it exits due to no scan results:

    Scanning stopped.
    disconnected!
    Scanning started.
    Scanning started.
    Scanning stopped.
    Scanning stopped.
    Scanning stopped.
    Scanning stopped.
    Timed out getting services. Disconnecting.
    Scanning started.
    BLE broken? No advertising packets in 10 seconds - restarting!

    BTW, was this update intended to help fix the RP2 disconnection thread
    http://forum.espruino.com/conversations/­297940/ or this thread?

Actions