首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >树莓派蓝牙-发送数据

树莓派蓝牙-发送数据
EN

Stack Overflow用户
提问于 2016-08-02 21:52:48
回答 1查看 16.2K关注 0票数 3

在张贴这篇文章之前,我试着寻找简单的程序来发送任何类型的数据使用BLE与rapsberry pi。但我得到了更多的细节,我知道有一些BLE库支持在RPi上使用Python编程。我是python网络编程的新手,我正在寻找教程。每一篇教程都是关于如何使用BLE.They连接RPi和某种类型的电话,而不是演示如何编写py脚本来发送一些传感器数据或诸如此类的东西。请指点一下。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-03 04:19:43

请参阅下面的材料,这些材料是从我为该主题创建的SO文档条目复制而来的。

最后,您基本上拥有了一个类似TCP的套接字,您可以通过它发送任何数据。但我建议您使用ATT和GATT协议(参见蓝牙规范)。所有的BLE设备都应该使用这些协议,但如果发送器和接收器都是由您编写的,您可以使用自己的协议,也许更简单。

这不是特定于RPi的,不需要这样做,因为几乎每个Linux发行版都使用相同的蓝牙协议栈,称为Bluez。您需要使用libbluetooth-dev包来开发您自己的应用程序。

对于Python,您可以使用以下任一库:

您可以找到第二个here的扩展教程。它是为特定的蓝牙硬件制作的,但它应该足以让你使用BLE。

用于低能耗通信的开放L2CAP插座

在C中,使用Bluez

代码语言:javascript
复制
 int get_l2cap_connection () {

首先,我们需要的所有变量和解释都将在适当的位置进行。

代码语言:javascript
复制
    int ssock = 0;
    int csock = 0;
    int reuse_addr = 1;
    struct sockaddr_l2 src_addr;
    struct bt_security bt_sec;
    int result = 0;

首先,我们需要创建一个套接字,我们可以接受来自该套接字的连接。套接字系列是PF_BLUETOOTH,套接字类型是SOCK_SEQPACKET (我们希望有一个类似TCP的套接字,而不是raw),协议是蓝牙协议L2CAP (BTPROTO_L2CAP)。

代码语言:javascript
复制
    ssock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);

我们希望确保它是成功的:

代码语言:javascript
复制
    if (ssock < 0) {
        perror("Opening L2CAP socket failed");
        return -1;
    }

我们现在必须用通配符地址填充源地址结构,这样具有任何地址的任何蓝牙设备都可以连接到我们。通配符地址在bluetooth.h中定义为BDADDR_ANY。要将其复制到地址结构中,我们可以使用bacpy函数。我们还必须设置地址族、地址类型和通道ID。

代码语言:javascript
复制
    memset(&src_addr, 0, sizeof(src_addr));
    bacpy(&src_addr.l2_bdaddr, BDADDR_ANY);
    src_addr.l2_family = AF_BLUETOOTH;
    src_addr.l2_bdaddr_type = BDADDR_LE_PUBLIC;
    src_addr.l2_cid = htobs(CID_ATT);

设置SO_REUSEADDR选项将允许我们在必要时再次快速调用bind (这可以省略):

代码语言:javascript
复制
    setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));

接下来,我们必须将套接字与我们刚刚定义的源地址结构绑定在一起。同样,我们检查返回值以确保它工作。

代码语言:javascript
复制
    result = bind(ssock, (struct sockaddr*) &src_addr, sizeof(src_addr));
    if (result < 0) {
        perror("Binding L2CAP socket failed");
        return -1;
    }

下一步是设置安全级别。请注意,此步骤是可选的,但将安全级别设置为“中”将允许与设备自动配对(实际配对由内核处理)。

代码语言:javascript
复制
    memset(&bt_sec, 0, sizeof(bt_sec));
    bt_sec.level = BT_SECURITY_MEDIUM;
    result = setsockopt(ssock, SOL_BLUETOOTH, BT_SECURITY, &bt_sec, sizeof(bt_sec));
    if (result != 0) {
        perrorno("Setting L2CAP security level failed");
        return -1;
    }

现在我们可以告诉内核我们的ssock是一个被动套接字,它将接受一个连接。第二个参数是backlog。如果你想了解更多,listen的manpage包含了你需要的所有信息。

代码语言:javascript
复制
    result = listen(ssock, 10);
    if (result < 0) {
        perror("Listening on L2CAP socket failed");
        return -1;
    }

现在我们可以等待传入的连接。一旦accept返回,peer_addr结构将包含所连接设备的地址。csock将是套接字的文件描述符,我们可以对其进行读写,以便与连接的设备进行通信。

代码语言:javascript
复制
    memset(peer_addr, 0, sizeof(*peer_addr));
    socklen_t addrlen = sizeof(*peer_addr);
    csock = accept(ssock, (struct sockaddr*)peer_addr, &addrlen);
    if (csock < 0) {
        perror("Accepting connection on L2CAP socket failed");
        return -1;
    }

我们可以打印连接设备的地址(当然是可选的)。我们可以使用batostr函数将蓝牙地址转换为字符串。

代码语言:javascript
复制
    printf("Accepted connection from %s", batostr(&peer_addr->l2_bdaddr));

如果我们不希望任何其他设备连接,我们应该关闭服务器插座。在完成与设备的通信后,对csock执行相同的操作。

代码语言:javascript
复制
    close(ssock);
    return csock;
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38722417

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档