TI-Nspire & SensorTag / 温度センサー TMP007 の値だけを取り出す


f:id:ti-nspire:20161111134827p:plain:h315
(photo: http://www.ti.com/ww/en/wireless_connectivity/sensortag2015/tearDown.html)

.lua

-- Refer to http://compasstech.com.au/TNS_Authoring/Scripting/script_tut34.html.
require "bleCentral"

local bleState        = ""
local peripheralState = ""
local myPeripheral    = nil
local peripheralName  = ""

-- Temperature
local tempDataUUID = "F000AA01-0451-4000-B000-000000000000" -- data: IR[0:7], IR[8:15], DIE[0:7], DIE[8:15]
local tempConfUUID = "F000AA02-0451-4000-B000-000000000000" -- configuration: Write 0x01 to enable data collection, 0x00 to disable.
local dieTemp      = nil
local irTemp       = nil

function on.resize()
   W, H = platform.window:width(), platform.window:height()
   leftMargin = W/100
   fontSize   = W/14
   lineSpace  = H/6
   platform.window:invalidate()
end
function on.construction()
   refreshMenu()
   ble.addStateListener(stateListener)
end
function on.paint(gc)
   gc:setFont("sansserif", "r", fontSize)
   gc:drawString(bleState        or "none", leftMargin, lineSpace * 0)
   gc:drawString(peripheralName  or "none", leftMargin, lineSpace * 1)
   gc:drawString(peripheralState or "none", leftMargin, lineSpace * 2)
   if dieTemp then
      gc:drawString("dieTemp = "..string.format("%5.1f", dieTemp).." ℃", leftMargin, lineSpace * 3)
   else
      gc:drawString("dieTemp = none", leftMargin, lineSpace * 3 * H)
   end
   if irTemp then
      gc:drawString("irTemp = " ..string.format("%5.1f", irTemp).." ℃", leftMargin, lineSpace * 4)
   else
      gc:drawString("irTemp = none", leftMargin, lineSpace * 4 * H)
   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 "none"
   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 "none"
   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 _, v in ipairs(characteristicsList) do
      local UUID = v:getUUID() 

      -- Temperature
      if UUID == tempDataUUID then
         v:setValueUpdateListener(valueUpdateListener)
         v:setNotify(true)
      elseif UUID == tempConfUUID then
         -- v:setWriteCompleteListener(valueUpdateListener)
         v:write(string.uchar(0x01), true) -- Write 0x01 to enable data collection.
      end
      
   end
end

----------------------------------
-- Define value-update listener --
----------------------------------
function valueUpdateListener(characteristic)
   local UUID = characteristic:getUUID()
   
   -- Temperature
   if UUID == tempDataUUID then
      local value = characteristic:getValue()
      if value then
         local irRaw, dieRaw = string.unpack("s16s16", value) -- IR[0:7], IR[8:15], DIE[0:7], DIE[8:15]
         ---[[
         dieTemp = tonumber(dieRaw) / 128
         irTemp  = tonumber(irRaw)  / 128 --]]
         --[[
         dieTemp = math.evalStr("shift("..tonumber(dieRaw)..", -2)") * 0.03125
         irTemp  = math.evalStr("shift("..tonumber(irRaw).. ", -2)") * 0.03125 --]]
      end
   end
   
   platform.window:invalidate()
end