This script was written to demonstrate Bluetooth Low Energy connection from a WearOS watch with the AEON
electronic interface or with PC simulation software. It is intended to provide useful information for the development
of various online graphics applications for the AEON product. dashboard
B4X:
'' This script was written to demonstrate the Bluetooth Low Energy connection with the
'' AEON electronic interface or with PC simulation software. It is intended to provide
'' useful information for the development of various graphics applications in line with
'' the AEON product.
'' Written by André FAËS (Mr Blue Sky)
#Region Shared Files
#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True
#End Region
'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=BLEExample.zip
' Class declaration and initialization of global variables
' defines variables used across the class, including UI elements
' like buttons and gauges, and managers for BLE services and execution permissions.
Sub Class_Globals
Private Root As B4XView
Private xui As XUI
Private manager As BleManager2
Private rp As RuntimePermissions
Private pnlLayout As Panel
Private btnDisconnect As B4XView
Private btnScan As B4XView
Private lblDeviceStatus As B4XView
Private currentStateText As String = "UNKNOWN"
Private currentState As Int
Private connected As Boolean = False
Private ConnectedName As String = "AEON"
Private ConnectedServices As List
Private pbScan As B4XLoadingIndicator
Private xSpeedGauge As xGauges
Private fntTANK, fntOIL, fntTEMP As B4XView
End Sub
' Method provided for initializing additional components or databases if necessary, currently commented
Public Sub Initialize
' If dBSQL.IsInitialized = False Then
' InitdbSQL
' End If
End Sub
' Load the main layout, initialize the dialog, BLE manager, configure gauges,
' start listening for device orientation, and configure policies and colors.
' Each of these methods initializes a specific part of the application,
' such as panel settings, dialogs, handlers, gauges, etc.
Private Sub B4XPage_Created (Root1 As B4XView)
Root = Root1
Root.LoadLayout("main")
InitializePanelSettings
InitializeManager
ConfigureGauges
ConfigureFontsAndColors
End Sub
' Configures initial interface panel settings, such as button visibility.
Private Sub InitializePanelSettings
pnlLayout.SetLayout(0, 0, pnlLayout.Width, pnlLayout.Height)
pnlLayout.Visible=True
btnScan.Visible = True
btnDisconnect.Visible = False
End Sub
' Initializes the BLE manager and updates the initial connection state
Private Sub InitializeManager
manager.Initialize("manager")
StateChanged
End Sub
' Updates interface elements based on BLE connection status
Public Sub StateChanged
If connected Then
' lblDeviceStatus.Text = "Connected: " & ConnectedName
lblDeviceStatus.Text = ""
manager.ReadData2(UUID("FFE0"), UUID("FFE1"))
Sleep(1000)
btnScan.Visible = False
btnDisconnect.Visible = True
manager.SetNotify(UUID("FFE0"), UUID("FFE1"),True)
Else
lblDeviceStatus.Text = "Not connected"
btnScan.Visible = True
btnDisconnect.Visible = False
End If
btnDisconnect.Enabled = connected
btnScan.Enabled = Not(connected)
pbScan.Hide
btnScan.Enabled = (currentState = manager.STATE_POWERED_ON) And connected = False
End Sub
' Configures gauges with initial values and visualization settings.
Private Sub ConfigureGauges
xSpeedGauge.Value = 0
End Sub
Private Sub ConfigureFontsAndColors()
Dim fonts As List = Array(fntTANK, fntOIL, fntTEMP)
For Each fnt As B4XView In fonts
fnt.Font = xui.CreateFont(Typeface.CreateNew(Typeface.LoadFromAssets("fiveaces.ttf"), Typeface.STYLE_NORMAL), fnt.TextSize)
fnt.TextColor = xui.Color_Gray
fnt.Color = xui.Color_Transparent
Next
Dim labelTexts As Map = CreateMap(fntTANK: "E", fntOIL: "F", fntTEMP: "K")
For Each key As B4XView In labelTexts.Keys
key.Text = labelTexts.Get(key)
Next
End Sub
' Handles the click of the scan button, checking the necessary permissions before starting the scan.
Sub btnScan_Click
Dim Permissions As List
Dim phone As Phone
If phone.SdkVersion >= 31 Then
Permissions = Array("android.permission.BLUETOOTH", rp.PERMISSION_ACCESS_FINE_LOCATION)
Else
Permissions = Array(rp.PERMISSION_ACCESS_FINE_LOCATION)
End If
For Each per As String In Permissions
rp.CheckAndRequest(per)
Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
If Result = False Then
ToastMessageShow("No permission: " & Permission, True)
Return
End If
Next
pbScan.Show
StartScan
End Sub
Public Sub StartScan
If manager.State <> manager.STATE_POWERED_ON Then
Log("Bluetooth is not powered on.")
Return
End If
CheckBluetoothPermissions
manager.Scan2(Array(UUID("FFE0")), False)
End Sub
Private Sub CheckBluetoothPermissions()
Dim Permissions As List = Array("android.permission.BLUETOOTH", rp.PERMISSION_ACCESS_FINE_LOCATION)
For Each Permission As String In Permissions
rp.CheckAndRequest(Permission)
Wait For B4XPage_PermissionResult (Permission As String, Result As Boolean)
If Result = False Then
xui.MsgboxAsync("Permission denied: " & Permission, "Error")
Return
End If
Next
End Sub
' Manage events related to BLE device discovery.
Sub Manager_DeviceFound (Name As String, Id As String, AdvertisingData As Map, RSSI As Double)
Log("Found: " & Name & ", " & Id & ", RSSI = " & RSSI & ", " & AdvertisingData) 'ignore
' If Id = "68:E7:4A:EB:EA:BB" Then
If Name = "AEON" Then
ConnectedName = Name
manager.StopScan
Log("connecting")
manager.Connect2(Id, False) 'disabling auto connect can make the connection quicker
End If
End Sub
' Manage events related to Bluetooth state changes.
Sub Manager_StateChanged (State As Int)
Select State
Case manager.STATE_POWERED_OFF
currentStateText = "POWERED OFF"
Case manager.STATE_POWERED_ON
currentStateText = "POWERED ON"
Case manager.STATE_UNSUPPORTED
currentStateText = "UNSUPPORTED"
End Select
currentState = State
StateChanged
End Sub
' Handles the click of the BLE device disconnect button
Sub btnDisconnect_Click
manager.Disconnect
Manager_Disconnected
End Sub
Sub btnReadData_Click
For Each s As String In ConnectedServices
manager.ReadData(s)
Next
End Sub
' Processes data received via BLE, decrypting received messages and triggering appropriate processing.
Sub Manager_DataAvailable (ServiceId As String, Characteristics As Map)
Dim BC As ByteConverter
For Each id As String In Characteristics.Keys
Dim b() As Byte = Characteristics.Get(id)
Dim GetHexString As String = BC.HexFromBytes(b)
' Log original hex string
Log("Trame reçue: " & GetHexString)
' Split the received string into valid messages
Dim messages() As String = Regex.Split("0D0A", GetHexString)
For Each msg As String In messages
If msg.Length > 0 Then ' Check to ensure non-empty
Dim validMsg As String = msg & "0D0A" ' Append back the split pattern to each valid message
'Log("Trame individuelle: " & validMsg)
If validMsg.EndsWith("0D0A") Then
HandleCharacteristic(validMsg)
Else
' Log("Trame individuelle non valide ou incomplète")
End If
End If
Next
Next
End Sub
' These methods break down and process specific BLE messages received,
' adjusting gauge values and displaying device data like speed, battery status, etc.
Sub HandleCharacteristic(GetHexString As String)
' Vérifiez la longueur et l'intégrité de base de GetHexString
If GetHexString.EndsWith("0D0A") Then
' Découpe la trame en fonction des exigences spécifiques de chaque message
Select Case True
Case GetHexString.Length = 20 ' Pour la majorité des cas
ProcessMessage(GetHexString)
Case GetHexString.Length = 24 ' Cas spécifique, comme pour ODO
If GetHexString.SubString2(8, 12) = "0032" Then
' lblODO.Text = "ODO : " & Bit.ParseInt(GetHexString.SubString2(12, 20), 16)
End If
Case Else
Log("Unmanaged or incorrect frame length: " & GetHexString)
End Select
Else
Log("Corrupted or incomplete frame: " & GetHexString)
End If
End Sub
' These methods break down and process specific BLE messages received,
' adjusting gauge values and displaying device data like speed, battery status, etc.
Sub ProcessMessage(GetHexString As String)
Dim functionCode As String = GetHexString.SubString2(8, 12)
Dim value As String = GetHexString.SubString2(12, 16)
Select Case functionCode
Case "0010" 'SPEED
Dim speedValue As Int = Bit.ParseInt(value, 16)
xSpeedGauge.Value = speedValue
Case "0117" 'OIL
If Bit.ParseInt(value, 16) = 1 Then
fntOIL.TextColor=xui.Color_Red
Else
fntOIL.TextColor=xui.Color_Gray
End If
Case "0118" 'FUEL
If Bit.ParseInt(value, 16) = 1 Then
fntTANK.TextColor=xui.Color_ARGB(255,249,180,121)
Else
fntTANK.TextColor=xui.Color_Gray
End If
Case "0120" 'TEMP
If Bit.ParseInt(value, 16) = 1 Then
fntTEMP.TextColor=xui.Color_Red
Else
fntTEMP.TextColor=xui.Color_Gray
End If
Case "0122" 'METRIC
If Bit.ParseInt(value, 16) = 1 Then
xSpeedGauge.GaugeUnit="mph"
Else
xSpeedGauge.GaugeUnit="km/h"
End If
Case Else
' This case might never be reached due to the above modulo operation
End Select
End Sub
' Calls the 'StateChanged' method to update the UI to reflect the disconnected state.
Sub Manager_Disconnected
Log("Disconnected")
connected = False
StateChanged
End Sub
' Calls the 'StateChanged' method to update the UI to reflect the connected state.
Sub Manager_Connected (services As List)
Log("Connected")
connected = True
ConnectedServices = services
Log(services)
StateChanged
End Sub
'utility to convert short UUIDs to long format on Android
Private Sub UUID(id As String) As String 'ignore
Return "0000" & id.ToLowerCase & "-0000-1000-8000-00805f9b34fb"
End Sub
Last edited: