【问题标题】:using C++ to get data from a LEGO EV3 sensor?使用 C++ 从 LEGO EV3 传感器获取数据?
【发布时间】:2014-06-16 23:06:05
【问题描述】:

我正在尝试使用 C++ 与 LEGO Mindstorms EV3 积木进行通信。我克隆了ev3sources repo,它允许我通过蓝牙来执行此操作 - 例如,启动连接到端口 A 的电机,我们可以这样做:

#include <unistd.h>
#include <fcntl.h>
#include "ev3sources/lms2012/c_com/source/c_com.h"

int main()
{

    // start motor on port A at speed 20
    unsigned const char start_motor[] {12, 0, 0, 0,
        DIRECT_COMMAND_NO_REPLY,
        0, 0,
        opOUTPUT_POWER, LC0(0), LC0(0x01), LC0(20),
        opOUTPUT_START, LC0(0), LC0(0x01)};

    // send above command to EV3 via Bluetooth
    int bt = open("/dev/tty.EV3-SerialPort", O_WRONLY);
    write(bt, start_motor, 14);
    close(bt);
}

但是如何从 EV3 程序块取回数据?例如,假设我想读取连接到端口 1 的任何传感器捕获的数据。基于the repo examples,我知道我需要一些看起来像这样的东西:

#include <unistd.h>
#include <fcntl.h>
#include "ev3sources/lms2012/c_com/source/c_com.h"

int main()
{

    // read sensor on port 1
    unsigned const char read_sensor[] {11, 0, 0, 0,
        DIRECT_COMMAND_REPLY,
        0, 0,
        opINPUT_READ, LC0(0), LC0(0), LC0(0), LC0(0), GV0(0)};

    // send above command to EV3 via Bluetooth
    int bt = open("/dev/tty.EV3-SerialPort", O_WRONLY);
    write(bt, read_sensor, 13);
    close(bt);
}

但是缺少一些东西 - 上面的 sn-p 没有返回任何错误,但我不知道传感器数据在哪里。那么,我该如何找回呢?我想它也是通过蓝牙发回的,但我该如何捕捉呢?

(OS X 10.9.3,Xcode 5.1.1,EV3 [31313])

【问题讨论】:

标签: c++ lego mindstorms


【解决方案1】:

写完后需要从bt读。就像你发送的数据一样,前两个字节是大小,所以先读取 2 个字节,然后用它来计算你还需要读取多少字节。

#define MAX_READ_SIZE 255
unsigned char read_data[MAX_READ_SIZE];
int read_data_size;

// existing code
// ...
write(bt, read_sensor, 13);
read(bt, read_data, 2);
read_size = read_data[0] + read_data[1] << 8;
read(bt, read_data, read_size);
close(bt);
// decode the data
// ...

编辑:基于 cmets 的完整代码

#include <unistd.h>
#include <fcntl.h>
#include "ev3sources/lms2012/c_com/source/c_com.h"

#define MAX_READ_SIZE 255

int main()
{
    unsigned char read_data[MAX_READ_SIZE];
    int read_data_size;

    // read sensor on port 1
    unsigned const char read_sensor[] {11, 0, 0, 0,
        DIRECT_COMMAND_REPLY,
        1, 0, // 1 global variable
        opINPUT_READ, LC0(0), LC0(0), LC0(0), LC0(0), GV0(0)};

    // send above command to EV3 via Bluetooth
    int bt = open("/dev/tty.EV3-SerialPort", O_RDWR);
    write(bt, read_sensor, 13);
    read(bt, read_data, 2);
    read_size = read_data[0] + read_data[1] << 8;
    read(bt, read_data, read_size);
    close(bt);
    // TODO: check that command was successful and so something with data
}

【讨论】:

  • 谢谢!唉,不知何故,这总是导致read_size 为零。当我检查read_data[0]read_data[1] 时,它们似乎也总是为零(假设printf("%x", read_data[i]); 是检查它们的正确方法;我也尝试了cout &lt;&lt; hex &lt;&lt; read_data[i];,但这会产生一个问号而不是有效输出) .我认为问题可能是 EV3 发回数据时出现了一些延迟,但在 write 和第一个 read 之间插入 usleep(10000000); 并没有改变任何东西。有什么想法吗?
  • read 应该阻塞直到有数据,所以不需要延迟。尝试阅读前 2 个字节,看看是否有什么有趣的东西。您可以检查read 的返回值,以确保它确实在读取内容。
  • 刚刚做了;所有其他字节也为零。 read 返回-1,所以我认为没有被读取。颜色传感器和接近传感器我都试过了,都是一样的。我不知道我做错了什么。
  • 等等,我是个白痴!我忘记将O_WRONLY 更改为O_RDWR。现在可以了!
  • 将该字节设为 5(小端序)``` unsigned const char read_sensor[] {11, 0, 0, 0, DIRECT_COMMAND_REPLY, 1, 0, opINPUT_READ, LC0(0), LC0(0 ), LC0(0), LC0(0), GV0(0)}; ```
【解决方案2】:

也许不完全是您正在寻找的答案,但可能对发现自己处于相同情况的人有用:

作为c4ev3 的一部分,我们开源了EV3 uploader,它也可用于向设备发送与连接无关的命令。

查看https://github.com/c4ev3/ev3duder/blob/master/moveEv3.pl 的示例。

这样做的好处是,您的代码不必担心连接方法:无论是通过蓝牙、Wi-Fi 还是 USB 实现连接,对您来说都是完全透明的。您只需打开 2 个到 ./ev3duder tunnel 的管道并使用它们。

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2021-05-15
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    相关资源
    最近更新 更多