EV3上的蓝牙

时间:2019-10-09 21:27:57

标签: c sockets bluetooth lego ev3

开始之前。是的,我可以使用leJOS,ev3dev或其他一些工具,但是我想这样做,因为那是我的学习方法。

我正在使用CodeSourcery arm-2009q1 arm工具链。我从此处获取了所需的库(蓝牙):{{​​3}}。 我正在使用以下工具将程序上传到模块:https://github.com/mindboards/ev3sources

我也已经获取了Brick的共享库,但是我无法使它们正常工作,关于如何使用共享库为ev3编写c程序的文档有0个。如果可以解决问题,我也许可以使用c_com模块来处理蓝牙,但是现在bluez和rfcomm结合:https://github.com/c4ev3/ev3duder用于电机和传感器控制似乎是我最好的选择。

现在,不用担心了: 我想将EV3作为蓝牙“服务器”运行,这意味着我在其上启动了一个程序,该程序打开了一个套接字,将其绑定,侦听连接,然后接受单个连接。 我能够打开套接字,将其绑定到通道1以外的任何东西(我相信这可能是我的问题的症结所在),我能够听。这些都返回0(确定),一切都很好。

然后,我尝试接受连接。立即返回-1,并将遥控器设置为地址00:00:00:00:00:00。

我的代码与此处的代码几乎相同:https://github.com/c4ev3/EV3-API

这里是:

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include <ev3.h>

int main(int argc, char **argv)
{
    InitEV3();
    struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
    char buf[1024] = { 0 };
    int sock, client, bytes_read;
    socklen_t opt = sizeof(rem_addr);

    sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);

    loc_addr.rc_family = AF_BLUETOOTH;
    loc_addr.rc_bdaddr = *BDADDR_ANY;
    loc_addr.rc_channel = 2; // <-- Anything but 1. 1 seems to be taken
    bind(sock, (struct sockaddr *)&loc_addr, sizeof(loc_addr));

    listen(sock, 1);

    // accept one connection <-- PROGRAM FAILS HERE AS accept() returns -1
    client = accept(sock, (struct sockaddr *)&rem_addr, &opt);

    // ---- All following code is irrelevant because accept fails ----

    ba2str( &rem_addr.rc_bdaddr, buf );
    fprintf(stderr, "accepted connection from %s\n", buf);
    memset(buf, 0, sizeof(buf));

    bytes_read = read(client, buf, sizeof(buf));
    if( bytes_read > 0 )
        printf("received [%s]\n", buf);

    close(client);
    close(sock);

    FreeEV3();
    return 0;
}

我能够在pi上获得相同的代码。注释掉ev3api特定功能时,甚至来回通信。我只是无法理解为什么它不能在EV3上运行。

1 个答案:

答案 0 :(得分:0)

我知道了。 在我的树莓派PI上,accept调用工作正常,没有任何怪癖。但是,在EV3上,accept调用是非阻塞的,即使没有被告知要这样做。 解决方案是将accept调用置于循环中,直到传入连接进入队列。

while (errno == EAGAIN && ButtonIsUp(BTNEXIT) && client < 0)
    client = accept(sock, (struct sockaddr*)&rem_addr, sizeof(rem_addr));

我将代码上传到github。如果您想对EV3做类似的事情,请与我联系。