среда, 16 марта 2016 г.

Соединяем EV3 и Arduino по Bluetooth



В наших предыдущих проектах, таких как "EV3 Bluetooth - гитара" и "Электроскрипка из LEGO EV3" мы использовали Bluetooth для передачи данных с EV3 на Arduino.

 


Если вы смотрели код нашей EV3 Bluetooth гитары, то видели как это было реализовано - мы не вдавались особо в тонкости Bluetooth протокола EV3. Пакет данных обрамлялся маркерами и отправлялся, на приемной стороне мы отбрасывали служебную информацию, заголовок пакета и из его тела извлекали строку, обрамленную маркерами. Такой способ передачи работает только в одну сторону, он довольно громоздкий и неудобный.

Мы долго ждали, пока кто-нибудь не напишет библиотеку для Arduino, позволяющую этой платформе полноценно взаимодействовать с EV3, но так и не дождались, поэтому решили написать такой инструмент сами. Надеемся он будет полезен Mindstorms-сообществу и пригодится в ваших проектах. 

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

Например, передавая текст "text" в удаленный слот с именем text вы отправите по Bluetooth последовательно 11000100819E05746578740005007465787400, а отправляя число -3,14 в слот с именем Numeric отправите 13000100819E084E756D65726963000400C3F548C0. Непонятно, правда? 

Чтобы не иметь дело с длинными  строками цифр мы публикуем ряд функций для Arduino, используя которые вы сможете общаться с вашим EV3. Мы не оформляли их в виде библиотеки, так как писали их в общем-то для собственных нужд.


Первым делом вы должны "спарить" ваш EV3 и Bluetooth-модуль, подключенный к Arduino и узнать имя модуля на стороне Arduino. Ваш EV3 не будет знать, что общается не с себе подобным, а с кучей микросхем и проводов, притворяющихся другим EV3. Это здорово, потому что общаться с Arduino вы  сможете из любого языка программирования для платформы EV3, который умеет работать с Bluetooth, будь то EV3-G, EV3 Basic или RobotC.

Например, на языке EV3-G код, который будет отправлять данные на Arduino будет выглядеть так:


Первый синий блок устанавливет соединение в Arduino-Bluetooth-модулем, в нем важно указать корректное имя модуля, которое вы ухнали при "спаривании". В данном примере мы отправляем логическое значение "Истина" в майл-слот с именем Status по нажатию кнопки, подключенной в первому порту.

Принимает данные с Arduino вот такая конструкция, Важно указать тип принимаемых данных и имя майл-слота.


Давайте смотреть скачанный по ссылке выше код.

Функция AskForEV3Message() опрашивает приемный буфер на предмет пакета данных, присланных с EV3. при их наличии она разбирает пакет и записывает в переменную in_message_type единицу, если пришло логическое значение, 2 - для числа и 3 - для текста. Если сообщения не было - в переменной будет 0. В случае наличия сообщения в переменную in_mailbox запишется имя слота, а в одну из переменных in_value_logic, in_value_numeric или in_value_chars - принятое значение, в зависимости от его типа в in_message_type.

Таким образом в программе вы можете использовать функцию приема данных AskForEV3Message()  с EV3 например таким образом:

AskForEV3Message();
if (in_message_type != 0) Serial.println(in_mailbox);
if (in_message_type == 1) Serial.println(in_value_logic);
if (in_message_type == 2) Serial.println(in_value_numeric);
if (in_message_type == 3) Serial.println(in_value_chars);

Смотрим дальше, теперь давайте отправим данные на удаленный EV3 из вашей Arduino-программы. Вы можете использовать три функция MakeLogicEV3Message, MakeNumericEV3Message и MakeTextEV3Message для отправки данных соответствующих типов, пример:

// отправляем в EV3-слот TestLogic истину
MakeLogicEV3Message("TestLogic", true);

// отправляем в в EV3-слот MyNumeric случайное число от 0 до 100
MakeNumericEV3Message("MyNumeric", (int)random(100));

// отправляем в в EV3-слот EV3Text строку "text_example"
MakeTextEV3Message("EV3Text", "text_example");

Давайте договоримся, что вы откроете код вашего будущего проекта также, как мы делаем это для вас. Удачи!

6 комментариев:

  1. Hi I have some question
    How to make a message to EV3
    I know that this code MakeTextEV3Message("EV3Text", "text_example"); has do almost everything
    But I don't know how can I actully send the message (Because the message has two terms:message title and message content)
    How to send a message including both of them by using the code

    ОтветитьУдалить
    Ответы
    1. In EV3-G there are also two lines in the receiving code. The bluetooth text-receiving unit contains a header (the slot in which data is expected to be received, "EV3Text" in example) and the text itself that is received in this slot, "text_example" in example.

      Удалить
    2. Thank you for replying

      I fill in the message title(EV3Text) in EV3 side and run the program,the program is following the guide.
      But no message display on the EV3 screen
      Do I miss something I need in the code of Arduino side?I noticed that the making message function have no bluetooth transporting description.Or I have to make by myself.If so,how?

      Удалить
    3. Check for the side of Arduino pins and speed
      SoftwareSerial mySerial(10, 11); // RX, TX
      mySerial.begin(38400);
      Check for the side of EV3 name of bluetooth module, ьust be specified in the block that establishes the connection.
      Make sure that the connection generally occurs (Led on BT-module).

      Удалить
    4. Thank you for replying

      I checked the Arduino pin and baud rate(I tried 9600,19200,38400 and 57600).
      The BT module can connect to EV3.The BT module can also receive the message from EV3.
      The BT module can send message to my phone so I guess the BT module is OK,sending and receiving.
      The program of EV3 is follwing the guide.The message title and message type is corresponding to the Arduino side.
      But I still cannot make the message to EV3.Does the code of Arduino can send message to EV3 without changing anything?
      Maybe I should add something like:

      mySerial.write(....); so I can send the message to EV3.I don't know.

      I tried so many ways but I still stuck in the problem:(

      Удалить
    5. Yes, you need to send the first out_message_length elements of the array out_message [] to the myserial.

      Удалить

Самое популярное