Отправка данных с Arduino через последовательный порт bluetooth

В настоящее время я пытаюсь разработать контроллер, который мог бы связываться через Bluetooth с телефоном Android (Galaxy Nexus). Я столкнулся с несколькими проблемами. Кроме того, у меня нет большого практического опыта программирования.

В основе контроллера находится микроконтроллер Arduino, который сканирует состояние 8 цифровых контактов и шести аналоговых контактов (10 бит) и отправляет данные через последовательный порт на микросхему Bluetooth HC-05. Затем телефон Android должен прочитать последовательную информацию, отправленную через Bluetooth, и либо передать пакет на другой телефон - это займет у меня некоторое время, чтобы реализовать, поскольку я очень мало знаю, как работает Интернет, - либо проанализировать и интерпретировать ее для дальнейших действий. взятый

Я прошу понять, как лучше всего это сделать. Что значит «лучше всего»? Мы хотим, чтобы это происходило в режиме реального времени, чтобы, когда я нажимаю кнопку или комбинацию нижних частей, бум, телефон Android начинает действовать достаточно быстро, чтобы человек не заметил задержки.

Затем я хочу связать информацию, которую телефон считывает в последовательном буфере, с соответствующей кнопкой или аналоговым контактом. В случае ошибки или во избежание рассинхронизации

Вот что у меня есть на данный момент. Я еще не тестировал этот код, отчасти потому, что я все еще учусь программировать часть этого проекта для Android, отчасти потому, что мне нужна обратная связь о том, веду ли я себя глупо или это действительно эффективный способ сделать это:

//Initialization
/*

This Program has three functions:
1) Scan 8 digital pins and compile their state in a single byte ( 8 bits)
2) Scans 6 Analogue inputs corresponding to the joysticks and triggers 
3) Send this info as packets through seril --> Bluetooth 

*/
#include <SoftwareSerial.h>// import the serial software library

#define A = 2
#define B = 3
#define X = 4
#define Y = 5
#define LB = 6
#define RB = 7
#define LJ = 8
#define RJ = 9
#define RX = 10
#define TX = 11
//Pin 12 and 13 are unused for now
SoftwareSerial Bluetooth(RX,TX); //Setup software serial using the defined constants
// declare other variables
byte state = B00000000

void setup() {
  //Setup code here, to run once:
  //Setup all digital pin inputs
  pinMode(A,INPUT);
  pinMode(B,INPUT);
  pinMode(X,INPUT);
  pinMode(Y,INPUT);
  pinMode(LB,INPUT);
  pinMode(RB,INPUT);
  pinMode(LJ,INPUT);
  pinMode(RJ,INPUT);
  //Setup all analogue pin inputs
  //setup serial bus and send validation message
  Bluetooth.begin(9600);
  Bluetooth.println("The controller has successfuly connected to the phone")
}

void loop() {
  //Main code here, to run repeatedly: 
  //Loop to sum digital inputs in a byte, left shift the byte every time by 1 and add that if the pin is high
  for(byte pin = 2, b = B00000001;  pin < 10; pin++, b = b << 1){ if (digitalRead(pin)== HIGH) state += b; }
  //Send digital state byte to serial
  Bluetooth.write(state);
  //Loop to read analgue pin 0 to 5 and send it to serial
  for( int pin = 0, testByte = 0x8000; pin < 6 ; pin++, testByte = testByte >> 1) { Bluetooth.write(analogRead(pin)+testByte); }
}

//Adding some validation would be wise. How would I go about doing that?
// Could add a binary value of 1000_0000_0000_0000,  0100_0000_0000_0000,  0010_0000_0000_0000 ... so on and then use a simple AND statement at the other end to veryfy what analogue reading the info came from
// so say the value for analgue is 1023 and came from analgue pin 1 I would have 0100_0011_1111_1111 now using an bitwise && I could check it against 0100_0000_0000_0000 if the result is 0100_0000_0000_0000 then I know this is the analogu reading from pin 1
//could easily implement a test loop with a shiting bit on the android side

Разве для меня бессмысленно делать такие битовые смены? В конечном итоге, если я не ошибаюсь, все данные отправляются в байтах (8-битные пакеты), поэтому Bluetooth.write(analogRead(pin)+testByte) действительно отправит два байта или будет усекать int данные? как он будет сломан и как его восстановить на стороне андроида?

Как бы вы это реализовали? Есть идеи или советы?


person Ethienne    schedule 06.02.2014    source источник


Ответы (3)


Здорово, что ты этому учишься! Некоторые предложения:

Ваш код будет легче читать, понимать и поддерживать, если вы немного расширите его, в частности, добавив новые строки ...

void loop() {
  //Main code here, to run repeatedly: 
  //Loop to sum digital inputs in a byte, 
  //left shift the byte every time by 1 and add that  if the pin is high
  for( byte pin = 2, b = B00000001;  pin < 10; pin++, b = b << 1) {
    if (digitalRead(pin)== HIGH)
      state += b;
  }
  //Send digital state byte to serial
  Bluetooth.write(state);
  //Loop to read analgue pin 0 to 5 and send it to serial
  for( int pin = 0, testByte = 0x8000; pin < 6 ; pin++, testByte = testByte >> 1) {
    Bluetooth.write(analogRead(pin)+testByte); 
  }
}

Кроме того, вы можете использовать операторы сдвига со значениями, отличными от единицы. поэтому вместо сохранения маски сдвига, которую вы затем добавляете, вы просто используете простую переменную. Более классический способ сделать то, что вы выражаете в первом цикле, будет примерно таким:

#define PIN_OFFSET 2
  for ( int i=0; i < 8; i++) {
    if (digitalRead( i+PIN_OFFSET)== HIGH)
      state += (1 << i);
  }

Второй цикл можно сделать аналогично:

  for( int pin = 0; pin < 6; pin++) {
    short testByte = 0x8000 >> pin;
    short result =  analogRead(pin) + testByte;
    Bluetooth.write( result >> 8); 
    Bluetooth.write( result & 0xFF); 
  }

Обратите внимание, что вызов Bluetooth.write () отправляет байт, поэтому этот код отправляет сначала старший, а затем наименьший байт.

Наконец, вы, вероятно, захотите обнулить свою переменную состояния в начале цикла () - иначе, как только бит установлен, он никогда не будет очищен.

Вы можете подумать о том, что вы отправляете на телефон. Это будут двоичные данные, и с ними может быть сложно справиться - как узнать начало и конец, и часто значение будет неверно истолковано как управляющий символ, что сильно вас испортит. Рассмотрите возможность преобразования его в форматированную, удобочитаемую строку с новой строкой в ​​конце.

Надеюсь, это поможет.

person bobwki    schedule 07.02.2014
comment
Спасибо за советы и поддержку @bobwki! Я обязательно буду иметь это в виду. Хорошо, поэтому вы предлагаете мне отправить более отформатированную строку, читаемую человеком. Будет ли вычисление этого достаточно быстрым, чтобы происходить в реальном времени? Это действительно моя единственная проблема и причина, по которой я стараюсь быть действительно эффективным с объемом данных, которые я отправляю и обрабатываю. - person Ethienne; 08.02.2014
comment
Не уверен в проблеме эффективности. Другой подход - закодировать результаты, чтобы, по крайней мере, это были печатные символы, чтобы избежать проблем с контрольным кодом. Также обратите внимание, что вы не можете предполагать, что Bluetooth сможет принимать символы так же быстро, как вы их отправляете. Он будет буферизовать символы и отправлять их как можно лучше. В зависимости от того, как работает интерфейс (я не смотрел), он может отбрасывать символы, которые не может отправить, или он будет выполнять какое-то управление потоком - и то, и другое может не подходить для того, что вы хотите сделать. - person bobwki; 09.02.2014

Конец Arduino этого более чем достаточно быстр, чтобы делать то, что вы хотите, и вам не нужно ни в малейшей степени беспокоиться о минимизации количества байтов, которые вы отправляете с микроконтроллера на телефон, когда вы говорите о таком крошечном количестве. данных. Мне не совсем понятно, что вы отправляете на телефон; вам нужно другое значение для каждой кнопки, поэтому при нажатии кнопки она отправляет что-то вроде:

Кнопка была нажата, номер кнопки (два байта)

А если это аналоговое значение:

Чтение аналогового значения, старший бит аналогового значения, младший бит аналогового значения (предполагается, что аналоговое значение больше восьми битов).

Я не знаю, какой код Arduino вы используете, но подозреваю, что эта строка:

Bluetooth.write (analogRead (контакт) + testByte)

Отправит один байт, который является добавлением аналогового значения и любого значения testByte.

Не могли бы вы опубликовать ссылку на документацию по этому API?

Любая задержка со всем этим будет по телефону. Пожалуйста, не беспокойтесь о попытках сохранить пару байт на конце Arduino! (В настоящее время я работаю над проектом с Cortex M3, отправляющим данные через модуль Bluetooth на телефоны Android, и мы отправляем несколько k данных. Из этого опыта я знаю, что разница между двумя и двадцатью байтами не имеет значения с точки зрения задержки.)

person DiBosco    schedule 10.02.2014
comment
Хорошо, спасибо, приятно знать, что тогда мне не нужно беспокоиться о скорости! И тогда мне бы не понадобился тестовый байт, если бы у меня была нажата кнопка, отправленная раньше. API можно найти на веб-сайте arduino. arduino.cc/en/Reference/HomePage#.UxLULfldVjQ - person Ethienne; 02.03.2014

Возможно, вам будет полезно выбрать готовые приложения для терминала Bluetooth для вашего телефона Android. В Google Play есть несколько приложений: 1) https://play.google.com/store/apps/details?id=arduino.bluetooth.terminal&hl=en 2) https://play.google.com/store/apps/details?id=com.sena.bterm&hl=en (доступно еще несколько в Google play). Это поможет вам сосредоточиться только на разработке стороны контроллера.

person SunGa    schedule 07.02.2014
comment
Спасибо за предложение. Я уже загрузил терминал, чтобы проверить, работает ли мой модуль blutooth или нет. Тем не менее, приложение-терминал бессмысленно, поскольку все, что они делают, это отображают данные, отправленные через терминал. Если я хочу обработать эти данные, мне нужно будет изменить их код или написать приложение с нуля. В обоих случаях мне нужно изучить андроид часть вещей. Что меня полностью устраивает! вся цель этого проекта - дать мне хороший повод приложить усилия, чтобы чему-то научиться. знак равно - person Ethienne; 08.02.2014