Scott H Tech Blue Tooth Plugin - How do I know if a device is linked

Hi Scott (or anyone else that can answer this question),

I am playing around with your plugin and mostly have got the idea.  I am going to try and use it in my class (next year( so that student can control their arduino tanks via their devices. (  For this to work then the students need to be able to choose their arduino from what could be a rather large list of devices. The end goal will be two assessments - 1. write the remote in Corona, 2. Create tank and interface.

What I want is for the students to be presented with a list of devices and then be able to click on their tank which will take them to the next scene (which they will then write).

As it currently stands it displays a list of devices that are paired and unpaired. 

  • If I click on an unpaired device it connects no problem (can go to next scene). 
  • If I click on a paired device that is ‘not linked’, it connects no problem (can go to next scene).  
  • However, if I click on a device that is already ‘linked’ then I get this error “read failed, socket might closed or timeout, read ret: -1”.  I assume because it is trying to do something that has already been done (create a link).

Simple question,  how can I get a devices link state?  The getDevices command returns a connected value, but this does indicate whether a link is live (I think this paired devices?).  If I know the device is already linked then I wont try and make a connection, but just move forward with it onto the next scene.

Thanks,

Craig

The only real way to check is to send data to the device and send data back 

OK.   

Was thinking a different way, but this will work…

Thanks,

Craig

Hi Scott,

I have been playing around, and think I have encountered an error (but not sure).  Ive created a video of the issue to help explain it, but basically if I try and send a command when the app is not ‘linked’ or it has been restarted with a ‘link’ then there is an error.  In this case I am using Arduino, but I dont believe it is Arduino specific as it is happening on the app specificially. 

Here is a video explaining the issue: https://youtu.be/4j1FPjn_cu0

Here is my code:  (error log below)

local sceneGroup = self.view print("Version 1") local bluetoothList local myArduino = "98:D3:31:B3:D3:81" local bg = display.newRect( display.contentCenterX, display.contentCenterY, display.actualContentWidth, display.actualContentHeight ) bg:setFillColor( .6 ) local title = display.newText( "Choose Device To Continue With", display.contentCenterX, 40, native.systemFontBold, 16 ) title:setFillColor( 0,0,1 ) --bluetoothM.init(loadBluetoothTable) bt.init(function (event) if (event.type == "device found") then native.setActivityIndicator( false ) end if (event.type == "connected") then native.showAlert( "Connected to device", "Name:"..event.deviceName, {"Ok"} ) bt.search() native.setActivityIndicator( false ) end if (event.type == "disconnect") then native.showAlert( "Disconnected from device", "Name:"..event.deviceName, {"Ok"} ) bt.search() native.setActivityIndicator( false ) end if (event.type == "connection error") then native.showAlert( "Connection error", "Name:"..event.deviceName.."/Error: "..event.error, {"Ok"} ) bt.search() end if (event.type == "discovery finished") then native.setActivityIndicator( false ) end if (event.type == "error") then native.showAlert( "Disconnected from device", "Name:"..event.error, {"Ok"} ) end if (event.type == "message") then native.showAlert( "Message Received", "Name:"..event.error, {"Ok"} ) end end) local buttons = {"Connect", "Disconnect", "Send"} local function handleButtonEvent (event) local id = event.target.id if id == "Connect" then bt.connect(myArduino) elseif id == "Disconnect" then bt.disconnect(myArduino) elseif id == "Send" then bt.send("t", myArduino) end end for x = 1, #buttons do local button1 = widget.newButton( { label = buttons[x], onRelease = handleButtonEvent, emboss = false, id = buttons[x], -- Properties for a rounded rectangle button shape = "roundedRect", width = fullw \* .5, height = 50, cornerRadius = 2, labelColor = { default={1,1,1,1}, over={.7,.7,.7,1}}, fillColor = { default={0,0,.7,1}, over={0,0,.5,1}}, strokeColor = { default={0,0,1,1}, over={0.8,0.8,1,1} }, strokeWidth = 4 } ) -- Center the button button1.y = x \* 70 + 100 button1.x = centerX end 

Here is my error log:

ERROR: Runtime error /data/user/0/com.gmail.cbriggsnz.bluetooth\_demo\_master/files/coronaResources/scenes/practiceMain.lua:86: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference Java Stack Trace: me.aflak.bluetooth.Bluetooth.send(Bluetooth.java:92) plugin.bt.LuaLoader$send.invoke(LuaLoader.java:448) com.ansca.corona.JavaToNativeShim.nativeTouchEvent(Native Method) com.ansca.corona.JavaToNativeShim.touchEvent(JavaToNativeShim.java:417) com.ansca.corona.input.RaiseTouchEventTask.executeUsing(RaiseTouchEventTask.java:39) com.ansca.corona.CoronaRuntimeTaskDispatcher$TaskEvent.Send(CoronaRuntimeTaskDispatcher.java:170) com.ansca.corona.events.EventManager.sendEvents(EventManager.java:91) com.ansca.corona.Controller.updateRuntimeState(Controller.java:308) com.ansca.corona.graphics.opengl.CoronaGLSurfaceView$CoronaRenderer.onDrawFrame(CoronaGLSurfaceView.java:421) com.ansca.corona.graphics.opengl.GLSurfaceView$GLThread.guard ERROR: Runtime error /data/user/0/com.gmail.cbriggsnz.bluetooth\_demo\_master/files/coronaResources/scenes/practiceMain.lua:86: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference Java Stack Trace: me.aflak.bluetooth.Bluetooth.send(Bluetooth.java:92) plugin.bt.LuaLoader$send.invoke(LuaLoader.java:448) com.ansca.corona.JavaToNativeShim.nativeTouchEvent(Native Method) com.ansca.corona.JavaToNativeShim.touchEvent(JavaToNativeShim.java:417) com.ansca.corona.input.RaiseTouchEventTask.executeUsing(RaiseTouchEventTask.java:39) com.ansca.corona.CoronaRuntimeTaskDispatcher$TaskEvent.Send(CoronaRuntimeTaskDispatcher.java:170) com.ansca.corona.events.EventManager.sendEvents(EventManager.java:91) com.ansca.corona.Controller.updateRuntimeState(Controller.java:308) com.ansca.corona.graphics.opengl.CoronaGLSurfaceView$CoronaRenderer.onDrawFrame(CoronaGLSurfaceView.java:421) com.ansca.corona.graphics.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1623) com.ansca.corona.graphics.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1378) stack traceback: [C]: ? [C]: in function 'send' /data/user/0/com.gmail.cbriggsnz.bluetooth\_demo\_master/files/coronaResources/scenes/practiceMain.lua:86: in function '\_onRelease' /Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget\_button.lua:90: in function 'manageButtonTouch' /Users/jenkins/slaveroot/workspace/Templates/label/android/subrepos/widget/widgetLibrary/widget\_button.lua:430: in function 'method' /Users/jenkins/slaveroot/workspace/Templates/label/android/platform/resources/init.lua:221: in function \</Users/jenkins/slaveroot/workspace/Templates/label/android/platform/resources/init.lua:190\>

Cheers,

Craig

it looks like the app is being forced quit based on the splash screen being shown. You may want to try connecting to the device again.

Thanks Scott,

I think I did a bad job of describing the issue.  I believe the issue is when trying to send a command when the library is not aware there is a “link”.

In this video you can see that I get the error when sending a message when there are no links - I was going to implement your solution of " send[ing] data to the device and send[ing] data back" by polling all devices, but this is not possible because it crashes if the “link” is not “live”.

In this video I make a connection, exit the app using the android back button, reload the app, try and make a connection (which errors) and then send a message - still crashes - https://youtu.be/SQR7Eh5E0c0

The only way I can see a work around is to make sure the device is disconnected if the app exits.  I can see this causing possible issues.

Cheers

Craig

You could just disconnect the device on exit.  

local function onSystemEvent( event ) if (event.phase == "applicationExit") then -- disconnect here end end Runtime:addEventListener( "system", onSystemEvent )

Yip, that was where I was heading. 

Is there any way of just unlinking the device?  Your disconnect ‘un-pairs’ it so that it needs to be searched for again…  Not a huge problem, just not the best workflow.  

Cheers,

Craig