### Flash TinyGo Bluetooth Examples to Microcontrollers Source: https://context7.com/tinygo-org/bluetooth/llms.txt Provides common `tinygo flash` commands for deploying Bluetooth examples to various Adafruit, Arduino, Raspberry Pi, and Seeed Studio microcontroller boards. It includes examples for specific targets and SoftDevice versions, as well as a command to build firmware without flashing. ```bash # Adafruit Circuit Playground Bluefruit (nRF52840 with pre-loaded SoftDevice) tinygo flash -target circuitplay-bluefruit ./examples/heartrate # Adafruit Feather nRF52840 Express tinygo flash -target feather-nrf52840 ./examples/battery # Arduino Nano 33 IoT (ESP32 NINA co-processor) tinygo flash -target nano-33-iot ./examples/scanner # Arduino Nano RP2040 Connect (ESP32 NINA co-processor) tinygo flash -target nano-rp2040 ./examples/heartrate # Raspberry Pi Pico W (CYW43439 co-processor) tinygo flash -target pico-w ./examples/heartrate # BBC micro:bit v2 with S140 SoftDevice (central + peripheral support) # First flash SoftDevice: cp ./s140_nrf52_7.3.0/s140_nrf52_7.3.0_softdevice.hex /media/user/MICROBIT/ tinygo flash -target microbit-v2-s140v7 -programmer=cmsis-dap ./examples/heartrate-monitor # Seeed Studio XIAO nRF52840 tinygo flash -target xiao-ble ./examples/heartrate # Build without flashing tinygo build -target pico-w -o firmware.uf2 ./examples/heartrate ``` -------------------------------- ### Flashing TinyGo Bluetooth Example Source: https://github.com/tinygo-org/bluetooth/blob/release/README.md Command to flash the Heart Rate Sensor example using TinyGo. The `-target` flag should be adjusted based on the specific board being used. This command is used after flashing the SoftDevice. ```bash tinygo flash -target=pca10040-s132v6 ./examples/heartrate ``` -------------------------------- ### Compiling and Flashing Arduino Nano RP2040 Connect with TinyGo Source: https://github.com/tinygo-org/bluetooth/blob/release/README.md Command to compile and flash an Arduino Nano RP2040 Connect board with a BLE peripheral example using TinyGo. This utilizes the pre-loaded nina-fw firmware on the ESP32 co-processor. ```bash tinygo flash -target nano-rp2040 ./examples/heartrate ``` -------------------------------- ### Compiling and Flashing Raspberry Pi Pico RP2040-W with TinyGo Source: https://github.com/tinygo-org/bluetooth/blob/release/README.md Command to compile and flash a Raspberry Pi Pico RP2040-W board with a BLE peripheral example using TinyGo. This leverages the CYW43439 Bluetooth Low Energy radio co-processor. ```bash tinygo flash -target pico-w ./examples/heartrate ``` -------------------------------- ### Nordic UART Service (NUS) Server Echo Example in Go Source: https://context7.com/tinygo-org/bluetooth/llms.txt Implements a BLE server using the Nordic UART Service (NUS) that echoes received data back to the client. It configures the adapter, sets up advertisements, and defines RX/TX characteristics for bidirectional communication. Requires the `tinygo.org/x/bluetooth` package. ```go package main import ( "tinygo.org/x/bluetooth" ) var ( serviceUUID = bluetooth.ServiceUUIDNordicUART rxUUID = bluetooth.CharacteristicUUIDUARTRX txUUID = bluetooth.CharacteristicUUIDUARTTX ) func main() { adapter := bluetooth.DefaultAdapter must("enable BLE stack", adapter.Enable()) adv := adapter.DefaultAdvertisement() must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "NUS Server", ServiceUUIDs: []bluetooth.UUID{serviceUUID}, })) must("start adv", adv.Start()) var rxChar bluetooth.Characteristic var txChar bluetooth.Characteristic must("add service", adapter.AddService(&bluetooth.Service{ UUID: serviceUUID, Characteristics: []bluetooth.CharacteristicConfig{ { // RX Characteristic - receives data from central Handle: &rxChar, UUID: rxUUID, Flags: bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission, WriteEvent: func(client bluetooth.Connection, offset int, value []byte) { println("Received:", string(value)) // Echo back via TX characteristic txChar.Write(value) }, }, { // TX Characteristic - sends data to central Handle: &txChar, UUID: txUUID, Flags: bluetooth.CharacteristicNotifyPermission | bluetooth.CharacteristicReadPermission, }, }, })) println("NUS Server running...") select {} } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Create BLE Peripheral Advertisement in Go Source: https://context7.com/tinygo-org/bluetooth/llms.txt Configures and starts a BLE advertisement for a peripheral device. It sets options like local name, service UUIDs, manufacturer data, and service data. This requires the 'tinygo.org/x/bluetooth' package and assumes the BLE stack is enabled. ```go package main import ( "context" "time" "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { must("enable BLE stack", adapter.Enable()) // Set up connection handler ctx, cancel := context.WithCancel(context.Background()) adapter.SetConnectHandler(func(device bluetooth.Device, connected bool) { if connected { println("device connected:", device.Address.String()) } else { println("device disconnected:", device.Address.String()) cancel() } }) // Configure advertisement adv := adapter.DefaultAdvertisement() must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "Go Bluetooth", ServiceUUIDs: []bluetooth.UUID{ bluetooth.ServiceUUIDBattery, }, // Include manufacturer-specific data ManufacturerData: []bluetooth.ManufacturerDataElement{ {CompanyID: 0xFFFF, Data: []byte{0x01, 0x02}}, // 0xFFFF for testing }, // Include service data ServiceData: []bluetooth.ServiceDataElement{ {UUID: bluetooth.ServiceUUIDBattery, Data: []byte{75}}, // 75% battery }, })) // Start advertising must("start adv", adv.Start()) defer adv.Stop() println("advertising...") address, _ := adapter.Address() for { select { case <-time.After(time.Second): println("Go Bluetooth /", address.MAC.String()) case <-ctx.Done(): return } } } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Scan for Bluetooth Low Energy Peripherals using Go Source: https://github.com/tinygo-org/bluetooth/blob/release/README.md This Go code demonstrates how to configure and use the Bluetooth adapter to scan for nearby BLE peripheral devices. It prints the address, RSSI, and local name of discovered devices. Ensure the BLE interface is enabled before starting the scan. ```go package main import ( "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { // Enable BLE interface. must("enable BLE stack", adapter.Enable()) // Start scanning. println("scanning...") err := adapter.Scan(func(adapter *bluetooth.Adapter, device bluetooth.ScanResult) { println("found device:", device.Address.String(), device.RSSI, device.LocalName()) }) must("start scan", err) } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Read and Write Bluetooth Characteristics Source: https://context7.com/tinygo-org/bluetooth/llms.txt Perform read and write operations on Bluetooth characteristics. Use `Read()` to get the current value, `Write()` for operations requiring a response, and `WriteWithoutResponse()` for faster, fire-and-forget writes. The choice depends on the characteristic's permissions. ```go package main import "tinygo.org/x/bluetooth" func characteristicOperations(char bluetooth.DeviceCharacteristic) { // Read characteristic value buf := make([]byte, 255) n, err := char.Read(buf) if err != nil { println("read error:", err.Error()) return } println("read", n, "bytes:", string(buf[:n])) // Write with response (waits for acknowledgment) // Use this for characteristics with CharacteristicWritePermission _, err = char.Write([]byte{0x01, 0x02, 0x03}) if err != nil { println("write error:", err.Error()) } // Write without response (fire-and-forget, faster) // Use this for characteristics with CharacteristicWriteWithoutResponsePermission _, err = char.WriteWithoutResponse([]byte("hello")) if err != nil { println("write error:", err.Error()) } } ``` -------------------------------- ### Advertise as a Bluetooth Low Energy Peripheral using Go Source: https://github.com/tinygo-org/bluetooth/blob/release/README.md This Go code sets up the device to act as a Bluetooth Low Energy peripheral, advertising its presence with a local name. It configures the advertisement, starts advertising, and waits for a connection or disconnection event. The `context` is used to manage the advertising lifecycle. ```go package main import ( "context" "time" "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { // Enable BLE interface. must("enable BLE stack", adapter.Enable()) ctx, cancel := context.WithCancel(context.Background()) adapter.SetConnectHandler(func(device bluetooth.Device, connected bool) { if connected { println("device connected:", device.Address.String()) return } println("device disconnected:", device.Address.String()) cancel() }) // Define the peripheral device info. adv := adapter.DefaultAdvertisement() must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "Go Bluetooth", })) // Start advertising must("start adv", adv.Start()) // Stop advertising to release resources defer adv.Stop() println("advertising...") <- ctx.Done() } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Handle Characteristic Writes with WriteEvent in TinyGo Bluetooth Source: https://context7.com/tinygo-org/bluetooth/llms.txt This Go code snippet demonstrates how to configure a Bluetooth characteristic with read, write, and write-without-response permissions. It utilizes the `WriteEvent` callback to process incoming data from clients, updating an LED color based on the received byte array. This example requires the TinyGo Bluetooth library. ```go package main import ( "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { must("enable BLE stack", adapter.Enable()) adv := adapter.DefaultAdvertisement() must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "TinyGo LED", })) must("start adv", adv.Start()) // Custom service and characteristic UUIDs serviceUUID := bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3}) charUUID := bluetooth.NewUUID([16]byte{0xa0, 0xb4, 0x00, 0x02, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3}) var ledColor = []byte{0xFF, 0x00, 0x00} // RGB: Red var ledChar bluetooth.Characteristic must("add service", adapter.AddService(&bluetooth.Service{ UUID: serviceUUID, Characteristics: []bluetooth.CharacteristicConfig{ { Handle: &ledChar, UUID: charUUID, Value: ledColor, // Multiple permissions can be combined with | Flags: bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicWritePermission | bluetooth.CharacteristicWriteWithoutResponsePermission, // WriteEvent is called when client writes to this characteristic WriteEvent: func(client bluetooth.Connection, offset int, value []byte) { if offset != 0 || len(value) != 3 { return // Invalid write } // Update LED color ledColor[0] = value[0] // R ledColor[1] = value[1] // G ledColor[2] = value[2] // B println("LED color set to RGB:", value[0], value[1], value[2]) }, }, }, })) println("LED service running...") select {} } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Add GATT Services and Characteristics in Go Source: https://context7.com/tinygo-org/bluetooth/llms.txt Adds GATT services and characteristics to a BLE peripheral. This example registers the Battery Service with a Battery Level characteristic, allowing centrals to read and subscribe to its value. It periodically updates the characteristic's value and notifies subscribers. This function requires the 'tinygo.org/x/bluetooth' package. ```go package main import ( time "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { must("enable BLE stack", adapter.Enable()) // Configure and start advertisement adv := adapter.DefaultAdvertisement() must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "TinyGo Battery", ServiceUUIDs: []bluetooth.UUID{bluetooth.ServiceUUIDBattery}, })) must("start adv", adv.Start()) // Characteristic handle for later use var batteryLevelChar bluetooth.Characteristic // Add Battery Service with Battery Level characteristic must("add service", adapter.AddService(&bluetooth.Service{ UUID: bluetooth.ServiceUUIDBattery, Characteristics: []bluetooth.CharacteristicConfig{ { Handle: &batteryLevelChar, // Store handle for updates UUID: bluetooth.CharacteristicUUIDBatteryLevel, Value: []byte{75}, // Initial value: 75% Flags: bluetooth.CharacteristicReadPermission | bluetooth.CharacteristicNotifyPermission, }, }, })) // Periodically update and notify batteryLevel := byte(75) for { time.Sleep(time.Second) batteryLevel = (batteryLevel + 1) % 101 // Cycle 0-100 // Write updates the value and sends notification to subscribed clients batteryLevelChar.Write([]byte{batteryLevel}) println("Battery level:", batteryLevel, "%") } } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Implement Heart Rate Service Peripheral with Notifications in TinyGo Source: https://context7.com/tinygo-org/bluetooth/llms.txt This Go code implements a standard Heart Rate Service peripheral using TinyGo and its Bluetooth library. It broadcasts heart rate measurements via notifications and includes characteristics for Body Sensor Location and Heart Rate Control Point. The example simulates heart rate variations and sends updates periodically. ```go package main import ( "math/rand" "time" "tinygo.org/x/bluetooth" ) var ( adapter = bluetooth.DefaultAdapter heartRateMeasurement bluetooth.Characteristic heartRate uint8 = 75 ) func main() { must("enable BLE stack", adapter.Enable()) // Advertise Heart Rate Service adv := adapter.DefaultAdvertisement() must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "Go HRS", ServiceUUIDs: []bluetooth.UUID{bluetooth.ServiceUUIDHeartRate}, })) must("start adv", adv.Start()) // Add Heart Rate Service with required characteristics must("add service", adapter.AddService(&bluetooth.Service{ UUID: bluetooth.ServiceUUIDHeartRate, Characteristics: []bluetooth.CharacteristicConfig{ { // Heart Rate Measurement - notify only Handle: &heartRateMeasurement, UUID: bluetooth.CharacteristicUUIDHeartRateMeasurement, Value: []byte{0, heartRate}, // Flags + HR value Flags: bluetooth.CharacteristicNotifyPermission, }, { // Body Sensor Location - read only UUID: bluetooth.CharacteristicUUIDBodySensorLocation, Value: []byte{1}, // 1 = Chest Flags: bluetooth.CharacteristicReadPermission, }, { // Heart Rate Control Point - write only UUID: bluetooth.CharacteristicUUIDHeartRateControlPoint, Value: []byte{0}, Flags: bluetooth.CharacteristicWritePermission, }, }, })) println("Heart Rate Service running...") // Simulate heart rate and send notifications for { time.Sleep(time.Second) // Simulate heart rate variation heartRate = uint8(65 + rand.Intn(20)) // Send notification (Flags=0, Heart Rate Value) heartRateMeasurement.Write([]byte{0, heartRate}) println("Heart rate:", heartRate, "bpm") } } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Initialize Bluetooth Adapter in Go Source: https://context7.com/tinygo-org/bluetooth/llms.txt Initializes the Bluetooth Low Energy (BLE) adapter, which is the main entry point for all Bluetooth operations. This step is mandatory before performing any BLE actions. It also demonstrates how to retrieve the adapter's MAC address. ```go package main import ( "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { // Enable the BLE adapter - required before any BLE operations err := adapter.Enable() if err != nil { panic("failed to enable BLE stack: " + err.Error()) } // Get the adapter's MAC address address, err := adapter.Address() if err != nil { panic("failed to get address: " + err.Error()) } println("Adapter address:", address.MAC.String()) // Output: Adapter address: AA:BB:CC:DD:EE:FF } ``` -------------------------------- ### Flashing SoftDevice Firmware with nrfjprog Source: https://github.com/tinygo-org/bluetooth/blob/release/README.md Commands to erase flash and program SoftDevice firmware onto Nordic Semiconductor chips using the nrfjprog tool. This is necessary for using unsupported boards with TinyGo and the Go Bluetooth package. Ensure the correct SoftDevice path is provided. ```bash nrfjprog -f nrf52 --eraseall nrfjprog -f nrf52 --program path/to/softdevice.hex ``` -------------------------------- ### Configure BLE Connection Parameters in Go Source: https://context7.com/tinygo-org/bluetooth/llms.txt Demonstrates how to create and configure Bluetooth connection parameters using the TinyGo bluetooth package. These parameters control aspects like connection timeout, interval range, and supervision timeout, and can be used during initial connection or for requesting changes on an existing connection. ```go package main import ( time "tinygo.org/x/bluetooth" ) func main() { // Create connection parameters params := bluetooth.ConnectionParams{ // Connection timeout for the connection attempt ConnectionTimeout: bluetooth.NewDuration(10 * time.Second), // Connection interval range (faster = more power, more bandwidth) MinInterval: bluetooth.NewDuration(15 * time.Millisecond), // 15ms minimum MaxInterval: bluetooth.NewDuration(30 * time.Millisecond), // 30ms maximum // Supervision timeout (connection considered lost after this) Timeout: bluetooth.NewDuration(2 * time.Second), } // Use when connecting // device, err := adapter.Connect(address, params) // Or request parameter change on existing connection // err := device.RequestConnectionParams(params) _ = params } ``` -------------------------------- ### UUID Handling Utilities in Go Source: https://context7.com/tinygo-org/bluetooth/llms.txt Demonstrates how to create, parse, and use Bluetooth UUIDs in Go using the `tinygo.org/x/bluetooth` package. It covers creating 16-bit and 128-bit UUIDs, using predefined standard UUIDs, parsing UUIDs from strings, and checking UUID bit length. ```go package main import ( "tinygo.org/x/bluetooth" ) func main() { // Create 16-bit UUID (standard Bluetooth SIG assigned) batteryUUID := bluetooth.New16BitUUID(0x180F) println("Battery UUID:", batteryUUID.String()) // Output: Battery UUID: 0000180f-0000-1000-8000-00805f9b34fb // Use predefined standard UUIDs println("Heart Rate Service:", bluetooth.ServiceUUIDHeartRate.String()) println("Battery Level Char:", bluetooth.CharacteristicUUIDBatteryLevel.String()) // Create custom 128-bit UUID customUUID := bluetooth.NewUUID([16]byte{ 0xa0, 0xb4, 0x00, 0x01, 0x92, 0x6d, 0x4d, 0x61, 0x98, 0xdf, 0x8c, 0x5c, 0x62, 0xee, 0x53, 0xb3, }) println("Custom UUID:", customUUID.String()) // Parse UUID from string parsed, err := bluetooth.ParseUUID("0000180f-0000-1000-8000-00805f9b34fb") if err != nil { panic(err) } println("Parsed UUID:", parsed.String()) // Check if UUID is 16-bit if batteryUUID.Is16Bit() { shortUUID := batteryUUID.Get16Bit() println("16-bit value:", shortUUID) // Output: 6159 (0x180F) } } ``` -------------------------------- ### MAC Address Parsing and Manipulation in Go Source: https://context7.com/tinygo-org/bluetooth/llms.txt Shows how to parse MAC addresses from strings and convert them back to string format using the `tinygo.org/x/bluetooth` package. It also demonstrates retrieving the raw address bytes and managing the random address flag. ```go package main import ( "tinygo.org/x/bluetooth" ) func main() { // Parse MAC address from string mac, err := bluetooth.ParseMAC("AA:BB:CC:DD:EE:FF") if err != nil { panic(err) } // Convert back to string println("MAC:", mac.String()) // Output: MAC: AA:BB:CC:DD:EE:FF // Get address in big-endian format (typical network order) addr := mac.Address() println("Address bytes:", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]) // Output: Address bytes: 170 187 204 221 238 255 // MACAddress wrapper with random address flag macAddr := bluetooth.MACAddress{MAC: mac} macAddr.SetRandom(true) println("Is random:", macAddr.IsRandom()) // Set address from string macAddr.Set("11:22:33:44:55:66") println("New MAC:", macAddr.MAC.String()) } ``` -------------------------------- ### Run Bare Metal Tests with TinyGo Source: https://github.com/tinygo-org/bluetooth/blob/release/CONTRIBUTING.md Executes the smoketest for bare metal environments using TinyGo. This command is used to ensure the Bluetooth module functions correctly in embedded systems. ```bash make smoketest-tinygo ``` -------------------------------- ### Run OS-Specific Tests for Bluetooth Module Source: https://github.com/tinygo-org/bluetooth/blob/release/CONTRIBUTING.md Executes smoketests for the Go Bluetooth module on specific operating systems. This helps verify functionality on Linux, macOS, and Windows. Cross-compilation might have limitations. ```bash make smoketest-linux ``` ```bash make smoketest-macos ``` ```bash make smoketest-windows ``` -------------------------------- ### Discover Bluetooth Services and Characteristics Source: https://context7.com/tinygo-org/bluetooth/llms.txt Discover available GATT services and characteristics on a connected Bluetooth peripheral. You can discover all available services/characteristics by passing nil, or filter by specific UUIDs. This function also demonstrates reading characteristic values and their MTU. ```go package main import ( "strconv" "tinygo.org/x/bluetooth" ) func discoverDevice(device bluetooth.Device) { // Discover all services (pass nil for all, or specific UUIDs) services, err := device.DiscoverServices(nil) must("discover services", err) buf := make([]byte, 255) for _, service := range services { println("Service:", service.UUID().String()) // Discover all characteristics in this service chars, err := service.DiscoverCharacteristics(nil) if err != nil { println(" error:", err.Error()) continue } for _, char := range chars { println(" Characteristic:", char.UUID().String()) // Get the MTU for this characteristic mtu, err := char.GetMTU() if err == nil { println(" MTU:", mtu) } // Read the characteristic value n, err := char.Read(buf) if err != nil { println(" Read error:", err.Error()) } else { println(" Value (", strconv.Itoa(n), "bytes):", string(buf[:n])) } } } } // Discover specific services and characteristics func discoverHeartRate(device bluetooth.Device) { services, err := device.DiscoverServices([]bluetooth.UUID{ bluetooth.ServiceUUIDHeartRate, }) must("discover HR service", err) if len(services) == 0 { panic("Heart Rate service not found") } chars, err := services[0].DiscoverCharacteristics([]bluetooth.UUID{ bluetooth.CharacteristicUUIDHeartRateMeasurement, }) must("discover HR characteristic", err) println("Found Heart Rate characteristic:", chars[0].UUID().String()) } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Connect to a BLE Peripheral Device in Go Source: https://context7.com/tinygo-org/bluetooth/llms.txt Connects to a specific Bluetooth Low Energy (BLE) peripheral device after it has been discovered via scanning. The `Connect` method establishes a connection, returning a `Device` object for further operations like service discovery and characteristic access. Optional connection parameters can be specified. ```go package main import ( "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { must("enable BLE stack", adapter.Enable()) // Scan for a specific device ch := make(chan bluetooth.ScanResult, 1) targetAddress := "EE:74:7D:C9:2A:68" println("scanning for", targetAddress) err := adapter.Scan(func(adapter *bluetooth.Adapter, result bluetooth.ScanResult) { println("found:", result.Address.String()) if result.Address.String() == targetAddress { adapter.StopScan() ch <- result } }) must("scan", err) // Connect to the found device result := <-ch device, err := adapter.Connect(result.Address, bluetooth.ConnectionParams{ // Optional: specify connection timeout (default used if zero) ConnectionTimeout: bluetooth.NewDuration(10 * 1000 * 1000), // 10 seconds }) must("connect", err) println("connected to", result.Address.String()) // ... perform operations with device ... // Disconnect when done err = device.Disconnect() must("disconnect", err) } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Scan for BLE Devices in Go Source: https://context7.com/tinygo-org/bluetooth/llms.txt Continuously scans for nearby Bluetooth Low Energy (BLE) devices using the `Scan` method. A callback function is invoked for each discovered device, providing details like address, RSSI, local name, and service/manufacturer data. The scan can be stopped using `StopScan()`. ```go package main import ( "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { must("enable BLE stack", adapter.Enable()) println("scanning...") err := adapter.Scan(func(adapter *bluetooth.Adapter, result bluetooth.ScanResult) { // Print device information println("found device:", result.Address.String(), result.RSSI, result.LocalName()) // Check for specific service UUID if result.HasServiceUUID(bluetooth.ServiceUUIDHeartRate) { println(" -> Heart Rate sensor found!") adapter.StopScan() } // Access manufacturer data for _, mfg := range result.ManufacturerData() { println(" Manufacturer:", mfg.CompanyID, "Data:", len(mfg.Data), "bytes") } // Access service data for _, svc := range result.ServiceData() { println(" Service:", svc.UUID.String(), "Data:", len(svc.Data), "bytes") } }) must("start scan", err) } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` -------------------------------- ### Enable Bluetooth Notifications Source: https://context7.com/tinygo-org/bluetooth/llms.txt Enable notifications to receive data pushed from a peripheral when a characteristic's value changes. Provide a callback function to process incoming data. Pass nil to the `EnableNotifications` function to disable notifications. ```go package main import ( "tinygo.org/x/bluetooth" ) var adapter = bluetooth.DefaultAdapter func main() { must("enable BLE stack", adapter.Enable()) // ... scan and connect to device ... var device bluetooth.Device // assume connected // Discover Heart Rate service and characteristic services, _ := device.DiscoverServices([]bluetooth.UUID{bluetooth.ServiceUUIDHeartRate}) chars, _ := services[0].DiscoverCharacteristics([]bluetooth.UUID{ bluetooth.CharacteristicUUIDHeartRateMeasurement, }) hrChar := chars[0] // Enable notifications - callback is invoked on each update err := hrChar.EnableNotifications(func(buf []byte) { // Heart rate is in second byte (first byte is flags) if len(buf) >= 2 { heartRate := uint8(buf[1]) println("Heart Rate:", heartRate, "bpm") } }) must("enable notifications", err) println("Listening for heart rate updates...") // Keep running to receive notifications select {} } func must(action string, err error) { if err != nil { panic("failed to " + action + ": " + err.Error()) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.