The following script will try to extract weather data from CC2650 SensorTag.
.lua
require "bleCentral" local bleState = "" local peripheralState = "" local myPeripheral = nil local peripheralName = "" -- Temperature TMP007 = { name = "TMP007" , dataUUID = "F000AA01-0451-4000-B000-000000000000" , confUUID = "F000AA02-0451-4000-B000-000000000000" , loData = nil , loDataUnit = "°C (ir)" , hiData = nil , hiDataUnit = "°C (die)" , convert = function(value) local loRaw, hiRaw = string.unpack("s16s16", value) -- IR[0:7], IR[8:15], DIE[0:7], DIE[8:15] local irTemp = tonumber(loRaw)/128 local dieTemp = tonumber(hiRaw)/128 return irTemp, dieTemp end , } -- Humidity HDC1000 = { name = "HDC1000" , dataUUID = "F000AA21-0451-4000-B000-000000000000" , confUUID = "F000AA22-0451-4000-B000-000000000000" , loData = nil , loDataUnit = "°C" , hiData = nil , hiDataUnit = "%RH" , convert = function(value) local loRaw, hiRaw = string.unpack("u16u16", value) -- Temp[0:7], Temp[8:15], Hum[0:7], Hum[8:15] local temp = (tonumber(loRaw) / 65536) * 165 - 40 local humidity = (tonumber(hiRaw) / 65536) * 100 return temp, humidity end , } -- Pressure BMP280 = { name = "BMP280" , dataUUID = "F000AA41-0451-4000-B000-000000000000" , confUUID = "F000AA42-0451-4000-B000-000000000000" , loData = nil , loDataUnit = "°C" , hiData = nil , hiDataUnit = "hPa" , convert = function(value) local loRaw, hiRaw = string.unpack("s24u24", value) -- Temp[0:7], Temp[8:15], Temp[16:23], Press[0:7], Press[8:15], Press[16:23] local temp if loRaw > 0 then temp = tonumber(loRaw) / 100 else temp = -(tonumber(loRaw) + 16777216) / 100 -- 16777216 = 2^24 end local pressure = tonumber(hiRaw) / 100 return temp, pressure end , } -- Illumination OPT3001 = { name = "OPT3001" , dataUUID = "F000AA71-0451-4000-B000-000000000000" , confUUID = "F000AA72-0451-4000-B000-000000000000" , loData = nil , loDataUnit = "none" , hiData = nil , hiDataUnit = "lux" , convert = function(value) local raw = string.unpack("u16", value) -- LightLSB:LightMSB local exponent = math.evalStr("shift(("..raw.." and 0hF000), -12)") local mantissa = math.evalStr("("..raw.." and 0h0FFF)") return 0, mantissa * (0.01 * 2^exponent) end , } sensorsList = {TMP007, HDC1000, BMP280, OPT3001} function on.resize() W, H = platform.window:width(), platform.window:height() leftMargin = W/100 fontSize = W/23 lineSpace = H/8 platform.window:invalidate() end function on.construction() refreshMenu() ble.addStateListener(stateListener) end function on.paint(gc) gc:setFont("sansserif", "r", fontSize) gc:drawString(bleState , leftMargin, lineSpace * 0) gc:drawString(peripheralName , leftMargin, lineSpace * 1) gc:drawString(peripheralState , leftMargin, lineSpace * 2) for i, sensor in ipairs(sensorsList) do if sensor.loData or sensor.hiData then gc:drawString( string.format( "%s : %.1f %s , %.1f %s", sensor.name, sensor.hiData, sensor.hiDataUnit, sensor.loData, sensor.loDataUnit ), leftMargin, lineSpace * (i + 2) ) end end end ------------------------------ -- Menu, Keyboard and Mouse -- ------------------------------ function refreshMenu() Menu = { {"Controls", {"Scan and Connect", function() peripheralOn() end}, {"Disconnect" , function() peripheralOff() end}, } } toolpalette.register(Menu) end -------------------------- -- Define state listner -- -------------------------- function stateListener(state) if state == "on" then peripheralOn() end bleState = "BLE: "..state platform.window:invalidate() end ---------------------------- -- Start or stop scanning -- ---------------------------- function peripheralOn() if peripheralState ~= "connected" then bleCentral.startScanning(scanner) end platform.window:invalidate() end function peripheralOff() bleCentral.stopScanning() if myPeripheral then myPeripheral:disconnect() end peripheralName = "" platform.window:invalidate() end -------------------- -- Define scanner -- -------------------- function scanner(peripheral) local name = peripheral:getName() or "" if peripheral and name:find("SensorTag") then myPeripheral = peripheral peripheralName = name peripheral:connect(connector) end platform.window:invalidate() end ---------------------- -- Define connector -- ---------------------- function connector(peripheral, event) local name = peripheral:getName() or "" if event == bleCentral.CONNECTED and name:find("SensorTag") then bleCentral.stopScanning() myPeripheral = peripheral peripheralName = name peripheral:discoverServices(servicesDiscoverer) elseif event == bleCentral.DISCONNECTED then myPeripheral = nil peripheralName = "" end peripheralState = peripheral:getState() platform.window:invalidate() end -------------------------------- -- Define services discoverer -- -------------------------------- function servicesDiscoverer(peripheral) if peripheral:getState() == bleCentral.CONNECTED then local servicesList = peripheral:getServices() for _, v in ipairs(servicesList) do v:discoverCharacteristics(characteristicsDiscoverer) end end platform.window:invalidate() end --------------------------------------- -- Define characteristics discoverer -- --------------------------------------- function characteristicsDiscoverer(service) local characteristicsList = service:getCharacteristics() for _, characteristic in ipairs(characteristicsList) do local UUID = characteristic:getUUID() for _, sensor in ipairs(sensorsList) do if UUID == sensor.dataUUID then characteristic:setValueUpdateListener(valueUpdateListener) characteristic:setNotify(true) elseif UUID == sensor.confUUID then -- characteristic:setWriteCompleteListener(valueUpdateListener) characteristic:write(string.uchar(0x01), true) end end end end ---------------------------------- -- Define value-update listener -- ---------------------------------- function valueUpdateListener(characteristic) local UUID = characteristic:getUUID() for _, sensor in ipairs(sensorsList) do if UUID == sensor.dataUUID then local value = characteristic:getValue() if value then sensor.loData, sensor.hiData = sensor.convert(value) end end end platform.window:invalidate() end
References: