使用Golang实现蓝牙通信的完整指南

使用Golang实现蓝牙通信的完整指南 大家好,

我是Go语言的新手(几周时间,做过几个项目——其中一些使用了fyne.io),现在又遇到了另一个难题。我是法国人(我知道,人无完人)。

我能看懂英文,但对我来说并不总是那么容易。同样,我的英文表达肯定也不是很好。

我有一个使用Arduino和HC06蓝牙适配器的项目。这个项目目前运行正常。

我用Android(使用App Inventor)制作了一个发送信息的应用程序。

我想把这个应用程序移植到Go语言上,以便在Linux和Windows上运行(甚至可能包括Android)。 但我不确定哪个库最适合我,以及如何在Go代码中发送消息(一个字符串或只是一个字符)。

我看到了Tinygo包(https://pkg.go.dev/tinygo.org/x/bluetooth)。使用它时,我不明白如何进行蓝牙通信。 我测试了扫描器的示例,它可以工作,但之后呢……?

我找不到更多的示例。

如果你能帮助我。

非常感谢。

Jean Pierre。


更多关于使用Golang实现蓝牙通信的完整指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

这听起来是个有趣的项目。我很喜欢tiny-go。当你提到“有某个地方(但看起来我找不到了)有一个示例……”时,你指的是这个心率监测器客户端吗?它看起来像是连接到一个设备并接收数据。

更多关于使用Golang实现蓝牙通信的完整指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好,

感谢您的回答。

这个项目旨在制作一个用于射箭的移动靶。它目前可以工作,但如果我能为PC(Linux和Windows)制作一个遥控器,并且为Android也制作一个(目前Android的遥控器可以工作),也许还能适配Apple设备……因为是用Go(和Fyne)编写的。

我需要更仔细地研究一下心率监测器的示例……并用不同的方式测试。当我第一次看到它时,我没有理解,就像这次第二次阅读一样(而且我还需要多次阅读才能完全理解)。

Jean-Pierre。

嗨,Jean,

这个想法很有趣。我认为你需要了解BLE编程:https://www.bluetooth.com/bluetooth-resources/bluetooth-le-developer-starter-kit/

这个也很有用:https://learn.sparkfun.com/tutorials/bluetooth-basics/all

不过我有些疑问:

  1. 你打算构建一个GUI应用程序吗?
  2. 为什么选择Go?

你好,

感谢你的回复和提供的链接。我会尽快阅读这些内容。

我知道我需要了解更多关于蓝牙的知识,但我个人学习编程语言的方法之一是查看示例并研究不同的信息,以理解实现细节。一步一步来。

我过去是一名程序员,但现在从事教育工作,我为协会或出于兴趣编写代码。

所以,我认为应该存在某个地方(但看起来我找不到)一个包含连接以及少量发送和接收消息的示例。

关于你的问题:

  1. 是的,使用 Fyne.io
  2. 出于几个原因:这门语言符合我的逻辑思维,我可以用它完成许多我需要的事情,支持交叉编译,它是一门编译型语言,用户只需安装一个可执行程序,我不想学习很多不同的语言(目前就是 Go),等等。

使用Golang实现蓝牙通信的完整指南

对于你的蓝牙通信需求,我推荐使用github.com/go-ble/ble库,它支持Linux、macOS和Windows平台。以下是完整的实现示例:

1. 安装必要的库

go get github.com/go-ble/ble
go get github.com/go-ble/ble/examples/lib/dev

2. 扫描蓝牙设备

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/go-ble/ble"
    "github.com/go-ble/ble/examples/lib/dev"
)

func main() {
    d, err := dev.NewDevice("default")
    if err != nil {
        log.Fatalf("无法创建设备: %v", err)
    }
    ble.SetDefaultDevice(d)

    // 扫描蓝牙设备
    ctx := ble.WithSigHandler(context.WithTimeout(context.Background(), 30*time.Second))
    
    fmt.Println("开始扫描蓝牙设备...")
    err = ble.Scan(ctx, true, func(a ble.Advertisement) {
        fmt.Printf("发现设备: %s, 地址: %s, RSSI: %d\n", 
            a.LocalName(), a.Addr(), a.RSSI())
    }, nil)
    
    if err != nil {
        log.Fatalf("扫描失败: %v", err)
    }
}

3. 连接HC-06蓝牙模块并发送数据

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/go-ble/ble"
    "github.com/go-ble/ble/examples/lib/dev"
)

const (
    hc06Address = "00:00:00:00:00:00" // 替换为你的HC-06地址
    serviceUUID = "00001101-0000-1000-8000-00805F9B34FB" // 标准串口服务UUID
)

func main() {
    d, err := dev.NewDevice("default")
    if err != nil {
        log.Fatalf("无法创建设备: %v", err)
    }
    ble.SetDefaultDevice(d)

    // 连接设备
    fmt.Printf("正在连接HC-06: %s\n", hc06Address)
    ctx := ble.WithSigHandler(context.WithTimeout(context.Background(), 30*time.Second))
    
    addr := ble.NewAddr(hc06Address)
    client, err := ble.Dial(ctx, addr)
    if err != nil {
        log.Fatalf("连接失败: %v", err)
    }
    defer client.CancelConnection()

    fmt.Println("连接成功!")

    // 发现服务
    p, err := client.DiscoverProfile(true)
    if err != nil {
        log.Fatalf("发现服务失败: %v", err)
    }

    // 查找串口服务
    var uartService *ble.Service
    for _, s := range p.Services {
        if s.UUID.Equal(ble.MustParse(serviceUUID)) {
            uartService = s
            break
        }
    }

    if uartService == nil {
        log.Fatal("未找到串口服务")
    }

    // 查找特征值(用于发送数据)
    var txCharacteristic *ble.Characteristic
    for _, c := range uartService.Characteristics {
        // 通常TX特征具有以下UUID之一
        if c.UUID.Equal(ble.MustParse("00002a00-0000-1000-8000-00805f9b34fb")) ||
           c.UUID.Equal(ble.MustParse("0000ffe1-0000-1000-8000-00805f9b34fb")) {
            txCharacteristic = c
            break
        }
    }

    if txCharacteristic == nil {
        log.Fatal("未找到发送特征")
    }

    // 发送字符串数据
    message := "Hello from Go!\n"
    fmt.Printf("发送消息: %s", message)
    
    err = client.WriteCharacteristic(txCharacteristic, []byte(message), false)
    if err != nil {
        log.Fatalf("发送失败: %v", err)
    }

    fmt.Println("消息发送成功!")
    
    // 保持连接
    time.Sleep(2 * time.Second)
}

4. 接收数据示例

// 添加接收数据的函数
func receiveData(client ble.Client, rxUUID string) {
    rxCharUUID := ble.MustParse(rxUUID)
    
    // 订阅通知
    err := client.Subscribe(rxCharUUID, false, func(req []byte) {
        fmt.Printf("收到数据: %s\n", string(req))
    })
    
    if err != nil {
        log.Printf("订阅失败: %v", err)
        return
    }
    
    // 持续接收数据
    select {}
}

5. 针对HC-06的简化版本

package main

import (
    "bufio"
    "context"
    "fmt"
    "log"
    "os"
    "time"

    "github.com/go-ble/ble"
    "github.com/go-ble/ble/examples/lib/dev"
)

func main() {
    // 初始化蓝牙适配器
    d, err := dev.NewDevice("default")
    if err != nil {
        log.Fatal(err)
    }
    ble.SetDefaultDevice(d)

    // HC-06蓝牙地址(替换为你的设备地址)
    hc06Addr := "00:00:00:00:00:00"
    
    // 连接设备
    ctx := context.WithTimeout(context.Background(), 30*time.Second)
    client, err := ble.Connect(ctx, ble.NewAddr(hc06Addr))
    if err != nil {
        log.Fatal(err)
    }
    defer client.Clear()

    fmt.Println("已连接到HC-06")
    fmt.Println("输入要发送的消息 (输入'quit'退出):")

    // 交互式发送消息
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        text := scanner.Text()
        if text == "quit" {
            break
        }
        
        // 添加换行符
        message := text + "\n"
        
        // 发送数据(使用HC-06的标准串口服务)
        err := client.WriteCharacteristic(
            ble.NewCharacteristic(ble.MustParse("0000ffe1-0000-1000-8000-00805f9b34fb")),
            []byte(message),
            false,
        )
        
        if err != nil {
            log.Printf("发送失败: %v", err)
        } else {
            fmt.Printf("已发送: %s\n", text)
        }
    }
}

6. Windows系统注意事项

对于Windows系统,需要安装WinBle驱动:

// Windows专用初始化
func initWindows() {
    // Windows需要额外的驱动设置
    // 参考: https://github.com/go-ble/ble/tree/master/examples/lib/dev/windows
}

关键点说明:

  1. HC-06地址:使用Android应用或系统蓝牙设置查找HC-06的MAC地址
  2. UUID:HC-06通常使用标准串口UUID(00001101-0000-1000-8000-00805F9B34FB)
  3. 权限:Linux系统需要蓝牙权限(将用户加入bluetooth组)
  4. 配对:确保HC-06已与计算机配对

这个实现可以让你在Linux和Windows上与HC-06蓝牙模块进行通信,发送字符串或字符数据。

回到顶部