Go Bluetooth

repository·dev·Indexed 20 days ago

https://github.com/tinygo-org/bluetooth

A cross-platform Go package for Bluetooth Low Energy (BLE) supporting BLE Central and Peripheral roles. It works on desktop operating systems (Linux via BlueZ, macOS via CoreBluetooth, and Windows via WinRT) as well as microcontrollers via TinyGo, including Nordic Semiconductor (SoftDevice), ESP32 (NINA-FW), and CYW43439 (RP2040-W).

Tokens
10.9K
Snippets
47
Records
52
Agent score
75%

What's inside tinygo-org/bluetooth

  1. Overview of Go Bluetooth

    dev

    Go Bluetooth is a cross-platform package for interacting with Bluetooth Low Energy (BLE) hardware using the Go programming language. It supports both BLE Central roles (e.g., a laptop or phone scanning for devices) and BLE Peripheral roles (e.g., a sensor advertising its presence).

    It is compatible with:

    • Operating Systems: Linux (via BlueZ), macOS (via CoreBluetooth), and Windows (via WinRT).
    • Microcontrollers: Nordic Semiconductor (via SoftDevice) and boards using a Bluetooth Host Controller Interface (HCI) like ESP32 (NINA-FW) or CYW43439 (RP2040-W).
  2. Important: API Stability Warning

    dev

    The Go Bluetooth API is not stable. Many features are unimplemented, and desktop support (Windows/macOS) is incomplete.

    Recommendation: If you require stability, pin your project to a specific git commit using Go modules.

    Expected future changes include:

    • Scan method options (e.g., UUID filtering).
    • Enable function options (e.g., requesting specific connection counts).
    • Implementation of Scan filters, Bonding, and Private addresses.
  3. Use ESP32 (NINA) with Go Bluetooth

    dev

    Go Bluetooth supports boards with an ESP32 Bluetooth Low Energy radio co-processor, provided the ESP32 is running the Arduino or Adafruit nina_fw firmware.

    Supported boards include:

    • Adafruit Metro M4 AirLift
    • Adafruit PyBadge (with AirLift WiFi FeatherWing)
    • Adafruit PyPortal
    • Arduino Nano 33 IoT
    • Arduino Nano RP2040 Connect

    Example for Arduino Nano RP2040 Connect:

    tinygo flash -target nano-rp2040 ./examples/heartrate
  4. Flash SoftDevice on other Nordic boards using nrfjprog

    dev

    If your board is not listed as having pre-loaded firmware, you may need to flash the SoftDevice manually using nrfjprog (part of nRF Command Line Tools).

    1. Erase flash and program the SoftDevice:
      nrfjprog -f nrf52 --eraseall
      nrfjprog -f nrf52 --program path/to/softdevice.hex
    2. Flash your TinyGo program immediately after (do not reset the board):
      tinygo flash -target=pca10040-s132v6 ./examples/heartrate
    nrfjprog -f nrf52 --eraseall
    nrfjprog -f nrf52 --program path/to/softdevice.hex
    tinygo flash -target=pca10040-s132v6 ./examples/heartrate
  5. Flash BBC micro:bit (Version 2)

    dev

    BBC micro:bit v2 uses an nRF52833 chip and requires OpenOCD. You can use it as a peripheral (S113 SoftDevice) or as both central and peripheral (S140 SoftDevice).

    Using S113 (Peripheral only)

    1. Flash SoftDevice (example for Linux):
      cd bluetooth
      cp ./s113_nrf52_7.0.1/s113_nrf52_7.0.1_softdevice.hex /media/yourusername/MICROBIT/
    2. Flash TinyGo program (do not reset power between steps):
      tinygo flash -target=microbit-v2-s113v7 -programmer=cmsis-dap ./examples/heartrate
    
    ### Using S140 (Central and Peripheral)
    1. Flash SoftDevice (example for Linux):
       ```bash
       cd bluetooth
       cp ./s140_nrf52_7.3.0/s140_nrf52_7.3.0_softdevice.hex /media/yourusername/MICROBIT/
    1. Flash TinyGo program (do not reset power between steps):
      tinygo flash -target=microbit-v2-s140v7 -programmer=cmsis-dap ./examples/heartrate-monitor
    
    ```bash
    # S113 Example
    cd bluetooth
    cp ./s113_nrf52_7.0.1/s113_nrf52_7.0.1_softdevice.hex /media/yourusername/MICROBIT/
    tinygo flash -target=microbit-v2-s113v7 -programmer=cmsis-dap ./examples/heartrate
    
    # S140 Example
    cd bluetooth
    cp ./s140_nrf52_7.3.0/s140_nrf52_7.3.0_softdevice.hex /media/yourusername/MICROBIT/
    tinygo flash -target=microbit-v2-s140v7 -programmer=cmsis-dap ./examples/heartrate-monitor
  6. Setup and Compile on Linux

    dev

    Linux support uses BlueZ via D-Bus.

    1. Install BlueZ: Ensure you have a recent version (e.g., v5.48+).
      sudo apt update
      sudo apt install bluez
    2. Get the package:
      git clone https://github.com/tinygo-org/bluetooth.git
    3. Compile/Run scanner example:
      cd bluetooth
      go run ./examples/scanner
    sudo apt update
    sudo apt install bluez
    
    git clone https://github.com/tinygo-org/bluetooth.git
    
    cd bluetooth
    go run ./examples/scanner
  7. Install Go Bluetooth for Nordic Semiconductor chips

    dev

    To use Go Bluetooth on Nordic Semiconductor bare metal chips, you must use TinyGo.

    1. Install TinyGo following the instructions at https://tinygo.org/getting-started/.
    2. Clone the Go Bluetooth repository:
      git clone https://github.com/tinygo-org/bluetooth.git
    3. Ensure your chip is running the appropriate Nordic 'SoftDevice' firmware (a binary BLE stack).
    git clone https://github.com/tinygo-org/bluetooth.git
  8. Flash BBC micro:bit (Version 1)

    dev

    BBC micro:bit v1 uses an nRF51 chip and requires OpenOCD to flash. You must manually flash the SoftDevice firmware first by copying the .hex file to the device.

    1. Flash SoftDevice (example for Linux):
      cd bluetooth
      cp ./s110_nrf51_8.0.0/s110_nrf51_8.0.0_softdevice.hex /media/yourusername/MICROBIT/
    2. Flash your TinyGo program:
      tinygo flash -target=microbit-s110v8 ./examples/heartrate
    cd bluetooth
    cp ./s110_nrf51_8.0.0/s110_nrf51_8.0.0_softdevice.hex /media/yourusername/MICROBIT/
    tinygo flash -target=microbit-s110v8 ./examples/heartrate
  9. Use CYW43439 (RP2040-W) with Go Bluetooth

    dev

    Go Bluetooth supports boards with a CYW43439 Bluetooth Low Energy radio co-processor.

    Supported boards:

    • Raspberry Pi Pico RP2040-W
    • Pimoroni Badger2040-W

    Example for Raspberry Pi Pico W:

    tinygo flash -target pico-w ./examples/heartrate
  10. Setup and Compile on Windows

    dev

    Windows support uses WinRT Bluetooth interfaces.

    1. Get the package:
      git clone https://github.com/tinygo-org/bluetooth.git
    2. Compile/Run scanner example:
      cd bluetooth
      go run .\examples\scanner
    git clone https://github.com/tinygo-org/bluetooth.git
    
    cd bluetooth
    go run .\examples\scanner
  11. Setup and Compile on macOS

    dev

    macOS support uses CoreBluetooth and is currently limited to BLE Central functionality only.

    Note: There is no cross-compiler support; you must compile on macOS. You must also have XCode tools installed.

    1. Install XCode tools:
      xcode-select --install
    2. Get the package:
      git clone https://github.com/tinygo-org/bluetooth.git
    3. Compile/Run scanner example:
      cd bluetooth
      go run ./examples/scanner

    Troubleshooting

    If using iTerm2 and encountering an abort: trap error, manually whitelist iTerm2 in: System Settings -> Privacy & Security -> Bluetooth.

    xcode-select --install
    
    git clone https://github.com/tinygo-org/bluetooth.git
    
    cd bluetooth
    go run ./examples/scanner
  12. Parse advertisement data from ScanResult

    dev

    When scanning for devices, the ScanResult provides an AdvertisementPayload interface. This interface allows you to extract structured data from the advertisement packet without manual parsing.

    Note: The data returned by these methods may only remain valid until the next scan event arrives. If you need to use the data outside the scan callback, you must copy it.

    Available methods on AdvertisementPayload:

    • LocalName() string: Returns the device's name.
    • HasServiceUUID(UUID) bool: Checks if a specific UUID is present.
    • ServiceUUIDs() []UUID: Returns all service UUIDs in the payload.
    • Bytes() []byte: Returns the raw advertisement packet (may return nil if structured data is used).
    • ManufacturerData() []ManufacturerDataElement: Returns manufacturer-specific data.
    • ServiceData() []ServiceDataElement: Returns service-specific data.
    // Inside a scan callback
    func onScanResult(result bluetooth.ScanResult) {
        name := result.AdvertisementPayload.LocalName()
        rssi := result.RSSI
        
        for _, data := range result.AdvertisementPayload.ManufacturerData() {
            fmt.Printf("Company: %X, Data: %v\n", data.CompanyID, data.Data)
        }
    }