Bluetooth на EV3 - PullRequest
       55

Bluetooth на EV3

2 голосов
/ 10 октября 2019

Прежде чем я начну. Да, я мог бы использовать leJOS, ev3dev или некоторые другие, но я бы хотел сделать это так, потому что так я учусь.

Я использую набор инструментов CodeSourcery arm-2009q1 arm. Я выбрал необходимые библиотеки (Bluetooth) отсюда: https://github.com/mindboards/ev3sources. Я загружаю программы в кирпич с помощью этого инструмента: https://github.com/c4ev3/ev3duder

Я также получил общие библиотеки кирпича, но яне может заставить их работать должным образом, и есть 0 документов о том, как написать программу ac для ev3 с использованием разделяемых библиотек. Если бы я мог заставить это работать, я мог бы использовать модуль c_com для обработки bluetooth, но сейчас bluez и rfcomm в сочетании с: https://github.com/c4ev3/EV3-API для управления двигателем и датчиком, кажется, моя лучшая ставка.

Теперь, с этим по-другому: я бы хотел запустить EV3 в качестве bluetooth-«сервера», что означает, что я запускаю на нем программу, и программа открывает сокет, связывает его, прослушивает соединение изатем принимает одно соединение. Я могу открыть сокет, связать его с чем угодно, кроме канала 1 (я считаю, что это может быть суть моей проблемы), я могу слушать. Все они возвращают 0 (ОК) и все в порядке.

Затем я пытаюсь принять соединение. Это мгновенно возвращает -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;
}

Я могу получить тот же код, работающий на моем пи. Даже общение назад и вперед, когда функции, специфичные для ev3api, закомментированы. Я просто не могу понять, почему он не работает на EV3.

1 Ответ

0 голосов
/ 10 октября 2019

Я понял это. На моем малиновом PI вызов на прием работал, как и ожидалось, без излишеств. На EV3, однако, вызов приема не блокируется, даже если ему не было сказано действовать так. Решением было поместить цикл приема в цикл до тех пор, пока входящее соединение не окажется в очереди.

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

Я загружу код в github. Свяжитесь со мной, если вы хотите сделать что-то подобное с EV3.

...