从SensorTag获取温度数据作为广告

时间:2015-06-15 08:08:44

标签: android bluetooth-lowenergy

我正在与德州仪器SensorTag CC2541进行一些合作。我试图在广告包中显示温度数据。

首先,我在广告数据包中实现了温度服务UUID。这是在SensorTag.c固件中完成的(使用IAR Workbench for 8051)。

static uint8 advertData[] =
{
  // Flags; this sets the device to use limited discoverable
  // mode (advertises for 30 seconds at a time) instead of general
  // discoverable mode (advertises indefinitely)
  0x02,   // length of this data
  GAP_ADTYPE_FLAGS,
  DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,

  0x03,
  GAP_ADTYPE_16BIT_MORE,
  LO_UINT16(IRTEMPERATURE_SERV_UUID),
  HI_UINT16(IRTEMPERATURE_SERV_UUID)

};

这是扫描响应数组:

// GAP - SCAN RSP data (max size = 31 bytes)
static uint8 scanRspData[] =
{
  // complete name
  0x0A,   // length of this data
  GAP_ADTYPE_LOCAL_NAME_COMPLETE,
  0x53,   // 'S'
  0x65,   // 'e'
  0x6E,   // 'n'
  0x73,   // 's'
  0x6F,   // 'o'
  0x66,   // 'f'
  0x74,   // 't'
  0x69,   // 'i'
  0x61,   // 'a'

  // connection interval range
  0x05,   // length of this data
  GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
  LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
  HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
  LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
  HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),

  0x03,
  GAP_ADTYPE_16BIT_MORE,
  LO_UINT16(IRTEMPERATURE_SERV_UUID),
  HI_UINT16(IRTEMPERATURE_SERV_UUID)

};

然后,我使用示例蓝牙低功耗GAT应用程序并对其进行修改以在扫描时显示数据。原始应用程序用于另一个信标设备,它在扫描时显示信标名称+ RSSI +温度计服务。 这是原始代码:

class TemperatureBeacon {

    /* Full Bluetooth UUID that defines the Health Thermometer Service */
    public static final ParcelUuid THERM_SERVICE = ParcelUuid.fromString("00001809-0000-1000-8000-00805f9b34fb");


    /* Short-form UUID that defines the Health Thermometer service */
    private static final int UUID_SERVICE_THERMOMETER = 0x1809;


    private String mName;
    private float mCurrentTemp;
    //Device metadata
    private int mSignal;
    private String mAddress;

    /* Builder for Lollipop+ */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public TemperatureBeacon(ScanRecord record, String deviceAddress, int rssi) {
        mSignal = rssi;
        mAddress = deviceAddress;

        mName = record.getDeviceName();

        byte[] data = record.getServiceData(THERM_SERVICE);
        if (data != null) {
            mCurrentTemp = parseTemp(data);
        } else {
            mCurrentTemp = 0f;
        }
    }

    /* Builder for pre-Lollipop */
    public TemperatureBeacon(List<AdRecord> records, String deviceAddress, int rssi) {
        mSignal = rssi;
        mAddress = deviceAddress;

        for(AdRecord packet : records) {
            //Find the device name record
            if (packet.getType() == AdRecord.TYPE_NAME) {
                mName = AdRecord.getName(packet);
            }
            //Find the service data record that contains our service's UUID
            if (packet.getType() == AdRecord.TYPE_SERVICEDATA
                    && AdRecord.getServiceDataUuid(packet) == UUID_SERVICE_THERMOMETER) {
                byte[] data = AdRecord.getServiceData(packet);
                mCurrentTemp = parseTemp(data);
            }
        }
    }

    private float parseTemp(byte[] serviceData) {
        /*
         * Temperature data is two bytes, and precision is 0.5degC.
         * LSB contains temperature whole number
         * MSB contains a bit flag noting if fractional part exists
         */
        float temp = (serviceData[0] & 0xFF);
        if ((serviceData[1] & 0x80) != 0) {
            temp += 0.5f;
        }

        return temp;
    }

    public String getName() {
        return mName;
    }

    public int getSignal() {
        return mSignal;
    }

    public float getCurrentTemp() {
        return mCurrentTemp;
    }

    public String getAddress() {
        return mAddress;
    }

    @Override
    public String toString() {
        return String.format("%s (%ddBm): %.1fC", mName, mSignal, mCurrentTemp);
    }
}

如您所见,该程序使用THERM_SERVICE UUID(00001809-0000-1000-8000-00805f9b34fb)及其缩写形式(0x1809)。我尝试使用SensorTag IR Temperature UUID服务(F000AA00-0451-4000-B000-000000000000)对其进行修改。结果是,它既不能显示扫描设备的名称,也不能显示温度数据。

你能就这个问题提出一些建议吗?谢谢!

1 个答案:

答案 0 :(得分:0)

您问题中缺少的部分是修改后的SensorTag代码中的扫描响应结构。 advertData仅通知中央(iOS)其存在和可用服务(温度)。扫描响应可以携带更多信息,例如温度值。你能发布扫描响应数组吗?