The following script, from http://compasstech.com.au/TNS_Authoring/Scripting/script_tut31.html, will try to read the state of SensorTag's buttons. Do not press and hold any button for too long, or powering off or mode changing will occur.
-- The following script is from http://compasstech.com.au/TNS_Authoring/Scripting/script_tut31.html. platform.apilevel = '2.5' screen = platform.window w = screen:width() h = screen:height() pcall(function () require 'bleCentral' end) require "color" local bleState = '' local bleStatus = 'Stand by' local peripheralName = '' local myPeripheral = nil -- SensorTag keyPress Variables local keysRead = 'FFE1' local keyPress = nil local nameList = {'SensorTag', 'LaunchPad', 'HMSoft', 'BT05', 'CC41'} -- Layout Functions (resize and paint) function on.resize() w = screen:width() or 841 h = screen:height() or 567 pcall(function() ble.addStateListener(listenerCallback) end) refreshMenu() screen:invalidate() end function on.paint(gc) w = screen:width() or 841 h = screen:height() or 567 local fontSize = math.floor(h/28 + 0.5) fontSize = fontSize < 25 and fontSize or 24 fontSize = fontSize > 6 and fontSize or 7 if bleState:find("ON") then gc:setColorRGB(color.blue) else gc:setColorRGB(color.red) end gc:setFont("sansserif", "b", fontSize) gc:drawString(bleState, 0.1*w, 0.1*h) if peripheralName then gc:drawString(peripheralName.." "..bleStatus, 0.1*w, 0.2*h) for n = 1, #nameList do local sw = gc:getStringWidth(nameList[n]) if peripheralName:find(nameList[n]) then gc:setColorRGB(color.green) else gc:setColorRGB(color.gray) end gc:drawString(nameList[n], 0.95*w - sw, 0.95*h - 0.01125*h*(n-1)*9-0.1*h, 'middle') end end gc:setColorRGB(color.green) gc:fillRect(0.9*w, 0.9*h, 0.1*w, 0.1*h) gc:setColorRGB(color.black) gc:drawRect(0.9*w, 0.9*h, 0.1*w, 0.1*h) local sw = gc:getStringWidth('Scan') gc:drawString('Scan', 0.95*w - sw/2, 0.95*h, 'middle') gc:setColorRGB(color.red) gc:fillRect(0, 0.9*h, 0.1*w, 0.1*h) gc:setColorRGB(color.black) gc:drawRect(0, 0.9*h, 0.1*w, 0.1*h) local sw = gc:getStringWidth('Stop') gc:drawString('Stop', 0.05*w - sw/2, 0.95*h, 'middle') local fontSize = math.floor(h/20 + 0.5) fontSize = fontSize < 25 and fontSize or 24 fontSize = fontSize > 6 and fontSize or 7 gc:setFont("sansserif", "b", 60) -- gc:setFont("sansserif", "b", fontSize) if bleStatus:find('Connect') then if keyPress and keyPress ~= 0 then local str = 'Keypress '..keyPress local sw = gc:getStringWidth(str) gc:drawString(str, 0.5*w - sw/2, 0.5*h, "middle") else local str = 'Press the left or right key...' local sw = gc:getStringWidth(str) gc:drawString(str, 0.5*w - sw/2, 0.5*h, "middle") end end end --Menu, Keyboard and Mouse Functions-------------- function refreshMenu() Menu = { {"Controls", {"Scan and Connect", function() peripheralOn() end}, {"Disconnect", function() peripheralOff() end}, {"Reset", function() bleState = '' bleStatus = 'Stand by' on.resize() end}, }, } toolpalette.register(Menu) end function on.enterKey() peripheralOn() end function on.escapeKey() resetall() end function resetall() bleState = '' keyPress = nil peripheralOff() on.resize() end function on.mouseUp(x, y) w = screen:width() or 841 h = screen:height() or 567 if x > 0.9*w and y > 0.9*h then on.enterKey() end if x < 0.1*w and y > 0.9*h then on.escapeKey() end screen:invalidate() end -- BLE General Functions ----------- function listenerCallback(state, scriptError) if state == ble.ON then bleState = 'BLE ON' elseif state == ble.OFF then bleState = 'BLE OFF' elseif state == ble.RESETTING then bleState = 'BLE RESET' elseif state == ble.UNSUPPORTED then bleState = 'UNSUPPORTED' if scriptError then print('Error message: BLE not supported') end end screen:invalidate() end function peripheralOn() bleCentral.startScanning(callbackScan) bleStatus = 'Scanning' screen:invalidate() end function peripheralOff() bleCentral.stopScanning() if myPeripheral then myPeripheral:disconnect() end bleStatus = 'Stand by' peripheralName = '' screen:invalidate() end function callbackScan(peripheral) if peripheral ~= nil then peripheralName = peripheral:getName() for n =1, #nameList do if peripheral:getName() and (peripheral:getName()):find(nameList[n]) then peripheral:connect(callbackConnect) break end end end screen:invalidate() end function callbackConnect(peripheral, event) if event == bleCentral.CONNECTED then bleCentral.stopScanning() bleStatus = 'Connected' myPeripheral = peripheral peripheralName = peripheral:getName() peripheral:discoverServices(callbackServices) elseif event == bleCentral.DISCONNECTED then bleStatus = 'Disconnected' peripheralName = '' end screen:invalidate() end function callbackServices(peripheral) if peripheral ~= nil and peripheral:getState() and peripheral:getState() == bleCentral.CONNECTED then local services = peripheral:getServices() for _,service in ipairs(services) do service:discoverCharacteristics(callbackCharacteristics) end end screen:invalidate() end -- BLE Specific Functions --------- function callbackCharacteristics(service) local characteristicsList = service:getCharacteristics() for _,characteristic in ipairs(characteristicsList) do if characteristic:getUUID() == keysRead then characteristic:setValueUpdateListener(callbackCharacteristic) characteristic:setNotify(true) end end end function callbackCharacteristic(characteristic) if characteristic:getUUID() == keysRead then --Simple Keys local value = characteristic:getValue() if value and peripheralName then if peripheralName:find("Tag") or peripheralName:find("LaunchPad") then keyPress = ble.unpack('u8', value) else keyPress = value:gsub("P", "") keyPress = keyPress:gsub(" ","") keyPress = tonumber(keyPress) end end end screen:invalidate() end