Home ← TI-Nspire Authoring ← TI-Nspire Scripting HQ ← Scripting Tutorial - Lesson 29
Scripting Tutorial - Lesson 29: Lua Objects Gallery
Download supporting files for this tutorial
Download this page in PDF format
Texas Instruments TI-Nspire Scripting Support Page
This tutorial is all about NOT re-inventing the wheel!
Lua is a powerful and flexible scripting tool. With a little imagination and a lot of effort, it can be persuaded to do almost anything, within reason. However, the amount of effort required to do even the most common things is sometimes more than many teachers can afford. Having to define all your own page elements - even frequently-used objects like buttons, sliders, grids, etc - is a deterent to those who want to get their teaching ideas in the hands of their students as quickly and efficiently as possible.
The Lua Objects Gallery is a collection of these common objects, defined in a way that those with moderate experience of Lua scripting may copy and paste the code into their own scripts, and then adapt as needed.
The first page of the Lua Objects Gallery TNS file (shown in the video displayed here) is a collection of many of the most useful of the gallery objects, showing how these may be inserted and made to work together to achieve quite effective results.
-- BLE General Functions -----------
Now it is time for you to play!
The images for the various objects above each link to a page where the script has been defined within your web browser. Click on the "run your code" button towards the top of the page, and the script in the text box at the end will be run. This means you are free to browse the script, try some changes and run these immediately. If you are using a tablet, you might find the scripts take a few seconds to load, but they will, so you can play and edit on iPad or any device that supports javascript.
Of course, a web browser (while convenient as a first stop) is not an ideal authoring environment, so download the Lua Objects Gallery tns file and use the TI-Nspire Script editor or your own preferred editor to explore.
In addition to the main document (Lua_Objects_Gallery.tns) the zipped file contains a couple of other documents, for those who might like to explore further:
Lua/JavaScript: Lua_Objects_Gallery_web.tns contains the simpler scripts that will run within the browser (featured above). The Lua/JavaScript translation does not at this stage work with string manipulation, and anything above APIlevel 1.0, so some nice features are not possible in this space. But you may be surprised by what IS possible!
For more on these possibilities, visit the Lua and JavaScript page.
Remote Libraries: Since we are using and reusing the same code snippets for multiple documents, I wondered if it might be possible to "share" the code, and access it remotely. Using the MyLib folder and some neat public variables definition, it turns out that it is! Take the file 'LuaLib.tns' and drop it into your MyLib folder on computer (in the Documents > TI-Nspire folder), on handheld, or on the iPad (go to settings and Show MyLib). Now open the file Lua_Objects_Gallery_remote.tns - you may need to refresh libraries, but you should be then able to run your Gallery objects just as if they were fully defined locally. Check the scripts and compare these to the local definitions: often reduced from 800-1000 lines down to a couple of hundred! Interesting, but may have no practical use at all. Feel free to explore...
I have attempted to annotate the scripts thoroughly (without being excessive). This hopefully will help you in learning how to use these objects for yourself. If you run into problems, or just wish to chat about using the Gallery, feel free to drop me an email - steve@compasstech.com.au. I would love to hear from you!
Something New: Control your iPad Scripts Remotely using a TI SensorTag and BLE
How would you like to control your scripts remotely, with just clicks of a button? The good news is that this is surprisingly easy to do, involving adding just a few additional lines to your existing scripts.
The TI SensorTag 2.0 offers amazing opportunities for mathematics and science STEM classroom applications. For less than $USD30 this device literally puts real world data collection in the palm of your hand, as well as BLE control functionality in a range of applications.
The TI SensorTags come with what are termed "Simple Keys" - we will refer to these as "left" and "right" keys. The SensorTag 2.0 (or CC2650 SensorTag) has only two buttons, found on the sides. Facing the two strip windows, the left side button also serves to turn the device on and off, but this actually requires a 3-second keypress. The right side button will switch to iBeacon mode after 6 seconds, and reset the device after 10.
These devices use the same broadcast signal (UUID) and transmit the same information when the left and right buttons are pressed. It is a simple thing to take this information and define actions for these events, turning your Tag into a remote control for your script. This has been done with most of the Lua Objects Gallery scripts.
The best documents for this treatment are probably those that work best on the handheld, surprisingly. This method easily converts enter key, escape key, tab key, even arrow keys, into button clicks.
When not in a BLE-enabled platform (at present just the iPad), there is no evidence that this code exists. But it comes to life in the iPad apps, with Bluetooth turned on. Tapping at the top of the page begins scanning, and connection when an active SensorTag or other supported BLE device (such as the CC2650 LaunchPad, or a LaunchPad with BLE support) is found. A few seconds later, and the buttons are ready to work.
So how do I do this?
Change your APIlevel to 2.5: platform.apilevel = '2.5'
Copy and paste some initial variables at the start of your script:
pcall(function () require 'bleCentral' end) local bleState = '' local bleStatus = 'Tap here to scan for BLE' local peripheralName = '' local keysRead = 'FFE1' local BLEready = 0 local keyPress = nil
Copy this snippet into your on.resize() function (or on.construction):
if not bleStatus:find("Connect") then
pcall(function() ble.addStateListener(listenerCallback) end)
end
(Optional) You may copy this snippet into your on.paint() function. It will be visible in BLE-active platforms (iPad) but not elsewhere.
fontSize = math.floor(w/42 + 0.5) if platform.isDeviceModeRendering() then
fontSize = fontSize > 6 and fontSize or 7 fontSize = fontSize < 24 and fontSize or 24end local radius = 0.05*hif bleState:find("ON") then
gc:setColorRGB(color.gray) gc:setFont("sansserif", "b", fontSize) local str = bleState..": "..bleStatusendif bleStatus:find("Connect") then
if BLEready ~= 0 thenendgc:setColorRGB(color.green) str = peripheralName .." connected"elsegc:setColorRGB(color.blue) str = "Connecting: Try your "..peripheralNameendgc:fillArc(0.015*w, 0.025*h, radius, radius, 0, 360) gc:drawString(str, radius + 0.0275*w, 0.025*h + radius/2, "middle") gc:setColorRGB(color.black) gc:drawArc(0.015*w, 0.025*h, radius, radius, 0, 360)
If you already have a mouseUp function, insert the if-then block, else copy and paste directly:
function on.mouseUp(x, y)
if x < 0.5*w and y < 0.1*h then
if bleStatus:find("Tap") thenendperipheralOn()elseperipheralOff()endscreen:invalidate()
end
Copy the following block of code at the end of your script:
bleCentral.startScanning(callbackScan) bleStatus = 'Scanning' screen:invalidate()function listenerCallback(state, scriptError)
if state == ble.ON then bleState = 'BLE ON' elseif state == ble.OFF then bleState = 'BLE OFF' peripheralOff() 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()
end
function peripheralOff()
bleCentral.stopScanning()
if myPeripheral then myPeripheral:disconnect() endbleStatus = 'Tap here to scan for BLE' peripheralName = '' BLEready = 0 screen:invalidate()
end
function callbackScan(peripheral)
if peripheral ~= nil then peripheralName = peripheral:getName() or 'Unknown Device'
if peripheralName thenif peripheralName:find('Tag') or peripheralName:find('LaunchPad') or peripheralName:find('HMSoft') or peripheralName:find('BT05') or peripheralName:find('CC41') thenperipheral:connect(callbackConnect)
end
end
end
screen:invalidate()end
function callbackConnect(peripheral, event)
if event == bleCentral.CONNECTED then
bleCentral.stopScanning() bleStatus = 'Connected' myPeripheral = peripheral peripheralName = peripheralName:gsub('(unsupported)', '') 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 then BLEready = 1 if peripheralName:find('Tag') or peripheralName:find('LaunchPad') then
keyPress = ble.unpack("u8",value)elsekeyPress = value:gsub("P", "") keyPress = keyPress:gsub(" ","") keyPress = tonumber(keyPress)endif keyPress and keyPress == 2 then on.enterKey() end if keyPress and keyPress == 1 then on.escapeKey() end
end
end
screen:invalidate()
end
You may choose to add more explanatory text to your screen, and to add to your menu, but these steps are optional. This code should make your script BLE ready. The magic happens in the last two lines (in red). Set whatever action you choose to the left and right button presses of the SensorTag, and you are away! You can even use long and short presses for different actions - check this in Lua Objects like the slider.
Home ← TI-Nspire Authoring ← TI-Nspire Scripting HQ ← Scripting Tutorial - Lesson 29