EV3 上的蓝牙
Bluetooth on the EV3
在我开始之前。是的,我可以使用 leJOS、ev3dev 或其他一些工具,但我想这样做,因为这就是我学习的方式。
我正在使用 CodeSourcery arm-2009q1 arm 工具链。我从这里获取了所需的库(蓝牙):https://github.com/mindboards/ev3sources。
我正在使用此工具将程序上传到 brick:https://github.com/c4ev3/ev3duder
我也获取了 brick 的共享库,但我无法使它们正常工作,并且关于如何使用共享库为 ev3 编写 c 程序的文档为 0。如果我能做到这一点,我也许可以使用 c_com 模块来处理蓝牙,但现在 bluez 和 rfcomm 结合: https://github.com/c4ev3/EV3-API 用于电机和传感器控制似乎是我最好的选择。
现在,让开这个:
我想 运行 EV3 作为蓝牙 "server" 意味着我在它上面启动一个程序,程序打开一个套接字,绑定它,侦听连接,然后接受单个连接。
我能够打开一个套接字,将它绑定到通道 1 以外的任何东西(我相信这可能是我问题的症结所在),我能够倾听。这些都是 return 0(OK),一切都很好。
然后我尝试接受连接。即刻 returns -1 并将遥控器设置为地址 00:00:00:00:00:00.
我的代码与在此处找到的代码几乎相同:https://people.csail.mit.edu/albert/bluez-intro/x502.html
这里是:
#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 上运行。
我明白了。
在我的 raspberry PI 上,accept 调用按预期工作,没有任何异常。然而,在 EV3 上,accept 调用是非阻塞的,即使它没有被告知要这样做。
解决方案是将接受调用置于循环中,直到传入连接进入队列。
while (errno == EAGAIN && ButtonIsUp(BTNEXIT) && client < 0)
client = accept(sock, (struct sockaddr*)&rem_addr, sizeof(rem_addr));
我会将代码上传到 github。如果您想对 EV3 进行类似操作,请与我联系。
在我开始之前。是的,我可以使用 leJOS、ev3dev 或其他一些工具,但我想这样做,因为这就是我学习的方式。
我正在使用 CodeSourcery arm-2009q1 arm 工具链。我从这里获取了所需的库(蓝牙):https://github.com/mindboards/ev3sources。 我正在使用此工具将程序上传到 brick:https://github.com/c4ev3/ev3duder
我也获取了 brick 的共享库,但我无法使它们正常工作,并且关于如何使用共享库为 ev3 编写 c 程序的文档为 0。如果我能做到这一点,我也许可以使用 c_com 模块来处理蓝牙,但现在 bluez 和 rfcomm 结合: https://github.com/c4ev3/EV3-API 用于电机和传感器控制似乎是我最好的选择。
现在,让开这个: 我想 运行 EV3 作为蓝牙 "server" 意味着我在它上面启动一个程序,程序打开一个套接字,绑定它,侦听连接,然后接受单个连接。 我能够打开一个套接字,将它绑定到通道 1 以外的任何东西(我相信这可能是我问题的症结所在),我能够倾听。这些都是 return 0(OK),一切都很好。
然后我尝试接受连接。即刻 returns -1 并将遥控器设置为地址 00:00:00:00:00:00.
我的代码与在此处找到的代码几乎相同:https://people.csail.mit.edu/albert/bluez-intro/x502.html
这里是:
#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 上运行。
我明白了。 在我的 raspberry PI 上,accept 调用按预期工作,没有任何异常。然而,在 EV3 上,accept 调用是非阻塞的,即使它没有被告知要这样做。 解决方案是将接受调用置于循环中,直到传入连接进入队列。
while (errno == EAGAIN && ButtonIsUp(BTNEXIT) && client < 0)
client = accept(sock, (struct sockaddr*)&rem_addr, sizeof(rem_addr));
我会将代码上传到 github。如果您想对 EV3 进行类似操作,请与我联系。