Platforms to show: All Mac Windows Linux Cross-Platform
/Bluetooth/Windows Bluetooth/Windows Bluetooth Socket
Required plugins for this example: MBS Bluetooth Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /Bluetooth/Windows Bluetooth/Windows Bluetooth Socket
This example is the version from Wed, 26th Jun 2018.
Project "Windows Bluetooth Socket.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
EventHandler Function UnhandledException(error As RuntimeException) As Boolean
MsgBox Introspection.GetType(error).fullname+EndOfLine+error.Message
Return true
End EventHandler
End Class
Class MainWindow Inherits Window
Control List Inherits Listbox
ControlInstance List Inherits Listbox
End Control
Control ListenButton Inherits PushButton
ControlInstance ListenButton Inherits PushButton
EventHandler Sub Action()
ListenSock = new MySocket
ListenSock.Bind -1, ""
if ListenSock.Lasterror <> 0 then
log "Bind error: "+str(ListenSock.Lasterror)+" "+ListenSock.LasterrorMessage
else
log "Bind okay"
me.Enabled = false
log "Bound to "+ListenSock.LocalAddress + " with port "+str(ListenSock.LocalPort)
ListenSock.Listen 3
if ListenSock.Lasterror <> 0 then
log "Listen error: "+str(ListenSock.Lasterror)+" "+ListenSock.LasterrorMessage
else
log "Listen okay"
end if
const SerialPortServiceClassID = "00001101-0000-1000-8000-00805F9B34FB"
ListenSock.RegisterService SerialPortServiceClassID, "myService", "just a test"
if ListenSock.Lasterror <> 0 then
log "Register error: "+str(ListenSock.Lasterror)+" "+ListenSock.LasterrorMessage
else
log "RegisterService okay"
end if
end if
End EventHandler
End Control
Control ConnectButton Inherits PushButton
ControlInstance ConnectButton Inherits PushButton
EventHandler Sub Action()
ConnectSock = new MySocket
ConnectSock.Connect AddressField.Text, PortField.Text.val
if ConnectSock.Lasterror <> 0 then
log "Connect error: "+str(ConnectSock.Lasterror)+" "+ConnectSock.LasterrorMessage
else
log "Connect okay"
me.Enabled = false
log "Local addresss: "+ConnectSock.LocalAddress + ":"+str(ConnectSock.LocalPort)
log "Remote address: "+ConnectSock.RemoteAddress + ":"+str(ConnectSock.RemotePort)
messageField.enabled = true
end if
End EventHandler
End Control
Control AddressField Inherits TextField
ControlInstance AddressField Inherits TextField
EventHandler Sub Open()
dim s as new WindowsBlueToothSocketMBS
me.Text = s.LocalAddress
End EventHandler
End Control
Control PortField Inherits TextField
ControlInstance PortField Inherits TextField
End Control
Control MessageField Inherits TextField
ControlInstance MessageField Inherits TextField
EventHandler Sub TextChange()
SendButton.Enabled = me.text.len > 0
End EventHandler
End Control
Control SendButton Inherits PushButton
ControlInstance SendButton Inherits PushButton
EventHandler Sub Action()
dim s as string = MessageField.Text.ConvertEncoding(encodings.UTF8)
dim n as integer = ConnectSock.Send(s)
log str(n)+" Bytes sent."
if ConnectSock.lastError <> 0 then
log "Send error: "+str(ConnectSock.Lasterror)+" "+ConnectSock.LasterrorMessage
end if
End EventHandler
End Control
Function MindstormEV3PlaySound() As Boolean
if ConnectSock <> nil then
EVPlaySound
else
MsgBox "Socket not open?"
end if
Return True
End Function
Function MindstormEV3QueryDeviceInputList() As Boolean
if ConnectSock <> nil then
EVQueryInputDeviceList
else
MsgBox "Socket not open?"
end if
Return True
End Function
Function MindstormEV3Querydirectorylisting() As Boolean
if ConnectSock <> nil then
EVListFiles
else
MsgBox "Socket not open?"
end if
Return True
End Function
Sub EVListFiles()
'Bytes send to the brick:
'xxxxxxxx0199xxxxxxx
'bbbbmmmmttssllllnnn...
'bbbb = bytes in message mmmm = message counter tt = type of message
'ss = system command
'llll = max. bytes to read nnn.. = path name
dim path as string = "/" // put linux path here
// bbbbmmmmttssllllnnn
dim m as MemoryBlock = new MemoryBlock(9 + lenb(path))
m.LittleEndian = true
m.UInt16Value(0) = m.size
m.UInt16Value(2) = 0
m.UInt8Value(4) = 1
m.UInt8Value(5) = &h99
m.UInt16Value(6) = 1012
m.StringValue(8,lenb(path)) = path
ConnectSock.EVListFiles = true
dim n as integer = ConnectSock.Send(m)
log EncodeHex(m)
log str(n)+" Bytes sent."
End Sub
Sub EVPlaySound()
'Play a 1Kz tone at level 2 for 1 sec.
'opSOUND,LC0(TONE),LC1(2),LC2(1000),LC2(1000)
'opSOUND LC0(TONE) LC1(2) LC2(1000) LC2(1000)
'Bytes sent to the brick:
'Opcode sound related
'Command (TONE) encoded as single byte constant Sound-level 2 encoded as one constant
'byte to follow Frequency 1000 Hz. encoded as two constant bytes to follow Duration 1000 mS.
'encoded as two constant bytes to follow
'0F00xxxx8000009401810282E80382E803
'Bbbbmmmmtthhhhcccccccccccccccccccc
'bbbb = bytes in message 15 excl. packet length bytes
'mmmm = message counter
'tt = type of command - Direct command no reply
'hhhh = header – variable alloc*).
'cc/CC = byte codes.
'*)hhhh = 10 least significant bits are number of globals, 6 most significal bits are locals
dim s as string
s = "0F0000000000009401810282E80382E803"
// Bbbbmmmmtthhhhcccccccccccccccccccc
dim m as MemoryBlock = DecodeHex(s)
dim n as integer = ConnectSock.Send(m)
log EncodeHex(m)
log str(n)+" Bytes sent."
End Sub
Sub EVQueryInputDeviceList()
'opINPUT_DEVICE_LIST Example
'
'Get all device types connected to input ports:
'
'Byte codes: opINPUT_DEVICE_LIST,LC0(4),GV0(0),GV0(4),
'\ /
'\ -------
'\ /
'Hex values send: 0900xxxx00050098046064
'
'
'Hex value received: 0800xxxx027E7E7E7D00
'^---------
'|
'Command global variable (response buffer offset)
'0=port 1 type, 1=port 2 type, 2=port 3 type, 3=port4 type, 4=change flag.
dim s as string
s = "0900000000050098046064"
// bbbbmmmmtthhhhcccccccc
dim m as MemoryBlock = DecodeHex(s)
dim n as integer = ConnectSock.Send(m)
log EncodeHex(m)
log str(n)+" Bytes sent."
ConnectSock.EVQueryInputDeviceList = true
// seems like answer doesn't come until next packet goes to device?
End Sub
Sub Log(s as string)
List.AddRow s
End Sub
Property ConnectSock As MySocket
Property Connections() As MySocket
Property ListenSock As MySocket
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
MenuItem MindstormEV3Menu = "Mindstorm EV3"
MenuItem MindstormEV3PlaySound = "Play Sound"
MenuItem MindstormEV3QueryDeviceInputList = "Query Device Input List"
MenuItem MindstormEV3Querydirectorylisting = "Query directory listing"
End MenuBar
Class MySocket Inherits WindowsBlueToothSocketMBS
EventHandler Sub DataAvailable()
dim s as string = me.ReadAll
dim e as string = EncodeHex(s)
dim data as MemoryBlock = s
MainWindow.log "Data received: "+e
if EVQueryInputDeviceList and mid(e, 9, 4) = "0221" then
// e.g. 0800000002217E101D06
dim Port0 as integer = data.UInt8Value(5) // e.g. 21 = EV3 IR sensor
dim Port1 as integer = data.UInt8Value(6) // e.g. 7E = Port empty or not available
dim Port2 as integer = data.UInt8Value(7) // e.g. 10 = EV3 touch sensor
dim Port3 as integer = data.UInt8Value(8) // e.g. 1D = EV3 color sensor
MainWindow.log "Port0: "+str(Port0)+" "+GetEVSensorType(port0)
MainWindow.log "Port1: "+str(Port1)+" "+GetEVSensorType(port1)
MainWindow.log "Port2: "+str(Port2)+" "+GetEVSensorType(port2)
MainWindow.log "Port3: "+str(Port3)+" "+GetEVSensorType(port3)
EVQueryInputDeviceList = false
end if
if EVListFiles and mid(e, 9, 4) = "0399" then
// got file listing
s = data.StringValue(12, data.size-12)
s = DefineEncoding(s, encodings.UTF8)
s = ReplaceLineEndings(s, EndOfLine)
dim lines() as string = split(s, EndOfLine)
for each line as string in lines
MainWindow.log "> "+line
next
EVListFiles = false
end if
End EventHandler
EventHandler Sub Error()
log "Error: "+str(me.Lasterror)
End EventHandler
EventHandler Sub NewConnection()
log "New connection"
dim NewSocket as new MySocket
dim RemoteAddress as string
dim RemotePort as integer
dim s as WindowsBlueToothSocketMBS = me.Accept(RemoteAddress, RemotePort, NewSocket)
if s = nil then
log "Accept error: " + str(me.Lasterror) + " " + me.LasterrorMessage
else
MainWindow.Connections.Append NewSocket
end if
End EventHandler
EventHandler Sub SendComplete()
log "Send complete"
End EventHandler
Function GetEVSensorType(n as integer) As string
// Types defined in "typedata.rcf"
const TYPE_NXT_TOUCH = 1 //!< Device is NXT touch sensor
const TYPE_NXT_LIGHT = 2 //!< Device is NXT light sensor
const TYPE_NXT_SOUND = 3 //!< Device is NXT sound sensor
const TYPE_NXT_COLOR = 4 //!< Device is NXT color sensor
const TYPE_NXT_ULTRASONIC = 5 //!< Device is NXT ultra sonic sensor
const TYPE_NXT_TEMPERATURE = 6 //!< Device is NXT temperature sensor
const TYPE_TACHO = 7 //!< Device is EV3/NXT tacho motor
const TYPE_MINITACHO = 8 //!< Device is EV3 mini tacho motor
const TYPE_NEWTACHO = 9 //!< Device is EV3 new tacho motor
const TYPE_TOUCH = 16 //!< Device is EV3 touch sensor
// Types defined in known EV3 digital devices
const TYPE_COLOR = 29 //!< Device is EV3 color sensor
const TYPE_ULTRASONIC = 30 //!< Device is EV3 ultra sonic sensor
const TYPE_GYRO = 32 //!< Device is EV3 gyro sensor
const TYPE_IR = 33 //!< Device is EV3 IR sensor
// Type range reserved for third party devices
const TYPE_THIRD_PARTY_START = 50
const TYPE_THIRD_PARTY_END = 98
// Special types
const TYPE_ENERGYMETER = 99 //!< Device is energy meter
const TYPE_IIC_UNKNOWN = 100 //!< Device type is not known yet
const TYPE_NXT_TEST = 101 //!< Device is a NXT ADC test sensor
const TYPE_NXT_IIC = 123 //!< Device is NXT IIC sensor
const TYPE_TERMINAL = 124 //!< Port is connected to a terminal
const TYPE_UNKNOWN = 125 //!< Port not empty but type has not been determined
const TYPE_NONE = 126 //!< Port empty or not available
const TYPE_ERROR = 127 //!< Port not empty and type is invalid
if n >= TYPE_THIRD_PARTY_START and n <= TYPE_THIRD_PARTY_END then
return "Third Party Sensor"
end if
Select case n
// Types defined in "typedata.rcf"
case TYPE_NXT_TOUCH
return "Device is NXT touch sensor"
case TYPE_NXT_LIGHT
return "Device is NXT light sensor"
case TYPE_NXT_SOUND
return "Device is NXT sound sensor"
case TYPE_NXT_COLOR
return "Device is NXT color sensor"
case TYPE_NXT_ULTRASONIC
return "Device is NXT ultra sonic sensor"
case TYPE_NXT_TEMPERATURE
return "Device is NXT temperature sensor"
case TYPE_TACHO
return "Device is EV3/NXT tacho motor"
case TYPE_MINITACHO
return "Device is EV3 mini tacho motor"
case TYPE_NEWTACHO
return "Device is EV3 new tacho motor"
case TYPE_TOUCH
return "Device is EV3 touch sensor"
// Types defined in known EV3 digital devices
case TYPE_COLOR
return "Device is EV3 color sensor"
case TYPE_ULTRASONIC
return "Device is EV3 ultra sonic sensor"
case TYPE_GYRO
return "Device is EV3 gyro sensor"
case TYPE_IR
return "Device is EV3 IR sensor"
// Special types
case TYPE_ENERGYMETER
return "Device is energy meter"
case TYPE_IIC_UNKNOWN
return "Device type is not known yet"
case TYPE_NXT_TEST
return "Device is a NXT ADC test sensor"
case TYPE_NXT_IIC
return "Device is NXT IIC sensor"
case TYPE_TERMINAL
return "Port is connected to a terminal"
case TYPE_UNKNOWN
return "Port not empty but type has not been determined"
case TYPE_NONE
return "Port empty or not available"
case TYPE_ERROR
return "Port not empty and type is invalid"
end Select
End Function
Sub Log(s as string)
Mainwindow.List.AddRow s
End Sub
Property EVListFiles As Boolean
Property EVQueryInputDeviceList As Boolean
End Class
End Project
See also:
The items on this page are in the following plugins: MBS Bluetooth Plugin.