• I was able to figure this out eventually. Can't believe how much google searching and code searching. Bluetooth specs are specific but not much help to the uninformed.

    Bottom line is that the value sent to the characteristic needs to be a signed 16 bit integer supplied as a mantissa with an 'implied' decimal exponent of -2. All along I was trying to fit a float16 or a half-precision float or a 4 bit exponent float variant into a sint16 and it just doesn't work. Duh.

    This works:

    function tempTo2a6e(temp) {
      var f = parseFloat(temp.toFixed(2)) * 100;
      if (tempTo2a6e.buf === undefined) tempTo2a6e.buf = new Uint8Array(2);
      tempTo2a6e.buf[0] = f & 0xff;
      tempTo2a6e.buf[1] = f >> 8 & 0xff;
      return tempTo2a6e.buf;
    }
    NRF.setServices({
      0x1809 : {
        0x2a6e : {
          readable : true, value : tempTo2a6e(E.getTemperature())
        }
      }
    });
    

    Be sure to disconnect from the puck and then connect using nRF Connect or whatever and look for the Health Thermometer service. The temperature now reads correctly as 18.75'C. If reading the value using another puck you just need to divide by 100 (or multiply by 10^-2).

    Of course this simple example doesn't update the temperature value over time. NRF.updateServices in some sort of a timed loop would do that.

    Writing a string to the characteristic does work (doesn't fail) and if you read back the data and interpet it as a string that will work too. But the spec for the characteristic is sint16. Tools like nRF Connect expect to see an sint16 vs an array of chacters which is why it appeared to display an incorrect value.

About

Avatar for dklinkman @dklinkman started