• Hi,
    I have a digital hydrometer - a device called Tilt.

    On the iphone - using the nrf scanner app - I can see:

    {
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataLocalName = Tilt;
    kCBAdvDataServiceUUIDs = (
    "A495FF10-C5B1-4B44-B512-1370F02D74DE",
    "A495FF10-C5B1-4B44-B512-1370F02D74DE"
    );
    kCBAdvDataTxPowerLevel = 4;
    }
    

    I try to scan from the puck:

    >NRF.requestDevice({ filters: [{ name: 'Tilt' }] }).then(function(device) {
    :   console.log(device);
    : });
    =Promise: {  }
    Uncaught Error: Unhandled promise rejection: No device found matching filters
    > 
    

    NRF.connect takes a address - but I don't know what the address of the device is - none of the NRF apps appear to show the address.

    Any ideas how I can connect to this device?

  • I’d seen the Tilt and was interested in how it worked and trying to make one (espruino on micro bit). So I’ve seen a number of tutorials out there on connecting to a tilt from Rasp Pi using Python - maybe they can offer some insight?

  • I have found nodejs examples and have connected with these under Linux, but this is not showing on the scan, so I can’t connect to it with the puck.

  • You could use NRF.findDevices(print) and then see what data it prints out that you could use to scan from? At the very least that'll give you an address, but you could also look at using that Service UUID...

  • I had used finddevices - apple tvs and laptops appeared but not the tilt device. That’s why I thought I could filter on name.

    So this sort of thing?

          NRF.requestDevice({
            filters: [{
                    services: ['A495FF10-C5B1-4B44-B512-1370F02D74DE']­
                    }]
            })
    
    
  • Yes - the above looks right - but findDevices uses exactly the same code requestDevice does for grabbing devices, so if findDevices doesn't list it there's no way that requestDevice will work.

    What if you do NRF.findDevices(print,10000) - it'll then scan for 10 seconds and return the response. It's possible that the Tilt doesn't advertise very often in order to conserve battery power.

  • It's possible that the Tilt doesn't advertise very often in order to conserve battery power.

    That makes sense. Don't need second by second readings on a process which lasts 7 - 14 days. But if @Wilberforce can see it on Rasp Pi with Node.js, would that be the case?

    @Wilberforce there is an OS project out there that uses Wifi called Spindel. Probably power hungry would expect, but for personal use, and putting patents to side, this is a really interesting project for accelerometer and Espruino.

  • But if @Wilberforce can see it on Rasp Pi with Node.js, would that be the case?

    It looks like the code he posted just sits there scanning all the time - so it's like doing a really long findDevices or using setScan.

    I'd come across Tilt before. It's a really cool little device, and it's really nice how they're just using a 100% off the shelf 'Lightblue Bean' board inside. I imagine you could do something extremely similar with an Espruino and accelerometer board.

    I was going to do a video about doing bubble counting with Espruino and logging to Google Sheets with Espruino WiFi - turns out it's stupidly easy to get one of those cheap microphone modules and then shove the end of it in an airlock to listen for the 'blobble'. Not that it's particularly accurate or useful, but you do end up with a nice graph :)

  • I started messing with a load cell, but concluded it would be just as vague as a bubble counter - nice graph but really only indicative of when process had finished. Batch size also needs to be factored in, whereas nice thing about the Tilt is it calibrated so as well as determining when finished it gives the OG and FG data and batch size is irrelevant.

    Be interested to know if you got connected to it @Wilberforce?

  • I’m away at the moment so can test the tilt with the longer scan. The good things about the tilt is it also gives a temperature reading with the gravity. The downside is because it’s Bluetooth you have to be close to get a reading with your phone, unless you can use another device to proxy.
    @Ollie - yes I have seen that esp8266 project - someone was also offering kit to get all the hard to find bits and the 3D printed framework- it can in at about 1/2 the cost of the tilt. It would have the advantage of being WiFi. The battery life on the tilt is not great, and uses an expensive camera battery.

  • Hi, a bit of progress. By increasing the scan I now can find the device:

    NRF.findDevices(function(devices) {
      console.log(devices);
    }, 30000);
    
    [
    
    // Apple TV
      BluetoothDevice: {
        "id": "08:66:98:c6:75:50 public",
        "rssi": -90,
        "data": new Uint8Array([2, 1, 26, 10, 255, 76, 0, 16, 5, 1, 16, 104, 16, 8]).buffer,
        "manufacturer": 76,
        "manufacturerData": new Uint8Array([16, 5, 1, 16, 104, 16, 8]).buffer
       },
    // Red Tilt
      BluetoothDevice: {
        "id": "04:a3:16:9a:af:cc public",
        "rssi": -92,
        "data": new Uint8Array([26, 255, 76, 0, 2, 21, 164, 149, 187, 16, 197, 177, 75, 68, 181, 18, 19, 112, 240, 45, 116, 222, 0, 62, 3, 239, 197]).buffer,
        "manufacturer": 76,
        "manufacturerData": new Uint8Array([2, 21, 164, 149, 187, 16, 197, 177, 75, 68, 181, 18, 19, 112, 240, 45, 116, 222, 0, 62, 3, 239, 197]).buffer
       }
     ]
    

    I can connect by service, by adding the timeout of 20000:

    var gatt;
    NRF.requestDevice({ timeout: 20000,filters: [{ "services": [
         'a495ff10-c5b1-4b44-b512-1370f02d74de'
         ]}] }).then(function(device) {
       console.log(device);
      return device.gatt.connect();
     }).then(function(g) {
      gatt = g;
      return gatt.getPrimaryService("a495ff10-c5b1-4b­44-b512-1370f02d74de");
    }).then(function(service) {
      console.log({service:service});
    }).then(function() {
      gatt.disconnect();
      console.log("Done!");
    });
    
    =Promise: {  }
    BluetoothDevice: {
      "id": "04:a3:16:9a:af:cc public",
      "rssi": -88,
      "data": new Uint8Array([2, 1, 6, 17, 6, 222, 116, 45, 240, 112, 19, 18, 181, 68, 75, 177, 197, 16, 255, 149, 164, 2, 10, 0]).buffer,
      "services": [
        "a495ff10-c5b1-4b44-b512-1370f02d74de"
       ],
      "manufacturer": undefined, "manufacturerData": undefined }
    Uncaught Error: Unhandled promise rejection: Disconnected
    > 
    
    1. The getPrimaryService never gets fulfilled. Not sure what is going on here? There does not seem to be a way of adding a timeout?

    2. The manufacturer data in the first code block - seems to wrong - as 76 is apple and the previous devices is an apple tv- and in the 2nd block of code - it is undefined for the Tilt - so I'm wondering if the previous values are getting set?

    3. What is data in BluetoothDevice: structure?

    4. Can the device name be included in the BluetoothDevice: structure?

  • The getPrimaryService never gets fulfilled. Not sure what is going on here? There does not seem to be a way of adding a timeout?

    Once connected, the timeout is in the number of connection intervals taken I think. It's possible the Tilt just doesn't implement any service discovery so just ignores any requests - which would then result in a disconnection when Espruino tried to request them and never got s response. It would make sense for it to output all its data as advertising.

    The manufacturer data in the first code block - seems to wrong - as 76 is apple and the previous devices is an apple tv- and in the 2nd block of code - it is undefined for the Tilt - so I'm wondering if the previous values are getting set?

    I imagine it's actually pretending to be an Apple iBeacon, which is why it's using Apple's company ID. That's what https://github.com/baronbrew/tilt-scan/b­lob/master/tilt-scan.js seems to be detecting/doing.

    So what you'd want to do is basically just do the opposite of https://www.espruino.com/modules/ble_ibe­acon.js to decode the iBeacon info.

    What is data in BluetoothDevice: structure?

    That's the raw advertising data - you can see the manufacturer/manufacturerData in there, so I think it is correct.

    Can the device name be included in the BluetoothDevice: structure?

    It can, but doesn't have to be. There are 32 bytes of advertising data (IIRC) allowed, so I imagine it's pretty much all take up with iBeacon stuff and they decided not to include it.

  • Thanks Gordon.

    I can now see that:

    "data": new Uint8Array([
    

    26, // Length of manufacturer data
    255, // manufacturer data
    76, 0, // 0x4c, 0x00, // Apple company id
    2, // 0x02, // type: iBeacon
    21, // 0x15, // length of remaining data

    164, 149, 187, 16, 197, 177, 75, 68, 181, 18, 19, 112, 240, 45, 116, 222,
    // a495ff10-c5b1-4b44-b512-1370f02d74de

    0, 62, // major
    3, 239, // minor
    197 // rssi
    ]).buffer,

  • So major is temp in F, followed by minor - gravity reading

    0, 62 = 62F = 16.6c
    =3*256+239=1007 = 1.007 sg

    The NRf can connect and show the battery level as well, as there is a battery service too, so that would be useful to be able to get too.

  • d = new DataView(device.data);
    readings= { temp: (( d.getUint16(18) -32) * 5 / 9).toFixed(1), gravity:(d.getUint16(20)/1000.0).toFixed­(3)  };
    console.log(readings);
    

    { "temp": "16.7", "gravity": "1.007" }

  • Wow, that's great!

  • Very nice! Do you get wacky readings during a decent fermentation - I could see it being knocked about with some yeasts. Does their tilt app average it out?

  • I've haven't taken any long term readings to see that kind of detail. The readings are instaneous and not averaged. I have noticed after a big ferment that trub can sit on the top of the tilt and alter the reading - say 6 gravity points. However rousing the fermenter resolves that which is good practice anyway. The good thing about it is another temperature reading - it seems I have a 1 degree C gradient comparing to a thermocouple at the bottom. You can tell if a ferment is stalled, and know when you are 2/3 through if you want to do a temperature rise for a diacetyl rest - some ferments this occurs far quicker than you thought it would.

  • function reading(timeout) {
    NRF.requestDevice({ timeout: timeout,filters: [{ "services": [
         'a495ff10-c5b1-4b44-b512-1370f02d74de'
         ]}] }).then(function(device) {
       console.log(device);
      d = new DataView(device.data);
      dF=d.getUint16(22);
    readings= { temp: (( dF -32) * 5 / 9).toFixed(1), F:dF,gravity:(d.getUint16(24)/1000.0).to­Fixed(3), d:device.data  };
    console.log(readings);
      return 1;
     }).then(function() {
      console.log("Done!");
    });
    };
    
    reading(5000);
    
    =undefined
    BluetoothDevice: {
      "id": "04:a3:16:9a:af:cc public",
      "rssi": -89,
      "data": new Uint8Array([26, 255, 76, 0, 2, 21, 164, 149, 187, 16, 197, 177, 75, 68, 181, 18, 19, 112, 240, 45, 116, 222, 0, 62, 3, 238, 197]).buffer,
      "manufacturer": 76,
      "manufacturerData": new Uint8Array([2, 21, 164, 149, 187, 16, 197, 177, 75, 68, 181, 18, 19, 112, 240, 45, 116, 222, 0, 62, 3, 238, 197]).buffer,
      "services": [
        "a495ff10-c5b1-4b44-b512-1370f02d74de"
       ]
     }
    {
      "temp": "16.7",
      "F": 62,
      "gravity": "1.006",
      "d": new Uint8Array([26, 255, 76, 0, 2, 21, 164, 149, 187, 16, 197, 177, 75, 68, 181, 18, 19, 112, 240, 45, 116, 222, 0, 62, 3, 238, 197]).buffer
     }
    Done!
    

    And this is from the app:


    1 Attachment

    • tilt.PNG
  • This would actually be a really neat use for a Pixl.js (or just a Puck/MDBT42 with a display attached). You could actually display some historical data to give you some idea how things were going, and could then just leave it by the side.

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

Can't locate device by Name - solved with longer scan

Posted by Avatar for Wilberforce @Wilberforce

Actions