BLE scan and advertising parallel?

Posted on
  • Is it possible to scan and advertise at the same time? I would like to do a setup with 3 beacon. Each beacon should scan for the other two beacons and save the current rssi. In the next Advertising package the beacon should send the last received rssi from the other two beacons. I'm new on programming with JavaScript. My current Codebase shows this:

    const be = {
          name: "BLE-Beacon B", // The name of the device
          showName: true, // include full name, or nothing
          discoverable: true, // general discoverable, or limited - default is limited
          connectable: true, // whether device is connectable - default is true      
          scannable : false, // whether device can be scanned for scan response packets - default is true
          interval: 300, // Advertising interval in msec, between 20 and 10000 (default is 375ms)
          manufacturer: 0x0590, // IF sending manufacturer data, this is the manufacturer ID
        };
    
    var deviceA = 0;
    var deviceB = 0;
    var deviceC = 0;
    
    // Start scanning
    started = true;
    logging = true;
    
    // scanning for the devices
    function scanDevice(d) {  
      let modified = false;
        
      // witch device is scanned
      // change the value
      switch (d.name) {
          case "BLE-Beacon A":
              modified = (deviceA !== d.rssi);
              deviceA = d.rssi;
              break;
          case "BLE-Beacon B":
              modified = (deviceB !== d.rssi);
              deviceB = d.rssi;
              break;
          case "BLE-Beacon C":
              modified = (deviceC !== d.rssi);
              deviceC = d.rssi;
              break;
      }
      
      // if value was modified setAdvertising to new Value
      if(modified){
        NRF.setAdvertising({
          0x180F: [deviceA]
          }, {
                name: be.name,
                manufacturer: be.manufacturer,
                interval: be.interval,
                manufacturerData: ["A", deviceA, "B", deviceB, "C", deviceC]
            });
      } else {
        console.log("nothing modified");
      }
      
    }
    
    // Initiales Scanning
    NRF.setScan(scanDevice, {filters: [{namePrefix:"BLE-Locate"}] });
    
    // Initiales Advertising
    NRF.setAdvertising({}, {
                name: be.name,
                manufacturer: be.manufacturer,
                interval: be.interval,
                manufacturerData: ["A", deviceA, "B", deviceB, "C", deviceC]
            });
    
    // Watch if BTN was pressed
    setWatch(function(){
     console. log("Device: " + be.name);
      
      if (started) {
        NRF.setScan();
        started = false;
        console.log("Stop Scanning");
      } else {
        NRF.setScan(scanDevice, {filters: [{namePrefix:"BLE-Locate"}] });
        started = true;
        console.log("Start Scanning");
      }
    }, BTN, {edge:"rising", repeat:1, debounce:20});
    
  • Hi - yes, BLE broadcast while scanning should 'just work' - however Espruino will only broadcast via BLE when you're disconnected from it, so that might be the issue you're hitting?

  • @Gordon yes that off course fixed the issue i have ;-). I've changed my code over the day it works like aspactad.

    let started = false;  // if scanning is startet
    var intervalLed;
    var selfid = NRF.getAddress().substr(12,5).replace(':',''); // get the last 5 digits of ble mac as id
    var scanIds = [ "5c5b", "69f0", "6d31" ];  // list of devices to scan for
    var data = new Uint8Array(scanIds.length); // define data as zero
    
    // Default ble settings
    const be = {
          name: "BLE "+ selfid, // The name of the device
          showName: true, // include full name, or nothing
          discoverable: true, // general discoverable, or limited - default is limited
          connectable: true, // whether device is connectable - default is true      
          scannable : true, // whether device can be scanned for scan response packets - default is true
          interval: 375, // Advertising interval in msec, between 20 and 10000 (default is 375ms)
          manufacturer: 0x0590, // IF sending manufacturer data, this is the manufacturer ID
        };
    
    // update Advertising by the current received rssi
    function updateAdvertising(device) {
      // our data - all 0 for nothing, 
      // or RSSI + 6 bytes address
      var id = device.id.substr(12, 5).replace(':','');
    
      if (!scanIds.includes(id)) return;
    
      data[scanIds.indexOf(id)] = device.rssi * -1; // converte to positive integer
    
      NRF.setAdvertising({}, {
        showName: false,
        connectable: false,
        scannable: false,
        interval: 100,
        manufacturer: be.manufacturer,
        manufacturerData: data
      });
      
      console.log("Found Device: " + id);
    }
    
    function setDefault() {
      // Initiale Advertising
      NRF.setAdvertising({}, {
        name: be.name,
        showName: be.showName,
        discoverable: be.discoverable,
        connactable: be.connectable,
        scannable: be.scannable,
        interval: be.interval,
        manufacturer: be.manufacturer,
        manufacturerData: data
      });
    }
    
    Pin.prototype.flash = function(period) { 
      var pin = this;
      digitalWrite(pin, true);
      setTimeout(function() {
        digitalWrite(pin, false);
      }, 100);
    };
    
    // Setting up defaults
    setDefault();
    
    // Watch if BTN was pressed
    setWatch(function(){
      console.log("Device: " + be.name);
      
      if (started) {
        console.log("Stop Scanning");
        NRF.setScan();  // Stop scanning on BLE devices
        clearInterval(intervalLed); // Stop Led from blinking
        started = false; // switch device status
        LED1.flash(); // Show stop with red LED
        setDefault();
      } else {
        console.log("Start Scanning");
        started = true;
        LED2.flash();  // Show start with green LED
        NRF.setScan(updateAdvertising); // Start scanning for BLE devices
        intervalLed = setInterval('LED2.flash();', 10000); // Flash the green led to visualise scanning mode
      }
    }, BTN, {edge:"rising", repeat:1, debounce:20});
    

    Now i have two new problems. First of all, after starting and stopping, i can't connect to the Puck-js scince i'm pull out the battery and plug it in again.

    ~~The second problem is the advertising interval. If i change the interval to somthing under 100ms i don't reseive any packages from the device. ~~

    [Edit] Answere for the second Question:
    NOTE: Non-connectable advertising can't have an advertising interval less than 100ms according to the BLE spec.

  • , i can't connect to the Puck-js

    Looks like you set connectable: false, but then there's a typo when you try and set it to true again connactable: be.connectable,

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

BLE scan and advertising parallel?

Posted by Avatar for kreativmonkey @kreativmonkey

Actions