TXT 4.0 Controller(s) mit dem Bluetooth-Set (569021)

Alles rund um TX(T) und RoboPro, mit ft-Hard- und Software
Computing using original ft hard- and software
Forumsregeln
Bitte beachte die Forumsregeln!
Antworten
rbudding
Beiträge: 41
Registriert: 01 Nov 2010, 18:36
Wohnort: UTRECHT

TXT 4.0 Controller(s) mit dem Bluetooth-Set (569021)

Beitrag von rbudding » 24 Jun 2025, 11:10

Hi!
Ich möchte meinen TXT 4.0 Controller(s) gerne mit dem Bluetooth-Set (569021) oder dem Set (563931) verbinden.
(TXT 4.0 => server, bluetooth module is client)

Ein weiterer Wunsch ist, meinen TXT 4.0 drahtlos zu betreiben, also zwei TXT 4.0 Controller per Bluetooth (Wifi?) miteinander zu koppeln.

Ich habe bereits recherchiert, aber leider kein Beispiel in Pro Coding oder in Python gefunden, mit dem das gelingt.

Hat das vielleicht schon jemand erfolgreich umgesetzt?

mit freundlichen grüß Richard

Code: Alles auswählen

# TXT 4.0 WiFi Communication Example - Pro Coding
# Knop op server zet motor op client aan/uit via TCP/IP

# === server.py ===
# Draait op de eerste TXT 4.0 (server)
# Leest knopinput (bijv. drukknop) en stuurt aan/uit-commando naar client

import socket
import ftrobopy
import time

# Initialiseer verbinding met TXT hardware
txt = ftrobopy.ftrobopy()
txt.updateWait()

def run_server():
    host = '0.0.0.0'
    port = 9999

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((host, port))
    server_socket.listen(1)
    print("[Server] Wacht op verbinding...")

    conn, addr = server_socket.accept()
    print(f"[Server] Verbonden met: {addr}")

    button = txt.input(1)  # Verbind hier een drukknop aan ingang 1

    try:
        while True:
            txt.updateWait()
            pressed = button.bool()
            if pressed:
                print("[Server] Knop ingedrukt - motor AAN")
                conn.send(b"ON")
            else:
                print("[Server] Knop niet ingedrukt - motor UIT")
                conn.send(b"OFF")
            time.sleep(0.5)
    finally:
        conn.close()
        server_socket.close()

if __name__ == "__main__":
    run_server()


# === client.py ===
# Draait op de tweede TXT 4.0 (client)
# Ontvangt aan/uit-signaal en stuurt motor aan

import socket
import time
import ftrobopy

# Initialiseer verbinding met TXT hardware
txt = ftrobopy.ftrobopy()
txt.updateWait()

def run_client():
    host = '192.168.0.101'  # IP van server-TXT
    port = 9999

    motor = txt.motor(1)

    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect((host, port))
    print("[Client] Verbonden met server")

    try:
        while True:
            data = client_socket.recv(1024)
            if not data:
                break
            command = data.decode().strip()
            print(f"[Client] Commando ontvangen: {command}")

            if command == "ON":
                motor.setSpeed(512)
            elif command == "OFF":
                motor.stop()
    finally:
        client_socket.close()

if __name__ == "__main__":
    run_client()

rbudding
Beiträge: 41
Registriert: 01 Nov 2010, 18:36
Wohnort: UTRECHT

Re: TXT 4.0 Controller(s) mit dem Bluetooth-Set (569021)

Beitrag von rbudding » 24 Jun 2025, 20:29

Nach einem Tag Reverse Engineering, Programmieren in Xcode und ein wenig Hilfe von meinen KI-Freunden veröffentliche ich nun eine Python-Klasse zur Kommunikation mit dem „BT Smart Controller“. Jetzt fehlt nur noch ein Weg, das Ganze auf dem TXT 4.0 zum Laufen zu bringen.

(I can share the Xcode project if wanted)

Code: Alles auswählen

# ble_manager_txt4.py

from ftrobopy import ftrobopy
import time

class BLEManagerTXT4:
    def __init__(self):
        self.batteryLevel = 0
        self.inputValues = [0, 0, 0, 0]
        self.receivedMessage = ""
        self.status = None
        self.manufacturerName = None
        self.modelNumber = None
        self.hardwareRevision = None
        self.firmwareRevision = None
        self.systemID = None

        self.txt = ftrobopy.ftrobopy("localhost", 65000)
        self.outputs = [1, 2, 3, 4]
        self.inputs = [1, 2, 3, 4]

        self.txt.updateWait()
        self.receivedMessage += "[TXT] ✅ Verbonden met TXT 4.0\n"

    def readBatteryLevel(self):
        voltage = self.txt.getBattery()
        self.batteryLevel = int(voltage / 9.0 * 100)  # normalize to 100%
        self.receivedMessage += f"[TXT] 🔋 Batterij = {self.batteryLevel}%\n"

    def readInputs(self):
        self.txt.updateWait()
        for i in range(4):
            val = self.txt.analog[self.inputs[i] - 1]
            self.inputValues[i] = int(val * 1023)
        self.receivedMessage += f"[TXT] 📥 Inputs: {self.inputValues}\n"

    def setOutput(self, index, value):
        if 1 <= index <= 4:
            # Clamp to 0–512 (half PWM scale of 1023)
            pwm_val = min(max(value, 0), 512)
            self.txt.setPWM(self.outputs[index - 1], pwm_val)
            self.receivedMessage += f"[TXT] 📤 Set O{index} = {pwm_val}\n"

    def setAllOutputs(self, value):
        for i in range(1, 5):
            self.setOutput(i, value)

    def loop(self):
        while True:
            self.readBatteryLevel()
            self.readInputs()
            print(self.receivedMessage)
            self.receivedMessage = ""
            time.sleep(1)


if __name__ == '__main__':
    manager = BLEManagerTXT4()
    manager.loop()

rbudding
Beiträge: 41
Registriert: 01 Nov 2010, 18:36
Wohnort: UTRECHT

Re: TXT 4.0 Controller(s) mit dem Bluetooth-Set (569021)

Beitrag von rbudding » 24 Jun 2025, 20:32

Some output from my Xcode / Swift implementation of the BT Smart controller on OSx

[BLE] ❌ Bluetooth niet actief
[BLE] ✅ Bluetooth is actief
[BLE] 🔍 Start scanning without filter
[BLE] 📡 Gevonden: BT Smart Controller @ RSSI: -47
[BLE] 🔗 Verbonden met 5A6B76F9-A2C8-F05C-0FE2-23F3DEB9B80D
[BLE] Service gevonden: 180A
[BLE] Service gevonden: 180F
[BLE] Service gevonden: 8AE87702-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Service gevonden: 8AE8806C-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Service gevonden: 8AE883B4-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Service gevonden: 8AE88D6E-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Service gevonden: 8AE8952A-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 2A29
[BLE] Characteristic gevonden: 2A24
[BLE] Characteristic gevonden: 2A27
[BLE] Characteristic gevonden: 2A26
[BLE] Characteristic gevonden: 2A23
[BLE] Characteristic gevonden: 2A19
[BLE] Characteristic gevonden: 8AE87E32-AD7D-11E6-80F5-76304DEC7EB7
[BLE] 📬 Notificaties geactiveerd
[BLE] Characteristic gevonden: 8AE88224-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 8AE8860C-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 8AE88B84-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 8AE88EFE-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 8AE89084-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 8AE89200-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 8AE89386-AD7D-11E6-80F5-76304DEC7EB7
[BLE] 🎯 Alle output characteristics klaar
[BLE] Characteristic gevonden: 8AE89A2A-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 8AE89BEC-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 8AE89DC2-AD7D-11E6-80F5-76304DEC7EB7
[BLE] Characteristic gevonden: 8AE89F66-AD7D-11E6-80F5-76304DEC7EB7
[BLE] 🎯 Alle output characteristics klaar
[BLE] 🔋 Batterij: 77%
[BLE] ✅ Bluetooth is actief
[BLE] 🔍 Start scanning without filter
[BLE] ✅ Bluetooth is actief
[BLE] 🔍 Start scanning without filter
[BLE] 📡 Gevonden: BT Smart Controller @ RSSI: -43
[BLE] 📡 Gevonden: BT Smart Controller @ RSSI: -43
[BLE] 🔗 Verbonden met 5A6B76F9-A2C8-F05C-0FE2-23F3DEB9B80D
[BLE] 🔗 Verbonden met 5A6B76F9-A2C8-F05C-0FE2-23F3DEB9B80D

rbudding
Beiträge: 41
Registriert: 01 Nov 2010, 18:36
Wohnort: UTRECHT

Re: TXT 4.0 Controller(s) mit dem Bluetooth-Set (569021)

Beitrag von rbudding » 25 Jun 2025, 22:49

Hi all,

quick update.
1. the bluetooth module is controlled by Root

Code: Alles auswählen

txt40-XKLx:~$ ps |grep .py
  247 ftgui     252m S    {txtapi} /usr/bin/python3 /usr/bin/txtapi
18378 ftgui    42608 S    /usr/bin/python3 -u /opt/ft/workspaces/subprocess_files/subprocess_files.py
19011 redadmin  2412 S    grep .py
txt40-XKLx:~$ 
but the txtapi user has no rights. So my Python script:

Code: Alles auswählen

bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object("org.bluez", "/"),
                         "org.freedesktop.DBus.ObjectManager")

time.sleep(6)

# Get the first adapter (usually hci0)
objects = manager.GetManagedObjects()
adapter_path = None
for path, interfaces in objects.items():
    if "org.bluez.Adapter1" in interfaces:
        adapter_path = path
        break

if adapter_path is None:
    raise Exception("Bluetooth adapter not found")

adapter = dbus.Interface(bus.get_object("org.bluez", adapter_path),
                         "org.bluez.Adapter1")
props = dbus.Interface(bus.get_object("org.bluez", adapter_path),
                       "org.freedesktop.DBus.Properties")

# Power on the adapter
props.Set("org.bluez.Adapter1", "Powered", dbus.Boolean(1))

# Start discovery
adapter.StartDiscovery()

print("Scanning for 10 seconds...")
time.sleep(10)

# List found devices
objects = manager.GetManagedObjects()
for path, interfaces in objects.items():
    if "org.bluez.Device1" in interfaces:
        device = interfaces["org.bluez.Device1"]
        name = device.get("Name", "Unknown")
        addr = device.get("Address")
        print("Found: {} [{}]".format(name, addr))

# Optional: Stop discovery
adapter.StopDiscovery()
will fail, with access errors.

So I entered the conf file for user ftapi.

Code: Alles auswählen

txt40-XKLx:~$ more /etc/dbus-1/system.d/bluetooth-ftgui.conf
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
  <policy user="ftgui">
    <allow send_destination="org.bluez"/>
    <allow send_interface="org.freedesktop.DBus.Introspectable"/>
    <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
    [b]<allow send_interface="org.freedesktop.DBus.Properties"/>[/b]
    <allow send_interface="org.bluez.Adapter1"/>
    <allow send_interface="org.bluez.Device1"/>
    <allow send_interface="org.bluez.Agent1"/>
  </policy>
</busconfig>
restarted both systems:

Code: Alles auswählen

txt40-XKLx:~$ sudo systemctl restart dbus
txt40-XKLx:~$ sudo systemctl restart bluetooth
✅ What's working now:
✔ Bluetooth controller is up and managed by bluetoothd
✔ Your custom D-Bus policy (bluetooth-ftgui.conf) is granting access
✔ Python script runs from ROBO Pro Coding and:

Starts scanning
Detects devices
Resolves names via DBus
Program starts ...

Scanning for 10 seconds...
Found: j755840 [50:14:79:D8:0D:2A]
Found: Unknown [54:67:06:D7:1C:92]

Program finished.
Now I need to pair both my bluetooth modules :D

rbudding
Beiträge: 41
Registriert: 01 Nov 2010, 18:36
Wohnort: UTRECHT

Re: TXT 4.0 Controller(s) mit dem Bluetooth-Set (569021)

Beitrag von rbudding » 25 Jun 2025, 23:19

🧠 What's confirmed so far
✅ bluetoothd is running with experimental features

Code: Alles auswählen

txt40-XKLx:~$ sudo killall bluetoothd
txt40-XKLx:~$ sudo /usr/libexec/bluetooth/bluetoothd --experimental --debug --nodetach &
txt40-XKLx:~$ bluetoothd[14314]: Bluetooth daemon 5.50
✅ Your BT Smart Controller advertises properly — visible on your Mac

✅ bluetoothctl works in general, other devices are discovered

Code: Alles auswählen

txt40-XKLx:~$ sudo bluetoothctl
Agent registered
[bluetooth]# power on
[CHG] Controller 00:13:43:AD:87:99 Class: 0x00000300
Changing power on succeeded
[CHG] Controller 00:13:43:AD:87:99 Powered: yes
[bluetooth]# agent on
Agent is already registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:13:43:AD:87:99 Discovering: yes
[NEW] Device 50:14:79:D8:0D:2A j755840
[CHG] Device 50:14:79:D8:0D:2A RSSI: -65
[bluetooth]# devices
Device 54:67:06:D7:1C:92 54-67-06-D7-1C-92
Device 50:14:79:D8:0D:2A j755840
[NEW] Device 80:5B:65:A5:33:7F [LG] webOS TV OLED55G26LA
[CHG] Device 50:14:79:D8:0D:2A RSSI: -77
[CHG] Device 50:14:79:D8:0D:2A RSSI: -65
[NEW] Device 80:CB:BC:B0:55:AB 80-CB-BC-B0-55-AB
[CHG] Device 50:14:79:D8:0D:2A RSSI: -74
[CHG] Device 80:5B:65:A5:33:7F RSSI: -70

❌ The BT Smart Controller (10:45:F8:6C:B8:85) is not seen by the TXT 4.0

💡 Most likely causes
BlueZ 5.50 lacks sufficient BLE scan support

Many BLE peripherals use extended advertising, connectable undirected advertising, or manufacturer-specific payloads.

These are poorly handled or ignored in BlueZ ≤ 5.50.

Even with bluetoothctl scan on, GATT devices may not be picked up unless a specific tool actively requests BLE advertisements (which bluetoothctl sometimes doesn’t do well on older versions).

TXT 4.0 hardware limitations
Though unlikely, there could be firmware-side limits to BLE support (some older chips are better at Classic Bluetooth).

rbudding
Beiträge: 41
Registriert: 01 Nov 2010, 18:36
Wohnort: UTRECHT

Re: TXT 4.0 Controller(s) mit dem Bluetooth-Set (569021)

Beitrag von rbudding » 25 Jun 2025, 23:20

My Robo Pro Coding code : (works as a scanner... )

Code: Alles auswählen

import dbus
import time

bus = dbus.SystemBus()

# Get BlueZ objects
manager = dbus.Interface(bus.get_object("org.bluez", "/"), "org.freedesktop.DBus.ObjectManager")
adapter_obj = bus.get_object("org.bluez", "/org/bluez/hci0")

# Use the correct interface to set properties
props = dbus.Interface(adapter_obj, "org.freedesktop.DBus.Properties")
adapter = dbus.Interface(adapter_obj, "org.bluez.Adapter1")

# Power on the adapter
props.Set("org.bluez.Adapter1", "Powered", dbus.Boolean(1))

# Start discovery
adapter.StartDiscovery()
print("Scanning for BT Smart devices...")

seen = set()
timeout = time.time() + 100
while time.time() < timeout:
    objects = manager.GetManagedObjects()
    for path, interfaces in objects.items():
        device = interfaces.get("org.bluez.Device1")
        if not device:
            continue
        name = str(device.get("Name", ""))
        addr = str(device.get("Address", ""))
        print(name)
        if addr not in seen and "BT Smart" in name:
            seen.add(addr)
            print("Found: {} [{}]".format(name, addr))
    time.sleep(1)

adapter.StopDiscovery()
print("Scan complete.")

Antworten