Here is an Universal Connector, which allows you to Write/Read from BT, LAN and Serial devices. The idea is to work with all devices with one and the same code and to do it very simple. The code is very simplified to be better described. Maybe in the future I will include all error handling routines and additional features like receiving packets, wrapping and others.
How do we use this module?
Here is the code:
And the project. It was tested with POS printers (Bluetooth, LAN and Serial). Uses felUSBSerial library.
B4X:
Sub Class_Globals
Public BaudRate As Long = 9600 'Sample baudrate, standart for serial POS printers
Public IPAddress As String = "192.168.0.1" 'Sample IP Address
Public IPPort As Long = 9100 'Sample port, standart for LAN POS printers
Public DeviceMAC As String = "00:00:00:00:00:00" 'Just put the real MAC of the POS printer
Public Const Conn_Bluetooth As Byte = 1 'This will be Bluetooth connection
Public Const Conn_LAN As Byte = 2 'This will be TCP connection
Public Const Conn_Serial As Byte = 3 'This will be USB-2-Serial connection
Public ConnectionType As Byte = 0 'The selected connection type
Public Connected As Boolean = False 'Are we connected?
Private BTAdmin As BluetoothAdmin
Private BTPort As Serial
Private MySocket As Socket
Private USBAdmin As UsbManager
Private USBSerial As felUsbSerial
Private PrinterTX As AsyncStreams
Private Const Connection_Attempts As Byte = 3 'How many attempts to reconnect should be done
Private Retries As Byte
End Sub
'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
USBAdmin.Initialize
End Sub
Public Sub Connect
If Connected Then Return 'Already connected, no need to connect
Retries = Connection_Attempts 'Make more than one attempt to connect
Select Case ConnectionType 'Select the proper connection type
Case Conn_Bluetooth 'Bluetooth connection
If Not(BTAdmin.IsInitialized) Then BTAdmin.Initialize("BluetoothAdmin") 'Init the Bluetooth hardware
If Not(BTPort.IsInitialized) Then BTPort.Initialize("RemoteDevice") 'Init the Bluetooth port. The event is Remote_Device
BTPort.Connect(DeviceMAC) 'Connect to existing device, MAC should be valid and paired
Case Conn_LAN 'LAN/WiFi connection over TCP
If Not(MySocket.IsInitialized) Then MySocket.Initialize("RemoteDevice") 'Initialize the connection socket. The events as Remote_Device
MySocket.Connect(IPAddress, IPPort, 1500) 'Address, Port and Timeout
Case Conn_Serial 'Serial device through felUSB library and USB-2-COM converter
If USBAdmin.GetDevices.Length > 0 Then 'There should be at least 1 device attached
Dim MyDevice As UsbDevice = USBAdmin.GetDevices(0) 'Assuming that there is exactly one device
If Not(USBAdmin.HasPermission(MyDevice)) Then 'Check for permission
ToastMessageShow("Allow permission to the Serial adapter", True) 'If no permission, ask for permission
USBAdmin.RequestPermission(MyDevice) 'Request permission
ConnectionError 'And execute error handling
Else
USBSerial.Initialize("USBSerial", MyDevice, -1) 'Initialize the serial device
USBSerial.BaudRate = BaudRate 'Set the requested baudrate
USBSerial.DataBits = USBSerial.DATA_BITS_8 '8 Data bits
USBSerial.Parity = USBSerial.PARITY_NONE 'Parity is None
USBSerial.StopBits = USBSerial.STOP_BITS_1 '1 Stop bit
Try 'Error handling for the serial device
USBSerial.StartReading 'Try the serial device
Catch
USBSerial.Close 'If not successful, close it
ConnectionError 'And execute error handling
Return 'Cannot countinue the tasks
End Try
Connected = True 'The connection was successful, set Connected flag
End If
Else
ToastMessageShow("No device",False) 'No serial device found
ConnectionError 'And execute error handling
End If
Case Else 'Connection type not properly set
ToastMessageShow("Invalid connection was selected!", True)
ConnectionError 'Execute error handling
End Select
End Sub
Public Sub Disconnect
Select Case ConnectionType 'Depends on connected type
Case Conn_Bluetooth: PrinterTX.SendAllAndClose: Sleep(100): MySocket.Close 'Send all data and close
Case Conn_LAN: PrinterTX.SendAllAndClose: Sleep(100): MySocket.Close 'Send all data and close
Case Conn_Serial: USBSerial.Close 'Data already sent, just close
End Select
Connected = False 'The connection was closed
End Sub
Private Sub RemoteDevice_Connected(Successful As Boolean)
If Successful Then 'Check if the connection is successful
'If successful, set up AsyncStreams
Select Case ConnectionType
Case Conn_Bluetooth 'AsyncStream on Bluetooth connection
Sleep(500) 'Sleep, because some of the Bluetooth devices do not respond immediately
PrinterTX.Initialize(BTPort.InputStream, BTPort.OutputStream, "DeviceTX") 'The event name is DeviceTX
Case Conn_LAN 'AsyncStream on TCP connection
Sleep(100) 'Sleep, because some of the LAN devices do not respond immediately
PrinterTX.Initialize(MySocket.InputStream, MySocket.OutputStream, "DeviceTX") 'The event name is DeviceTX
End Select
Retries = Connection_Attempts 'Connection was ready, so next time we will have new attempts to connect
Connected = True 'We are connected to the device
Else
If Retries > 0 Then 'Connection not successful, retrying
Log("Connection atempt N:" & (Connection_Attempts - Retries)) 'Log the result
Sleep(300) 'Wait until next connection
Retries = Retries - 1 'Decrease the number of retries
Connect 'Repeat the Connect subroutine
Else
Retries = Connection_Attempts 'The connection was unsuccessful, set the standart connection attempts
Log("No connection to the device") 'Log the result
ConnectionError 'Execute the error handling procedure
End If
End If
End Sub
Private Sub ConnectionError
ToastMessageShow("Error connecting the device", True) 'Here should be error handling procedure for connection errors
End Sub
Public Sub Write(WriteBuffer() As Byte) 'Send the data in the buffer
Select Case ConnectionType 'Depending on the selected ConnectionType
Case Conn_Bluetooth: PrinterTX.Write(WriteBuffer) 'Write to AsyncStream on Bluetooth connection
Case Conn_LAN: PrinterTX.Write(WriteBuffer) 'Write to AsyncStream on LAN connection
Case Conn_Serial: USBSerial.Write(WriteBuffer) 'Write to Stream on serial connection
End Select
End Sub
'Answer from the connected device from AsyncStream
Private Sub DeviceTX_NewData (Buffer() As Byte) 'The event name for LAN and Bluetooth is the same. Easy to work
If Buffer.Length = 0 Then Return 'Event was fired, but no information was available
DataReceived(Buffer)
End Sub
'Communication error
Private Sub DeviceTX_Error 'Error was detected on TX/RX
ToastMessageShow(LastException.Message, True)
End Sub
'Event from Serial Device, redirect it like AsyncStream for easier handling
Private Sub USBSerial_DataAvailable (Buffer() As Byte) 'Redirect the data to LAN/Bluetooth device
DeviceTX_NewData(Buffer) 'so it is very easy to work with universal conection
End Sub
Private Sub DataReceived(Buffer() As Byte) 'Data was received from the device
Dim Msg As String
Msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8") 'Change it to string
Log(Msg) 'And log it. You can pass it through CallSub
End Sub
How do we use this module?
Here is the code:
B4X:
Sub btnOK_Click
MyDevice.BaudRate = edtBaudrate.Text
MyDevice.IPAddress = edtIPAddress.Text
MyDevice.IPPort= edtIPPort.Text
MyDevice.DeviceMAC = edtMAC.Text
MyDevice.ConnectionType = MyDevice.Conn_Bluetooth
MyDevice.Connect
Do While Not(MyDevice.Connected)
Sleep(100)
Loop
Dim s As String = "Hello world!" & CRLF
MyDevice.Write(s.GetBytes("windows-1251"))
Sleep(100)
MyDevice.Disconnect
End Sub
And the project. It was tested with POS printers (Bluetooth, LAN and Serial). Uses felUSBSerial library.