Skip to content

tools_communication_clients

The tools_communication_clients module provides PC-side developer tools for testing, debugging, and validating the communication transports of the Pibot CNC Pendant firmware. Each tool mirrors one of the firmware’s transport channels, letting a developer reproduce the exact protocol sequences the pendant uses — without needing a second physical pendant or CNC machine.

The tools live in the tools/ directory tree and are standalone Python scripts that run on any desktop/laptop. They are not compiled into the firmware; they interact with the pendant or with a CNC controller over USB, Bluetooth, Telnet (TCP), or WebSocket depending on the tool.

Related firmware module: Communication_Transports — the embedded implementations these tools exercise.


CNC Controller

Pendant Firmware (ESP32)

Developer Workstation (Python tools)

UART (two ports)

UART

BLE GATT FFF0

BT SPP COM port

BT SPP COM port

TCP :23

WebSocket /wsdata

esp3d-v1

GCode

GCode

GCode

GCode

GCode / files

serial_bridge.py

SerialBridge

(bidirectional relay)

fluidnc_ble.py

FluidNcBle

(BLE GATT client)

fluidnc_bt.py

FluidNcBt

(BT SPP client)

grblhal_bt.py

GrblHalBt

(BT SPP client)

fluidnc_serial.py

FluidNcSerial

(UART client)

grblhal_telnet.py

GrblHalTelnet

(TCP/Telnet client)

ws_transfer_test.py

WebSocket V1

(file transfer tester)

ESP3DSerialClient

serial/

ESP3DBTBleClient

bt_ble/

ESP3DBTSerialClient

bt_serial/

ESP3DSocketClient

socket_client/

ESP3DWebsocketClient

websocket_client/

FluidNC / grblHAL

Each tool connects to one transport and uses the same protocol framing the firmware uses, making them suitable for:

  • Validating a transport after a code change
  • Replaying the pendant’s startup/init sequence manually
  • Capturing raw traffic for debugging
  • Testing binary file transfer (WebSocket V1 protocol)

Generated sub-module documentation files:

1. Serial Bridge — tools/bridge/serial_bridge.py

Section titled “1. Serial Bridge — tools/bridge/serial_bridge.py”

Detailed reference: tools_communication_clients_serial_bridge.md

A bidirectional serial relay that simultaneously connects two serial (USB/UART) ports and relays data between them in both directions. Primary use-case: inserting a PC between the pendant and the CNC controller to observe or inject traffic without modifying firmware.

ClassResponsibility
SerialBridgeOpens two pyserial ports, spawns three threads (Port1→Port2, Port2→Port1, keyboard), processes G-code commands line-by-line

Key capabilities:

  • Color-coded console output (green = Port1→Port2, blue = Port2→Port1, yellow = keyboard injection)
  • Interactive keyboard input with port-switching shortcuts (Ctrl+A/B/S, or type 1/2)
  • Built-in G-code shortcut commands (status, home, unlock, reset)
  • Cross-platform (Windows msvcrt, Unix select)

Quick start:

Terminal window
pip install pyserial
python tools/bridge/serial_bridge.py /dev/ttyUSB0 /dev/ttyUSB1
python tools/bridge/serial_bridge.py --list # enumerate available ports

Detailed reference: tools_communication_clients_bt_clients.md

Three Tkinter GUI terminals covering every Bluetooth transport the firmware supports:

ScriptClassProtocolTarget firmware
fluidnc_ble.pyFluidNcBleBLE GATT (service 0xFFF0)ESP3DBTBleClient — FluidNC
fluidnc_bt.pyFluidNcBtBT Classic SPP (COM port)ESP3DBTSerialClient — FluidNC
grblhal_bt.pyGrblHalBtBT Classic SPP (COM port)ESP3DBTSerialClient — grblHAL

All three share the same UI pattern: connection bar, scrolled log (color-coded RX/TX/INFO/ERR), real-time single-byte command buttons, a manual command entry, and a raw hex sender.

The BLE client (FluidNcBle) additionally provides:

  • Async BLE scanning via bleak with RSSI sorting and service-UUID filtering
  • GATT Device Name query for unnamed devices
  • MTU-aware chunked writes (20-byte BLE default)
  • Sequenced init flow replay matching the pendant’s startup behavior

Quick start:

Terminal window
pip install pyserial bleak
python tools/bt_client/fluidnc_ble.py # BLE
python tools/bt_client/fluidnc_bt.py COM5 # BT SPP — FluidNC
python tools/bt_client/grblhal_bt.py COM5 # BT SPP — grblHAL

3. Serial Client — tools/serial_client/fluidnc_serial.py

Section titled “3. Serial Client — tools/serial_client/fluidnc_serial.py”

A Tkinter GUI terminal for observing and replaying the pendant’s FluidNC serial connection over a USB/UART port. The pendant’s UART0 (GPIO1/GPIO3) is the same port used for flashing and appears as a standard COM device on the host PC.

ClassKey methods
FluidNcSerial_connect(), _recv_loop(), _send_raw(), _send_text_direct(), _send_full_sequence()

The UI is identical in structure to the BT Serial clients. It targets ESP3DSerialClient in the firmware.

Init sequence replayed (matching pendant startup):

ButtonCommand sent
$I (identify)$I\n
$Report/Interval=100$Report/Interval=100\n
$planner_blocks$planner_blocks\n
$10=3 (full reports)$10=3\n

Real-time single-byte commands: ?, !, ~, 0x18 (reset), 0x85 (jog cancel)

Quick start:

Terminal window
pip install pyserial
python tools/serial_client/fluidnc_serial.py /dev/ttyUSB0 115200

4. Telnet Client — tools/telnet_client/grblhal_telnet.py

Section titled “4. Telnet Client — tools/telnet_client/grblhal_telnet.py”

A Tkinter GUI terminal that connects to a grblHAL controller over a raw TCP socket (default port 23 — telnet). This exercises the same TCP path the firmware uses when SOCKET_CLIENT_SERVICE is enabled (ESP3DSocketClient).

ClassKey methods
GrblHalTelnet_connect(), _recv_loop(), _send_raw(), _send_text(), _send_hex()

grblHAL-specific real-time bytes exposed:

ButtonByte
Status report all0x87
MPG toggle0x8B
AR toggle0x8C
Soft reset0x18
Feed hold / cycle start / jog cancel! / ~ / 0x85

Quick start:

Terminal window
python tools/telnet_client/grblhal_telnet.py 192.168.1.100 23
python tools/telnet_client/grblhal_telnet.py 192.168.1.100 23 admin # ESP3D-X with authentication

ESP3D-X telnet server (a14): with authentication enabled every connection starts as guest. Fill Password (user or admin, or give it as third argument) to send [ESP500] pwd=<password> right after connecting (shown as pwd=*** in the log), or use the Login button; Logout sends [ESP500]LOGOUT (the connection stays open, back to guest).


5. WebSocket Transfer Test — tools/websocket/ws_transfer_test.py

Section titled “5. WebSocket Transfer Test — tools/websocket/ws_transfer_test.py”

Detailed reference: tools_communication_clients_websocket.md

A command-line tool implementing the full ESP3D WebSocket Protocol V1 binary file-transfer layer on the /wsdata endpoint (subprotocol esp3d-v1). It exercises ESP3DWebsocketClient and ESP3DWsDataService.

OperationCLI sub-commandDescription
Probe binary supportstatusSend SR, await RS — confirms V1 capability
List fileslist <path>Send [ESP720]/[ESP740] command, receive JSON or text
Uploadupload <local> <remote_dir>SU → US → UP/PU × N → EU → UE
Downloaddownload <remote_dir> <name>SD → DS → DP/PD × N → ED → DE
Round-triproundtrip <local> <remote_dir>Upload + download + MD5 comparison

Quick start:

Terminal window
pip install websockets
python tools/websocket/ws_transfer_test.py --host 192.168.1.100 --port 8282 status
python tools/websocket/ws_transfer_test.py --host 192.168.1.100 --port 8282 list /
python tools/websocket/ws_transfer_test.py --host 192.168.1.100 --port 8282 upload myfile.nc /fs

ToolTransportGUITarget firmwareFirmware config flag
serial_bridge.pyUART (two ports)CLIESP3DSerialClientAlways available
fluidnc_serial.pyUART (single port)TkinterESP3DSerialClientAlways available
fluidnc_ble.pyBLE GATT 0xFFF0TkinterESP3DBTBleClientBT_BLE_SERVICE
fluidnc_bt.pyBT Classic SPPTkinterESP3DBTSerialClientBT_SERIAL_SERVICE
grblhal_bt.pyBT Classic SPPTkinterESP3DBTSerialClientBT_SERIAL_SERVICE
grblhal_telnet.pyTCP (Telnet)TkinterESP3DSocketClientSOCKET_CLIENT_SERVICE
ws_transfer_test.pyWebSocket /wsdataCLIESP3DWebsocketClient + ESP3DWsDataServiceWS_CLIENT_SERVICE

⚠️ Mutual exclusion: The firmware’s cmake/sanity_check.cmake forbids enabling both SOCKET_CLIENT_SERVICE and WebUI/SSDP services simultaneously. Bluetooth (BLE/SPP) and WiFi are also mutually exclusive on boards without PSRAM. See feature_resource_matrix.md before selecting a transport.


Firmware Startup Init (Serial / BT clients)

Section titled “Firmware Startup Init (Serial / BT clients)”

All serial and BT clients provide a “Full sequence” button that replays the pendant’s startup G-code handshake:

CNC ControllerPendant FirmwareDebug Client (PC)CNC ControllerPendant FirmwareDebug Client (PC)Debug client replays this same sequence$IFirmware info string$Report/Interval=100$planner_blocks$10=3$I\n(forwarded)InfoRX: info line ESP WebSocket Serverws_transfer_test.pyESP WebSocket Serverws_transfer_test.pybinary_capable = Truebinary_capable = Falsealt[Binary supported][No binary support / timeout]WebSocket connect /wsdata (esp3d-v1)TEXT welcome frameBINARY frame [SR][len=0]BINARY frame [RS][len>=1][status_byte ...]
ToolPython packages
serial_bridge.pypyserial
fluidnc_serial.pypyserial
fluidnc_bt.pypyserial
grblhal_bt.pypyserial
fluidnc_ble.pybleak
grblhal_telnet.pystdlib only (socket, threading, tkinter)
ws_transfer_test.pywebsockets

All tools require Python 3.9+ and are cross-platform (Windows / Linux / macOS).


tools/
├── bridge/
│ └── serial_bridge.py # Bidirectional serial relay
├── bt_client/
│ ├── fluidnc_ble.py # BLE GATT debug terminal
│ ├── fluidnc_bt.py # BT Serial debug terminal (FluidNC)
│ └── grblhal_bt.py # BT Serial debug terminal (grblHAL)
├── serial_client/
│ └── fluidnc_serial.py # UART debug terminal (FluidNC)
├── telnet_client/
│ └── grblhal_telnet.py # TCP/Telnet debug terminal (grblHAL)
└── websocket/
└── ws_transfer_test.py # WebSocket V1 file transfer tester