繁体   English   中英

Raspberry Pi蓝牙-发送数据

[英]Raspberry pi bluetooth - send data

在发布此内容之前,我曾尝试寻找一种简单的程序来使用BLE与rapsberry pi发送任何类型的数据。 但更详细地讲,我知道有些BLE库支持在RPi上使用Python进行编程。 我是python网络编程的新手,正在寻找教程。 每个教程都涉及如何使用BLE连接RPi和某种手机,但没有显示如何制作py脚本来发送一些传感器数据或类似的东西。 请指导。

请参阅以下材料,该材料是从我在该主题上创建的SO文档条目中复制的。

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

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

对于Python,您可以使用以下两个库之一:

您可以在这里找到第二篇的详尽教程。 它是针对特定的蓝牙硬件而设计的,但它足以使您开始使用BLE。


开放的L2CAP插座实现低能耗通信

在C中,与Bluez

 int get_l2cap_connection () {

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

    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的套接字,而不是原始套接字),并且协议是蓝牙协议L2CAP( BTPROTO_L2CAP )。

    ssock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);

我们要确保它成功:

    if (ssock < 0) {
        perror("Opening L2CAP socket failed");
        return -1;
    }

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

    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(可以省略):

    setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));

接下来,我们必须将套接字与我们刚刚定义的源地址结构绑定。 再次,我们检查返回值以确保其有效。

    result = bind(ssock, (struct sockaddr*) &src_addr, sizeof(src_addr));
    if (result < 0) {
        perror("Binding L2CAP socket failed");
        return -1;
    }

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

    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;
    }

现在我们可以告诉内核我们的袜子是一个被动套接字,它将接受连接。 第二个参数是积压。 如果您想了解更多信息,listen的联机帮助页包含您需要的所有信息。

    result = listen(ssock, 10);
    if (result < 0) {
        perror("Listening on L2CAP socket failed");
        return -1;
    }

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

    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函数将蓝牙地址转换为字符串。

    printf("Accepted connection from %s", batostr(&peer_addr->l2_bdaddr));

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

    close(ssock);
    return csock;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM