{"id":22760276,"url":"https://github.com/jakeler/ble-serial","last_synced_at":"2025-05-15T10:06:41.876Z","repository":{"id":40414395,"uuid":"225734653","full_name":"Jakeler/ble-serial","owner":"Jakeler","description":" \"RFCOMM for BLE\" a Serial UART over Bluetooth low energy (4+) bridge for Linux, Mac and Windows","archived":false,"fork":false,"pushed_at":"2024-12-10T03:04:28.000Z","size":323,"stargazers_count":325,"open_issues_count":5,"forks_count":41,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-05-15T10:06:03.099Z","etag":null,"topics":["bluetooth","bluetooth-low-energy","linux","python","serialport","uart"],"latest_commit_sha":null,"homepage":"https://blog.ja-ke.tech/tags/#bluetooth","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Jakeler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-03T23:07:41.000Z","updated_at":"2025-05-15T05:33:28.000Z","dependencies_parsed_at":"2024-06-21T19:01:58.402Z","dependency_job_id":"5a255658-7443-4267-8dfa-71ffd20f0651","html_url":"https://github.com/Jakeler/ble-serial","commit_stats":{"total_commits":214,"total_committers":5,"mean_commits":42.8,"dds":0.01869158878504673,"last_synced_commit":"b11892544bbb73c684cd68e4ef23afd7ce4820f7"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jakeler%2Fble-serial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jakeler%2Fble-serial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jakeler%2Fble-serial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Jakeler%2Fble-serial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Jakeler","download_url":"https://codeload.github.com/Jakeler/ble-serial/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254319720,"owners_count":22051073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bluetooth","bluetooth-low-energy","linux","python","serialport","uart"],"created_at":"2024-12-11T09:06:26.424Z","updated_at":"2025-05-15T10:06:41.822Z","avatar_url":"https://github.com/Jakeler.png","language":"Python","readme":"# BLE Serial\nA tool to connect Bluetooth 4.0+ Low Energy to UART modules and normal PCs/laptops/RaspberryPi.\n\nIt fulfills the same purpose as `rfcomm bind` for the old Bluetooth 2.0, creating a virtual serial port in `/dev/pts/x`, which makes it usable with any terminal or application.\n\nOn Windows it provides a `COM` port, similar to the Microsoft \"Standard Serial over Bluetooth\" (a driver which exists since Windows XP and unsurprisingly also does not support BLE standards).\n\n## Installation\n### Standard (via [Python Package Index](https://pypi.org/project/ble-serial/))\nThe software is written completely in Python and packaged as module, so it can be easily installed with pip:\n```console\n$ pip install ble-serial\n```\n\nNow you should have 2 new scripts: `ble-scan` and the main `ble-serial`.\n\nOn Linux/Mac you are ready now and can directly jump to the [usage](#usage) section!\nFor Windows follow the [additional steps below](#additional-steps-for-windows).\n\n### From source (for developers)\nYou can clone the repository with:\n```console\n$ git clone https://github.com/Jakeler/ble-serial.git\n```\n\nThen switch branches, make changes etc... \nMake sure the dependencies are installed, I recommend to use a virtualenv like this:\n```console\n$ python -m venv ble-venv\n$ source ble-venv/bin/activate\n$ pip install -r requirements.txt\n```\n\nThe package can be either started directly with `-m`:\n```console\n$ python -m ble_serial ARGUMENTS # Main tool = ble-serial\n$ python -m ble_serial.scan # BLE scan = ble-scan\n$ python -m ble_serial.setup_com0com # Windows only setup = ble-com-setup\n```\n\nOr installed with `pip` from the current directory:\n```console\n$ pip install .\n```\nand started as usual.\n\n### Additional steps for Windows\nWindows does not have a builtin feature to create virtual serial ports (like Linux does), so it is required to install a additional driver. \nI decided to use the open source `com0com` Null-modem emulator, downloaded from [here](https://sourceforge.net/projects/signed-drivers/files/com0com/v3.0/) as signed version. This is required because unsigned drivers can not be installed anymore.\n\n**Note: on Windows 10+ you still have to disable secure boot for it to work.** Otherwise you might get a `Unexpected Error: SerialException` when starting ble-serial.\n\nble-serial includes the `ble-com-setup` script to make the `com0com` configuration easier:\n```console\n\u003e ble-com-setup.exe -h\nusage: ble-com-setup [-h] [--install-path INSTALL_PATH]\n\nSetup required COM port pair\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --install-path INSTALL_PATH\n                        Installation directory of the null modem emulator (default: C:/Program Files (x86)/com0com/)\n```\n\nIt will request administrator privileges (if it does not already have it) and setup the port in another CMD window:\n```\n\u003e ble-com-setup.exe\nOK\n\n[New Window]\nChanging into C:/Program Files (x86)/com0com/\n\n\u003e Checking port list for BLE\n       CNCA0 PortName=-\n       CNCB0 PortName=-\n\nBLE port does not exist\n\n\u003e Checking port list for COM9\n       CNCA0 PortName=-\n       CNCB0 PortName=-\n\n\u003e Trying to create port pair\n       CNCA1 PortName=COM9\n       CNCB1 PortName=BLE\nComDB: COM9 - logged as \"in use\"\n\nSetup done!\n\nHit any key to close\n```\nAs you can see it created the `BLE`\u003c-\u003e`COM9` pair. ble-serial will internally connect to `BLE`, users can then send/receive the data on `COM9`.\n\nOtherwise there exist multiple proprietary serial port emulators, these should work too. Just manually create a pair that includes a port named `BLE`.\n\n## Usage\n### Finding devices\nFirst make sure the bluetooth adapter is enabled, for example with `bluetoothctl power on`, then the scan function can be used:\n```console\n$ ble-scan\n\nStarted BLE scan\n\n20:91:48:4C:4C:54 (RSSI=-56): UT61E -  JK\n...\n\nFinished BLE scan\n```\nThe output is a list of the recognized nearby devices. After the MAC address and signal strength it prints out the device name, if it can be resolved.\n\nOn macOS it displays a system specific device ID instead of a MAC address:\n```\n55AEB150-5AF1-4318-A02E-19A46223F572 (RSSI=-70): nRF52 Accelerometer\n```\nIt can be used simply in place of the MAC to specify a device to connect in the following section.\n\nIf there are no devices found it might help to increase the scan time. All discoverable devices must actively send advertisements, the interval of this can be quite long to save power, try for example 30 seconds in this case.\n```console\n$ ble-scan -h\nusage: ble-scan [-h] [-t SEC] [-d ADDR]\n\nScanner for BLE devices and service/characteristics.\n\noptions:\n  -h, --help            show this help message and exit\n  -t SEC, --scan-time SEC\n                        Duration of the scan in seconds (default: 5.0)\n  -i ADAPTER, --interface ADAPTER\n                        BLE host adapter number to use (default: hci0)\n  -d ADDR, --deep-scan ADDR\n                        Try to connect to device and read out service/characteristic UUIDs (default: None)\n  -s SERVICE_UUID, --service-uuid SERVICE_UUID\n                        The service used for scanning of potential devices (default: None)\n  -v, --verbose         Print all infos from advertisement data (default: False)\n```\n\nOn Bluetooth 2.0 there was a \"serial port profile\", with 4.0 - 5.2 (BLE) there is unfortunately no standardized mode anymore, every chip manufacturer chooses their own UUIDs to implement the features. \n```py\n'0000ff01-0000-1000-8000-00805f9b34fb', # LithiumBatteryPCB adapter: read/notify\n'0000ff02-0000-1000-8000-00805f9b34fb', # LithiumBatteryPCB adapter: write\n'0000ffe1-0000-1000-8000-00805f9b34fb', # TI CC245x (HM-10, HM-11)\n```\nSome usual read/write UUIDs are included in ble-serial, these will be tried automatically if nothing is specified.\nYou might skip this part and start directly with the connection.\n\nOtherwise to find the correct UUID, use the deep scan option. It expects a device MAC/ID, connects to it and reads out all services/characteristic/descriptors:\n```console\n$ ble-scan -d 20:91:48:4C:4C:54\nStarted deep scan of 20:91:48:4C:4C:54\n\nSERVICE 00001801-0000-1000-8000-00805f9b34fb (Handle: 12): Generic Attribute Profile\n     CHARACTERISTIC 00002a05-0000-1000-8000-00805f9b34fb (Handle: 13): Service Changed ['indicate']\n         DESCRIPTOR 00002902-0000-1000-8000-00805f9b34fb (Handle: 15): Client Characteristic Configuration\nSERVICE 0000ffe0-0000-1000-8000-00805f9b34fb (Handle: 16): Vendor specific\n     CHARACTERISTIC 0000ffe1-0000-1000-8000-00805f9b34fb (Handle: 17): Vendor specific ['read', 'write-without-response', 'notify']\n         DESCRIPTOR 00002902-0000-1000-8000-00805f9b34fb (Handle: 19): Client Characteristic Configuration\n         DESCRIPTOR 00002901-0000-1000-8000-00805f9b34fb (Handle: 20): Characteristic User Description\n\nCompleted deep scan of 20:91:48:4C:4C:54\n```\nNow the interesting parts are the characteristics, grouped into services. The ones belows the first service starting with `00002` are not relevant in this case, because they are standard values (for example the device name), if you want to know more look at [this list](https://gist.github.com/sam016/4abe921b5a9ee27f67b3686910293026#file-allgattcharacteristics-java-L57).\n\nAfter the UUID, handle and type the permissions are listed in []. We are searching for a characteristic that allows writing = sending to the device, the only candidate in here is `0000ffe1-0000-1000-8000-00805f9b34fb` (spoiler: a HM-11 module again).\nSame procedure with the read characteristic, here you have to actually look for `notify` or `indicate`, that is how the receiving side is informed about new data in BLE.\nThis module handles both directions through the same characteristic.\n\nSome other chips split it up, for example (this time on macOS with device ID):\n```console\n$ ble-scan -d 55AEB150-5AF1-4318-A02E-19A46223F572\nStarted deep scan of 55AEB150-5AF1-4318-A02E-19A46223F572\n\nSERVICE 00000001-af0e-4c28-95a4-4509fd91e0bb (Handle: 10): SDP\n     CHARACTERISTIC 00000006-af0e-4c28-95a4-4509fd91e0bb (Handle: 11): Unknown ['read', 'notify']\n         DESCRIPTOR 00002902-0000-1000-8000-00805f9b34fb (Handle: 13): Client Characteristic Configuration\n     CHARACTERISTIC 00000005-af0e-4c28-95a4-4509fd91e0bb (Handle: 14): TCS-BIN ['write-without-response', 'notify']\n         DESCRIPTOR 00002902-0000-1000-8000-00805f9b34fb (Handle: 16): Client Characteristic Configuration\n\nCompleted deep scan of 55AEB150-5AF1-4318-A02E-19A46223F572\n```\nAs you can see, here the read/notify UUID is `00000006-af0e-4c28-95a4-4509fd91e0b` and write UUID `00000005-af0e-4c28-95a4-4509fd91e0bb`.\n\n### Connecting a device\nThe `ble-serial` tool itself has a few more options:\n```console\n$ ble_serial -h\nusage: ble-serial [-h] [-v] [-t SEC] [-i ADAPTER] [-m MTU] [-g {server,client}] [-n GAP_NAME] [-d DEVICE] [-a {public,random}] [-s SERVICE_UUID] [-r READ_UUID] [-w WRITE_UUID] [--permit {ro,rw,wo}] [--write-with-response]\n                  [-l FILENAME] [-b] [-p PORT] [--expose-tcp-host TCP_HOST] [--expose-tcp-port TCP_PORT]\n\nCreate virtual serial ports from BLE devices.\n\noptions:\n  -h, --help            show this help message and exit\n  -v, --verbose         Increase verbosity, can be specified multiple times for connection/DBus debugging (default: 0)\n\nconnection parameters:\n  -t SEC, --timeout SEC\n                        BLE connect/discover timeout in seconds (default: 5.0)\n  -i ADAPTER, --interface ADAPTER\n                        BLE host adapter number to use (default: hci0)\n  -m MTU, --mtu MTU     Max. bluetooth packet data size in bytes used for sending (default: 20)\n\ndevice parameters:\n  -g {server,client}, --role {server,client}\n                        Operate as BLE role: client (BLE central), server (BLE peripheral) (default: client)\n  -n GAP_NAME, --name GAP_NAME\n                        Custom display name in BLE server mode, uses \"BLE Serial Server {PID}\" otherwise. Prefix for logs lines in all modes. (default: None)\n  -d DEVICE, --dev DEVICE\n                        BLE device address to connect (hex format, can be separated by colons) (default: None)\n  -a {public,random}, --address-type {public,random}\n                        BLE address type, only relevant on Windows, ignored otherwise (default: public)\n  -s SERVICE_UUID, --service-uuid SERVICE_UUID\n                        In \"client\" mode - service UUID used for scanning of potential devices. In \"server\" mode - service UUID used to provide read/write GATT characteristics. (default: None)\n  -r READ_UUID, --read-uuid READ_UUID\n                        The GATT characteristic to subscribe to notifications to read the serial data. If omitted, will be auto generated based on service UUID (default: None)\n  -w WRITE_UUID, --write-uuid WRITE_UUID\n                        The GATT characteristic to write the serial data, you might use \"ble-scan -d\" to find it out. If omitted, will be auto generated based on service UUID (default: None)\n  --permit {ro,rw,wo}   Restrict transfer direction on bluetooth: read only (ro), read+write (rw), write only (wo) (default: rw)\n  --write-with-response\n                        Wait for a response from the remote device before sending more. Better data integrity, higher latency and less throughput (default: False)\n```\n\nIn any case it needs to know which device to connect, the simple and most reliable way to specify this is by device address/id:\n```console\n$ ble-serial -d 20:91:48:4c:4c:54\n20:38:31.271 | INFO | linux_pty.py: Port endpoint created on /tmp/ttyBLE -\u003e /dev/pts/5\n20:38:31.271 | INFO | ble_interface.py: Receiver set up\n20:38:31.485 | INFO | ble_interface.py: Trying to connect with 20:91:48:4C:4C:54: UT61E -  JK\n20:38:32.844 | INFO | ble_interface.py: Device 20:91:48:4C:4C:54 connected\n20:38:32.844 | INFO | ble_interface.py: Found write characteristic 0000ffe1-0000-1000-8000-00805f9b34fb (H. 17)\n20:38:32.844 | INFO | ble_interface.py: Found notify characteristic 0000ffe1-0000-1000-8000-00805f9b34fb (H. 17)\n20:38:33.128 | INFO | main.py: Running main loop!\n\n```\nThis log shows a successful start on Linux, the virtual serial port was opened on `/dev/pts/8`, the number at the end changes, depending on how many pseudo terminals are already open on the system. It uses the same mechanism on macOS, just the path is slightly different, in the format `/dev/ttys000`.\nIn addition it automatically creates a symlink to `/tmp/ttyBLE`, so you can easily access it always on the same file, the default can be changed with:\n```\nserial port parameters:\n  -p PORT, --port PORT  Symlink to virtual serial port (default: /tmp/ttyBLE)\n```\n\nOn Windows it uses the port pair created in the setup described above, this does not dynamically change and endpoint is always `COM9` if you use the default script.\n\nNow it is possible to use any serial monitor program, just connect to that port, baud rate etc. does not matter, it will work with any value (settings are ignored, because it is only virtual).\nThe software acts as transparent bridge, everything that is sent to that virtual port gets transmitted to the BLE module and comes out of the TX pin there. Same in the other direction, everything that the BLE module receives on the RX pin gets transmitted to the PC and shows up in the virtual serial port. This makes it also possible to add ble module to create a wireless serial connection with existing hard/software.\n\nAnother way to find a device is by service uuid:\n```console\n$ ble-serial -s 0000ffe0-0000-1000-8000-00805f9b34fb\n20:35:41.964 | INFO | linux_pty.py: Port endpoint created on /tmp/ttyBLE -\u003e /dev/pts/5\n20:35:41.964 | INFO | ble_interface.py: Receiver set up\n20:35:41.964 | WARNING | ble_interface.py: Picking first device with matching service, consider passing a specific device address, especially if there could be multiple devices\n20:35:42.308 | INFO | ble_interface.py: Trying to connect with 20:91:48:4C:4C:54: UT61E -  JK\n20:35:43.020 | INFO | ble_interface.py: Device 20:91:48:4C:4C:54 connected\n...\n```\nThis has the advantage that you can replace the device/chip without changing anything in the host script, it will automatically pick the first device that provides the service. It is also possible to add both the service and address, then it will only connect if both match.\nOn early versions of macOS 12 (Monterey) it is always required to filter with the service uuid, otherwise scanning/connecting won't work.\n\nAs mentioned before, the start might fail because the characteristic UUIDs are not in the list, then you can manually specify the correct write UUID like this:\n```\n$ ble-serial -d 20:91:48:4c:4c:54 -w 0000ffe1-0000-1000-8000-00805f9b34fb\n```\n\nSame for reading with `-r`/`--read-uuid`, for example:\n```\n$ ble-serial -d 20:91:48:4c:4c:54 -r 0000ffe1-0000-1000-8000-00805f9b34fb\n```\n\nPer default it always tries to setup reading and writing and searches for both characteristics. If none of your characteristics are in the builtin list then you have to specify both `-w` and `-r`. \n\nOtherwise if your device has only a read/notify characteristic or you want to intentionally prevent writing then you can use `--permit`:\n```\n$ ble-serial -d 20:91:48:4c:4c:54 -r 0000ffe1-0000-1000-8000-00805f9b34fb --permit ro\n```\nHere `-r` is enough for `ro` = read only. \nThis works also the other way around with `wo` = write only.\n\n### Log to file\nThere is an option to log all traffic on the link to a text file:\n```\nlogging options:\n  -l FILENAME, --log FILENAME\n                        Enable optional logging of all bluetooth traffic to file (default: None)\n  -b, --binary          Log data as raw binary, disable transformation to hex. Works only in combination with -l (default: False)\n```\n\n```console\n$ ble-serial -d 20:91:48:4c:4c:54 -l demo.txt\n...\n$ cat demo.txt\n2019-12-09 21:15:53.282805 \u003c- BLE-OUT: 48 65 6c 6c 6f 20 77 6f 72 6c 64\n2019-12-09 21:15:53.491681 -\u003e BLE-IN: b0 b0 b0 b0 b0 b0 3b b0 b0 b0 ba b0 0d 8a\n2019-12-09 21:15:53.999795 -\u003e BLE-IN: b0 b0 b0 b0 b0 b0 3b b0 b0 b0 ba b0 0d 8a\n```\nPer default it is transformed to hex bytes, use `-b`/`--binary` to log raw data, useful if your input is already ASCII etc.\n\n## Advanced Usage\n### Bluetooth server\nPer default ble-serial operates in client (ble central) role and can connect to typical modules (ble peripheral) which define services and advertise itself.\nSince version 3.0 it's possible to swap these roles with `-g {server,client}`/`--role {server,client}`.\n\n#### Prerequisites\nInstall extra dependencies with:\n```console\n$ pip install ble-serial[server]\n```\nand on Windows additionally (one not on pypi):\n```console\n$ pip install https://github.com/gwangyi/pysetupdi/archive/refs/heads/master.zip\n```\n\n#### Config and startup\nNo external device argument is required in this mode, but you have to define the service and characteristics.\n```console\n$ ble-serial -g server -s 6e400001-b5a3-f393-e0a9-e50e24dcca9e\n17:02:23.860 | INFO | linux_pty.py: Port endpoint created on /tmp/ttyBLE -\u003e /dev/pts/6\n17:02:23.860 | INFO | ble_server.py: Name/ID: BLE Serial Server 11296\n17:02:23.860 | INFO | ble_server.py: Listener set up\n17:02:23.860 | WARNING | uuid_helpers.py: No write uuid specified, derived from service 6e400001-b5a3-f393-e0a9-e50e24dcca9e -\u003e 6e400002-b5a3-f393-e0a9-e50e24dcca9e\n17:02:23.860 | WARNING | uuid_helpers.py: No read uuid specified, derived from service 6e400001-b5a3-f393-e0a9-e50e24dcca9e -\u003e 6e400003-b5a3-f393-e0a9-e50e24dcca9e\n17:02:23.864 | INFO | ble_server.py: Service 6e400001-b5a3-f393-e0a9-e50e24dcca9e\n17:02:23.864 | INFO | ble_server.py: Write characteristic: 6e400002-b5a3-f393-e0a9-e50e24dcca9e: Nordic UART RX\n17:02:23.864 | INFO | ble_server.py: Read characteristic: 6e400003-b5a3-f393-e0a9-e50e24dcca9e: Nordic UART TX\n17:02:23.893 | INFO | ble_server.py: Server startup successful\n17:02:23.893 | INFO | main.py: Running main loop!\n```\nIt automatically derives all characteristics when only the service uuid is specified, the run above is equivalent to `-w 6e400002-b5a3-f393-e0a9-e50e24dcca9e` `-r 6e400003-b5a3-f393-e0a9-e50e24dcca9e`. Also the other arguments (name, mtu, logs, ports, tcp, etc.) are supported.\n\n#### Connection\nWorks like with any other server via the device address. Note that mac address might change in every session depending on OS/platform and currently it's not possible to set or display this value.\n\nUsing ble-serial as client on the other machine can solve this with service based selection:\n\n```console\n$ ble-serial -g client -s 6e400001-b5a3-f393-e0a9-e50e24dcca9e\n...\n17:27:26.069 | WARNING | ble_client.py: Picking first device with matching service, consider passing a specific device address, especially if there could be multiple devices\n17:27:27.685 | INFO | ble_client.py: Trying to connect with [MAC]: BLE Serial Server 11296\n```\n\nWith a custom service it's also highly unlikely to accidentally connect a wrong device. So maybe use something else than the standard Nordic UART service and the warning can be ignored.\n\n### TCP socket server\nInstead of the serial port emulation there is a also builtin raw tcp server since version 2.7:\n```\nnetwork options:\n  --expose-tcp-host TCP_HOST\n                        Network interface for the server listen on (default: 127.0.0.1)\n  --expose-tcp-port TCP_PORT\n                        Port to listen on, disables local serial port and enables TCP server if specified (default: None)\n```\nThis is only activated if TCP_PORT is set. Also it removes the dependency to com0com or other drivers.\n\nThe server is listening on localhost per default, therefore only reachable from apps running on the same machine. Other interfaces or `0.0.0.0` for all interfaces can be specified with TCP_HOST.\nSecurity is to consider though, this is plain TCP without encryption or authentication. Only recommended on a separate local network, otherwise stay with the default/localhost.\n\nNote: this is limited to one concurrent connection, it will reject all connection attempts if there is already a client connected and emit a warning, example:\n```console\n$ ble-serial -d 20:91:48:4C:4C:54 --expose-tcp-port 4002 -v\n[...]\n19:30:11.650 | INFO | main.py: Running main loop!\n19:30:11.650 | INFO | tcp_socket.py: TCP server started\n19:30:11.650 | DEBUG | tcp_socket.py: Listening on \u003casyncio.TransportSocket fd=8, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('127.0.0.1', 4002)\u003e\n[...]\n19:30:13.618 | INFO | tcp_socket.py: New TCP peer connected: ('127.0.0.1', 49104)\n19:30:13.787 | DEBUG | ble_interface.py: Received notify from 0000ffe1-0000-1000-8000-00805f9b34fb (Handle: 17): Vendor specific: bytearray(b'\\xb0\\xb0\\xb0\\xb01\\xb6;\\xb0\\xb0\\xb0\\xba\\xb0\\r\\x8a')\n19:30:13.787 | DEBUG | tcp_socket.py: Sending: bytearray(b'\\xb0\\xb0\\xb0\\xb01\\xb6;\\xb0\\xb0\\xb0\\xba\\xb0\\r\\x8a')\n[...]\n19:30:26.726 | INFO | tcp_socket.py: New TCP peer connected: ('127.0.0.1', 56172)\n19:30:26.726 | WARNING | tcp_socket.py: More than one connection is not allowed, closing\n```\n\nNow there a various ways to connect to it. \n#### Linux and macOS\n- Very simple option: `netcat 127.0.0.1 4002` or `telnet 127.0.0.1 4002`\n- More powerful: `socat -dd tcp:localhost:4002 -`, can forward data to many modules, not only stdin/stdout.\n- Custom apps are easy to make with tcp too\n#### Windows\n- Graphical: Putty, just put in the IP+port and select Other - Raw as connection type.\n- Terminal: netcat/telnet/socat can be installed separately\n\n### Multi device connection\nIt is possible to connect several devices to a host simultaneously. Limiting factor is only the bluetooth baseband layer, which uses a Active Member Address (AMA, 3 bit). From these 8 possible values address zero is always occupied by the host, so it can be connected to (up to) 7 devices at the same time.\n\nThere is no special mode, ble-serial can be just started multiple times with different parameters. Following are some tips, showing how to do this in practice.\n\n#### Linux and macOS\nCommon shells (bash, zsh, fish) have a useful background job feature. Add the `-p` (port) option to make sure every instance has a unique path. Also you probably want to redirect the log output to keep it separate. Resulting command lines could look like:\n```terminal\n$ ble-serial -d $ADDR1 -p /tmp/ttyBLE1 2\u003e dev1.log \u0026\n[1] 178378\n\n$ ble-serial -d $ADDR2 -p /tmp/ttyBLE2 2\u003e dev2.log \u0026\n[2] 178397\n```\nThe `\u0026`  at the end causes it to go into background mode immediately, showing the job number and PID. \nNow it is usual control, here are 2 running visible with `jobs` as expected:\n```\n$ jobs                                                     \n[1]  - running   ble-serial -d ... -p /tmp/ttyBLE1 2\u003e dev1.log \u0026\n[2]  + running   ble-serial -d ... -p /tmp/ttyBLE2 2\u003e dev2.log \u0026\n```\nGet them back to foreground with `fg` or view logs live with `tail -f dev1.log` etc.\nOf course you can also put everything into a shell script. \nFor stopping multiple instances you can send signals with `kill -s SIGINT $PID`, this will bring ble-serial to graceful shutdown as well, same as ctrl-c.\n\n#### Windows\nMore com0com port pairs need to be created manually: go to `Program Files (x86)/com0com` and either use command line `setupc.exe` `install` or the graphical `setupg.exe` 'Add pair' button. The PortNames can be chosen arbitrarily at least for the ble-serial side, but I would recommend to use something between COM1-COM9 for the external side, because I noticed many other applications are incompatible with different naming schemes. So use for example BLE2 \u003c\u003e COM8, BLE3 \u003c\u003e COM7 and so on.\n\nDefault cmd has no real background job feature, instead multiple cmd windows or Windows Terminal with tabs can do the trick.\nMake sure to specify the right port for every additional instance, example:\n```\n[Window/Tab 1]\n\u003e ble-serial -d ... -p BLE\n```\n```\n[Window/Tab 2]\n\u003e ble-serial -d ... -p BLE2\n```\n```\n[Window/Tab 3]\n\u003e ble-serial -d ... -p BLE3\n```\n\n### Automated connections\nThe repo [`helper/`](https://github.com/Jakeler/ble-serial/tree/master/helper) directory contains a `ble-autoconnect.py` script:\n```console\n$ python helper/ble-autoconnect.py -h\nusage: ble-autoconnect.py [-h] [-c CONFIG] [-v]\n\nService to automatically connect with devices that get available.\n\noptions:\n  -h, --help            show this help message and exit\n  -c CONFIG, --config CONFIG\n                        Path to a INI file with device configs (default: autoconnect.ini)\n  -v, --verbose         Increase log level from info to debug (default: False)\n  -m MIN_RSSI, --min-rssi MIN_RSSI\n                        Ignore devices with weaker signal strength (default: -127)\n  -t TIMEOUT, --timeout TIMEOUT\n                        Pause scan for seconds amount to let ble-serial start up (default: 10)\n```\nThis continuously scans for devices and compares them with the configuration, \nthen automatically starts up `ble-serial` (or other tools) if a known device is detected.\nBrings similar convenience as USB adapters, just turn the BLE device on and the serial port shows up on the PC. \nSee the example `autoconnect.ini` for configuration. \n\nStarting with version 3.0 it can connect to multiple devices in parallel, make sure there are no port conflicts described [above](#multi-device-connection).\nOutput from the managing script and all instances are printed to the same terminal in this case. It's possible to add a instance specific prefix to each log line\nwith `--name GAP_NAME` and in .ini `name = your-name-here`.\n\nExample launch:\n```console\n[AUTOCONNECT] 2024-12-09 16:35:02,922 | INFO | 20:91:48:4C:4C:54 = UT61E -  JK (RSSI: -76) Services=['0000ffe0-0000-1000-8000-00805f9b34fb', '0000b000-0000-1000-8000-00805f9b34fb']\n[AUTOCONNECT] 2024-12-09 16:35:02,922 | INFO | Found 20:91:48:4C:4C:54 in config!\n[AUTOCONNECT] 2024-12-09 16:35:02,922 | INFO | ['ble-serial', '--dev', '20:91:48:4C:4C:54', '--address-type', 'public', '--port', '/tmp/UT61E', '--name', 'your-name-here', '--timeout', '10', '--mtu', '20']\n[your-name-here] 16:35:02.993 | INFO | linux_pty.py: Port endpoint created on /tmp/UT61E -\u003e /dev/pts/6\n[your-name-here] 16:35:02.993 | INFO | ble_client.py: Receiver set up\n[your-name-here] 16:35:04.252 | INFO | ble_client.py: Trying to connect with 20:91:48:4C:4C:54: UT61E -  JK\n[your-name-here] 16:35:05.922 | INFO | ble_client.py: Device 20:91:48:4C:4C:54 connected\n...\n```\n\nOn Linux you can also use the included systemd (user) service to auto start this on boot.\n\n### Usage as library\nble-serial is primarily designed for command line usage. Nonetheless it is possible to import modules of it into another python application. See the\n[`examples/`](https://github.com/Jakeler/ble-serial/tree/master/examples) dir for how to use the ble parts directly.\n\n## Troubleshooting\nFirst you can use `-v` to increase the log verbosity to DEBUG:\n```console\n18:31:25.136 | DEBUG | ble_interface.py: Received notify from 17: bytearray(b'\\xb0\\xb0\\xb0\\xb0\\xb0\\xb0;\\xb0\\xb0\\xb0\\xba\\xb0\\r\\x8a')\n18:31:25.136 | DEBUG | linux_pty.py: Write: bytearray(b'\\xb0\\xb0\\xb0\\xb0\\xb0\\xb0;\\xb0\\xb0\\xb0\\xba\\xb0\\r\\x8a')\n\n18:31:25.373 | DEBUG | linux_pty.py: Read: b'hello world'\n18:31:25.373 | DEBUG | ble_interface.py: Sending b'hello world'\n```\nThis will log all traffic going through. Note that everything shows up two times, because it goes through the ble module and then into the serial port and vice versa.\nIt also helps with figuring out how characteristics are selected:\n```console\n14:32:47.589 | DEBUG | ble_interface.py: No write uuid specified, trying builtin list\n14:32:47.589 | DEBUG | ble_interface.py: Characteristic candidates for write: \n        0000ffe1-0000-1000-8000-00805f9b34fb (Handle: 17): Vendor specific ['read', 'write-without-response', 'notify']\n14:32:47.589 | INFO | ble_interface.py: Found write characteristic 0000ffe1-0000-1000-8000-00805f9b34fb (H. 17)\n14:32:47.589 | DEBUG | ble_interface.py: No notify uuid specified, trying builtin list\n14:32:47.589 | DEBUG | ble_interface.py: Characteristic candidates for notify: \n        0000ffe1-0000-1000-8000-00805f9b34fb (Handle: 17): Vendor specific ['read', 'write-without-response', 'notify']\n14:32:47.589 | INFO | ble_interface.py: Found notify characteristic 0000ffe1-0000-1000-8000-00805f9b34fb (H. 17)\n```\nAlways try the verbose option if something is not working properly.\n\nIf this is not enough use the double verbose `-vv` flag. It activates debug logging also for the underlying [bleak](https://github.com/hbldh/bleak) module and shows interactions with the bluetooth stack more detailed.\nCheck out the [issue tracker](https://github.com/hbldh/bleak/issues) there too, it is often helpful for problems not directly caused by ble-serial. \n\n## Known limitations\n* Chromium 73+ based applications, including NW.js/electron desktop apps. Connection to the virtual serial port (pty) fails. This is because of explicit whitelisting in chromium. \nTCP might be an alternative (see above), for example in Betaflight Configurator with Manual selection and `tcp://IP:PORT` url as port.\n\n* Certain baud/chipset/firmware configurations can have significant packet loss, see my [benchmark blog post](https://blog.ja-ke.tech/2021/04/22/ble-serial-2.html#performance) with the HM-10 module. Consider other protocols if the application requires constant high bandwidth, short bursts of data are usually fine though.\n\n## Closing remarks\nIf you encounter unexpected problems, please use the [issue tracker](https://github.com/Jakeler/ble-serial/issues). For general questions there is also the discussions tab.\nAs always, I hope it was helpful, if you like it then I would appreciate if you could star it on [GitHub](https://github.com/Jakeler/ble-serial). \n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakeler%2Fble-serial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjakeler%2Fble-serial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjakeler%2Fble-serial/lists"}