Я пытаюсь использовать C ++ для связи с кирпичом LEGO Mindstorms EV3. Я клонировал ev3sources репо, что позволяет мне делать это через Bluetooth — например, чтобы запустить двигатель, подключенный к порту 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. На основе примеры репо Я знаю, что мне нужно что-то похожее на это:
#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);
}
Но чего-то не хватает — приведенный выше фрагмент не возвращает никаких ошибок, но я не знаю, где находятся данные датчика. Итак, как мне его получить? Я полагаю, что это также отправляется через Bluetooth, но как мне это перехватить?
(OS X 10.9.3, Xcode 5.1.1, EV3 [31313])
Вам нужно прочитать из 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
// ...
РЕДАКТИРОВАТЬ: полный код на основе комментариев
#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
}
Возможно, это не совсем тот ответ, который вы искали, но он может оказаться полезным для того, кто оказался в такой же ситуации:
Как часть c4ev3, Мы с открытым исходным кодом наши EV3 загрузчик, который также может использоваться для отправки на устройство команд, не зависящих от соединения.
проверять, выписываться https://github.com/c4ev3/ev3duder/blob/master/moveEv3.pl для примера.
Хорошая вещь в этом заключается в том, что вашему коду не нужно беспокоиться о способе подключения: независимо от того, реализовано ли подключение через Bluetooth, Wi-Fi или USB, вам абсолютно прозрачно. Вы просто открываете 2 трубы ./ev3duder tunnel
и использовать их.