Bluetooth HC-05 подключение, настройка, программа управления

Smith2007
Offline
Зарегистрирован: 30.10.2017

Дождался посылочки с Блютус модулем hc-05 

Первое подключение к питанию от платы ардуино леонардо. Смартфон сразу обнаружил новое Блютус устройство. Скачал Блютус терминал на смартфон. Законнектиться.

затем решил загрузить простенькую программу. При помощи softwareserial организовал последовательный интерфейс на 2, 3 пине. 

Ввожу на компьютере в терминале символы - они отражаются в терминале смартфона. Передача работает. 

Ввожу символы в терминале смартфона - на терминал компьютера ни чего не приходит. Перечитал множество статей, тем и примеров.

потом поменял номера пинков как ниже в скетче. 

Заработало. Приём и передача идёт в обе стороны. Почему не получилось на других пинках так и не понял. 

Еще не понял как отлаживать приложения с Блютус модулями. Serial хардварный подключён к компу. Не работать же с блютусом через софтверный канал.

 

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8, 9); // 9 подключаем к RX | 8 подключаем к TX

void setup()
{
  Serial.begin(9600);
  Serial.println("Enter AT commands:");
  BTSerial.begin(9600); // HC-05 default speed in AT command more
}

  void loop()
{
   if (BTSerial.available())
   Serial.write(BTSerial.read());
    if (Serial.available())
    BTSerial.write(Serial.read());
}

 

Подскажите пожалуйста как решаете данные вопросы.

спасибо.

Smith2007
Offline
Зарегистрирован: 30.10.2017

И сколько не пытался - перевести модуль в режим приме АТЛАС команд так и не удалось.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

два раза брал BT Модули у разных продавцов на Ali и у каждого перевод в режим AT команд был реализован по разному, если у вас отдельным пином выведено режим АТ - повезло - самый простой вариант

Smith2007
Offline
Зарегистрирован: 30.10.2017

Smith2007
Offline
Зарегистрирован: 30.10.2017

tx, rx уровни 3,3 В

Если подключать к пинам ардуинки на прямую то мне кажется нужно делитель использовать. Хотя бы со стороны tx ардуины.

Или это не принципиально?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Smith2007 пишет:

tx, rx уровни 3,3 В

Если подключать к пинам ардуинки на прямую то мне кажется нужно делитель использовать. Хотя бы со стороны tx ардуины.

Или это не принципиально?

я подключал делитель, ваш в АТ режим переводиться кнопкой, но там есть тонкость (точно не помню поочередность), если на кнопку нажать после подачи питания то переходит в режим АТ команд на скорости 38400, если перед подачей питания - то на скорости установленной АТ командами :)

в интернете поищите описание поподробней

короче я намучился с ним, с первого раза сбросив на дефолтную скорость а потом как то умудриться UNO к нему зацепить на большую чем 9600 скорость (хотя может руки просто у меня кривые).

Smith2007
Offline
Зарегистрирован: 30.10.2017

Подключу сегодня через делитель. 

Правильно понимаю, что достаточно 1 ма снимать с выхода пинка ардуинки? Делитель из резисторов  1,5 и 3,3 кОм подойдёт? 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Smith2007 пишет:

Подключу сегодня через делитель. 

Правильно понимаю, что достаточно 1 ма снимать с выхода пинка ардуинки? Делитель из резисторов  1,5 и 3,3 кОм подойдёт? 

не помню - первый попавшийся запрос в интернете - подключени HC-05 к ардуино - 2КОм на землю 1КОм к TX Arduino

Smith2007
Offline
Зарегистрирован: 30.10.2017

В общем понятно. В Вашем примере ток с выхода ардуинки около 1,5 мА. И напряжение как раз 3,3 В.

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

хотя я пробовал просто соединить выход модуля со входом. Эхо не получил, что довольно странно. Тут то все уровни сигналов нормальные.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

"хозяин - барин" но я не рискую работать с модулями заявленными 3.3 в - через 5 в

Smith2007
Offline
Зарегистрирован: 30.10.2017

 

 

Подключил модуль через делитель

 

 

Работает отлично!

Проверял на расстоянии 10м. 

Следующий эксперимент со входом в режим AT команд

Smith2007
Offline
Зарегистрирован: 30.10.2017

Перевод модуля в режим AT команд.

1. На пин EN подаем 3,3В с платы (если нет 3,3, подаем 5 через делитель 1К и 2К)

2. Отключаем питание с модуля.

3. Нажимаем и удерживаем кнопку на модуле и подаем питание (кнопку удерживаем до тех пор пока светодиод не начнет мигать)

4. Отпускаем кнопку

Если модем перешел в режим АТ команд - светодиод будет мигать с частотой 0,5 Гц.

Список доступных команд на сайте IARDUINO.RU.

Не смотря на то, что все удалось, у меня не сходятся скорости.

Как видно ниже в скетче скорость на порту блютус-модуля установлена 38400 (на других скоростях он отказывался работать). Но если посмотреть АТ команду AT+UART? - модуль дал ответ 9600.

Объяснить пока не могу. Вероятно это сказывается SoftwareSerial интерфейс.

Но как бы ни было - модуль завелся и дал доступ к командному режиму.

Вчера он постоянно глючил я думаю по причине не согласования уровней RX-TX. Модулю нужно 3,3 В, а с ардуинки (TX) идет 5В.

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8, 9); // 9 подключаем к RX | 8 подключаем к TX

void setup()
{
  Serial.begin(9600);
  delay(3000);
  Serial.println("Enter AT commands:");
  //BTSerial.begin(9600); // HC-05 default speed in AT command more
  BTSerial.begin(38400);
}

  void loop()
{
   if (BTSerial.available()) {
     Serial.write(BTSerial.read()); 
   }
   if (Serial.available()) {
     BTSerial.write(Serial.read());
   }
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Я же вам писал что режим ат команд на скорости 38400 включается при определённом режиме нажатия кнопки - вы интернет почитали? Или мне за вас читать?

Smith2007
Offline
Зарегистрирован: 30.10.2017

andycat пишет:
Я же вам писал что режим ат команд на скорости 38400 включается при определённом режиме нажатия кнопки - вы интернет почитали? Или мне за вас читать?

Я прочитал, что при режиме команд модуль переходит на скорость 38400. И я к нему подключился. Странно то, что при подключении скорость показывает 9600. Т.е. в режиме команд он не использует эту настройку и выставляет скорость жестко. Это и смутило. В обычных модемах такого нет. Какую скорость установишь, на той и общаешься.

 

Smith2007
Offline
Зарегистрирован: 30.10.2017

Модифицировал скетч и подключил модуль к аппаратному uart (pins 0,1)

Питание подал от блока питания. usb с ардуинки извлек.

Телефон подключен к блютус модулю, но ни каких пакетов не терминал не приходит.

В чем может быть проблема?

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8, 9); // 9 подключаем к RX | 8 подключаем к TX

void setup()
{
  Serial.begin(9600);
  delay(3000);
  Serial.println("Enter AT commands:");
  BTSerial.begin(9600); // HC-05 default speed in AT command more
  //BTSerial.begin(38400);
}

int count = 0;
  void loop()
{
   //BTSerial.write(count);
   //BTSerial.write("\0x0A\0x0D");
   Serial.println(count);
   delay(3000);
   count++;
}

 

Соединил на модуле TX и RX, подключился к модулю со смартфона. Набираю в терминале любые символы и отправляю их в модуль. Эти же символы возвращаются.

Т.е. сам модуль нормально работает. Похоже, что не получается сопряжение с модулем на пинах 0, 1. Что там на них за особенность такая?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Smith2007 пишет:

andycat пишет:
Я же вам писал что режим ат команд на скорости 38400 включается при определённом режиме нажатия кнопки - вы интернет почитали? Или мне за вас читать?

Я прочитал, что при режиме команд модуль переходит на скорость 38400. И я к нему подключился. Странно то, что при подключении скорость показывает 9600. Т.е. в режиме команд он не использует эту настройку и выставляет скорость жестко. Это и смутило. В обычных модемах такого нет. Какую скорость установишь, на той и общаешься.

 

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

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Smith2007 пишет:

Модифицировал скетч и подключил модуль к аппаратному uart (pins 0,1)

Питание подал от блока питания. usb с ардуинки извлек.

Телефон подключен к блютус модулю, но ни каких пакетов не терминал не приходит.

В чем может быть проблема?

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(8, 9); // 9 подключаем к RX | 8 подключаем к TX

void setup()
{
  Serial.begin(9600);
  delay(3000);
  Serial.println("Enter AT commands:");
  BTSerial.begin(9600); // HC-05 default speed in AT command more
  //BTSerial.begin(38400);
}

int count = 0;
  void loop()
{
   //BTSerial.write(count);
   //BTSerial.write("\0x0A\0x0D");
   Serial.println(count);
   delay(3000);
   count++;
}

 

Соединил на модуле TX и RX, подключился к модулю со смартфона. Набираю в терминале любые символы и отправляю их в модуль. Эти же символы возвращаются.

Т.е. сам модуль нормально работает. Похоже, что не получается сопряжение с модулем на пинах 0, 1. Что там на них за особенность такая?

не очень понятно - что значит возвращается?

и странно как  то вы модуль опрашиваете, вот пример из моей реальной железки:

  // read BT console
  if (BT.available()) {
    while (BT.available()) {
      strCommand += char(BT.read());
      delay(50);
    }
  }
  // exec command
  strCommand.trim();
  if (strCommand.length() > 3) {
    executeCommand();
    strCommand = "";
  }
  // - 

 

Smith2007
Offline
Зарегистрирован: 30.10.2017

Разобрался в проблеме обмена данными при подключении к pin0, pin1.

Все дело в модели ардуинки. Я все подключения делаю на Iskra Neo (Arduino Lepnardo)

Для обращения к пинам 0,1 как к последовательному порту необходимо использовать Serial1. Т.е. на борту 2 serial порта. Один для подключения компа по usb, второй как serial1.

В общем модифицировал скетч и все завелось.

#include <SoftwareSerial.h>
//SoftwareSerial BTSerial(8, 9); // 9 подключаем к RX | 8 подключаем к TX

void setup()
{
  Serial.begin(38400);
  Serial1.begin(38400);
  delay(5000);
  //BTSerial.println("Enter AT commands:");
  Serial.println("Enter AT commands:");
  Serial1.println("Enter AT commands:");
}

int count = 0;

void loop()
{
  Serial1.write(count);
  Serial1.println();
  Serial.println(count);
  count++;
  delay(3000);
}

 

Теперь встал следующий вопрос. HC-05 принимает данные по воздуху, но что бы он передал полученные данные на контроллер - необходимо подать (по воздуху) завершающий символ 0x0D. Без этого или ждать пока буфер не заполнится полностью или пока в теле сообщения не встретиться 0x0D. 

Вопрос: Можно ли это отключить и заставить передавать каждый символ сразу на контроллер? 

Или не стоит этим заниматься, а сразу предусмотреть в кадре завершающий символ?

Smith2007
Offline
Зарегистрирован: 30.10.2017

andycat пишет:

не очень понятно - что значит возвращается?

и странно как  то вы модуль опрашиваете, вот пример из моей реальной железки:

  // read BT console
  if (BT.available()) {
    while (BT.available()) {
      strCommand += char(BT.read());
      delay(50);
    }
  }
  // exec command
  strCommand.trim();
  if (strCommand.length() > 3) {
    executeCommand();
    strCommand = "";
  }
  // - 

 

"Возвращаются" - это значит, что любой символ прилетевший по воздуху, по воздуху же и отправляется обратно отправителю.

Замкнув на hc-05 tx и  rx мы получаем пертлю (выход соединили со входом).  Это работает.

И что такого нового в Вашем скетче я не понимаю. Чтение символа принятого от hc-05 (который в свою очередь принял символ по воздуху)  и дальнейшая его обработка.

У меня все тоже.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

объясните мне пожалуйста тупому стройки с 18 по 20ю в 17 сообщении?

записываем с сериал и сериал 1 данные а чтение то где?

 

Smith2007
Offline
Зарегистрирован: 30.10.2017

andycat пишет:

объясните мне пожалуйста тупому стройки с 18 по 20ю в 17 сообщении?

записываем с сериал и сериал 1 данные а чтение то где?

 

в 11 сообщении передача между интерфейсами. В 17 просто вывожу значение count. Я понимаю как передавать и принимать. Проблема была в обращении к порту. Я пытался использовать serial, а нужно было serial1 

Smith2007
Offline
Зарегистрирован: 30.10.2017

Помогите разобраться со следующим вопрос....

модуль соединён с другим устройством по Блютус.

модуль подключён к serial порту на скорости 38400.

Если я передаю в сериал порт массив байт в цикле loop 

вопрос: 

В цикле loop передача байт в драйвер сериал порта происходит за очень короткое время. Скорость передачи высокая. Но сам порт настроен на Скорость 38400. Т.е. Данные в драйвер будут поступать быстрее чем уходить в линию связи. Что будет с данными? Будет потеря? Потеря какой части буфера? 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Не следует передавать в буфер больше данных, чем он способен вместить.

Smith2007
Offline
Зарегистрирован: 30.10.2017

andriano пишет:

Не следует передавать в буфер больше данных, чем он способен вместить.

а как определить, что он уже заполнен?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Если аппаратный сериал то судя по реализации write и комментариям внутри будите крутить в вайле пока место в буфере не появится.

// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit

size_t HardwareSerial::write(uint8_t c)
{
  _written = true;
  // If the buffer and the data register is empty, just write the byte
  // to the data register and be done. This shortcut helps
  // significantly improve the effective datarate at high (>
  // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
  if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
    *_udr = c;
    sbi(*_ucsra, TXC0);
    return 1;
  }
  tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;
	
  // If the output buffer is full, there's nothing for it other than to 
  // wait for the interrupt handler to empty it a bit
  while (i == _tx_buffer_tail) {
    if (bit_is_clear(SREG, SREG_I)) {
      // Interrupts are disabled, so we'll have to poll the data
      // register empty flag ourselves. If it is set, pretend an
      // interrupt has happened and call the handler to free up
      // space for us.
      if(bit_is_set(*_ucsra, UDRE0))
	_tx_udr_empty_irq();
    } else {
      // nop, the interrupt handler will free up space for us
    }
  }

  _tx_buffer[_tx_buffer_head] = c;
  _tx_buffer_head = i;
	
  sbi(*_ucsrb, UDRIE0);
  
  return 1;
} 

 

Smith2007
Offline
Зарегистрирован: 30.10.2017

Serial аппаратный. 

Получается если отправить serial.write большой массив байт, то эта процедура остановит программу до тех пор пока последний байт не уйдёт в буфер. Это логично.

А как узнать размер буфера? 

 

В программе делаю 5 последовательных вызовов serial.write с записью буферов по 12 байт.  Этот порт подключён к Блютус модулю he-05.

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

ввел задержку между вызовами serial.write на 200мс - заработало. Но как-то сильно смущает такая задержка.

ощущение, что чего-то не понимаю и поэтому возникает эта проблема.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Все же есть, смотрите исходники HardwareSerial

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif 

Не знаю что у вас за железо, но думаю что 64 байта буфер должен быть.

Может вы куда-то по прерываниям уходите и не досылаете или что-то наоборот с приемом на телефоне.

Smith2007
Offline
Зарегистрирован: 30.10.2017

По прерыванию одно действие
Val++
Не может оно много времени занять.
На смарте просто вывожу буфер приема.

sadman41
Offline
Зарегистрирован: 19.10.2016

По симптомам - затыки в БТ модуле. 

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

Smith2007
Offline
Зарегистрирован: 30.10.2017

Как реализована передача в эфир и буферизация в блютус модуле?
Допускаю, что это у него происходит переполнение. Хотя очень странно. Скорость serial - bluetooth 38400 бод. Скорость передачи в эфире вроде существенно выше.
Где же затык?

sadman41
Offline
Зарегистрирован: 19.10.2016

А вот тут начинается самое интересное. Берете документацию на протокол, изучаете, потом на модуль и тоже изучаете. А затем начинаете гадать - что накрутили китайцы в прошивке конкретного БТ.

 

Smith2007
Offline
Зарегистрирован: 30.10.2017

Не очень обнадеживающе :)
Учитывая уровень моих познаний... Может заняль неприличное время.
Попробовать скорость снизить до 9600 и проверить....
Но вообще то думал поднять до 115200

Smith2007
Offline
Зарегистрирован: 30.10.2017

Глючит форум

Temik007
Offline
Зарегистрирован: 24.12.2017

Smith2007 пишет:
Не очень обнадеживающе :) Учитывая уровень моих познаний... Может заняль неприличное время. Попробовать скорость снизить до 9600 и проверить.... Но вообще то думал поднять до 115200

Не смог пройти мимо, сам боролся с таким модулем.

У меня работает так: arduino nano + hc05, подключено на 0 и 1 пины, скорость порта выставлена абсолютно везде 115200, то есть в arduino ide, конфиг прошивки, бутлоадер оптибут, в блютуз модуле.

Таким образом имею: беспроводной serial, читаю и отправляю данные + отправляю новый скетч на заливку по воздуху, ожидаю в arduino ide надписи "Загрузка..." и жму reset на ардуинке.

Один существенный минус (помимо необходимости нажатия reset) - если в новом скетче будет другая скорость порта, то всё идёт крахом, восстановить можно только отключив блютуз модуль и прошив через кабель.

kraiv
Offline
Зарегистрирован: 02.12.2015

To Smith2007

Разобрались? У меня похожая проблема, две ардуины общаются по блютуз (hc05), команды в один байт, доходят не все, иногда теряются, иногда накапливается несколько и отрабатывают одна за другой. 

Smith2007
Offline
Зарегистрирован: 30.10.2017

kraiv пишет:

To Smith2007

Разобрались? У меня похожая проблема, две ардуины общаются по блютуз (hc05), команды в один байт, доходят не все, иногда теряются, иногда накапливается несколько и отрабатывают одна за другой. 

 

Я решил вопрос следующим образом:

1. Увеличил скорость serial порта до 115200. Не уверен, но вроде как можно и выше установить но не проверял.

2. Пакеты с командами отправляются и принимаются нормально но...

если команды (команда = 12 байт) отправлять слишком часто - то опять теряются. Пришлось ввести паузу в 50 мс перед отправкой следующей команды.

Теперь не отправляю все команды сразу. После каждой команды задержка 50 мс. Меньше не проверял. Можно наверное подобрать меньшее значение задержки, но меня 50 мс устроило и я оставил так

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Вероятная причина потери данных - переполнение буфера.

При скорости 9600 один байт данных отправляется чуть дольше 1 мс. Соответственно, если интервал ме\жду пакетами будет менее 12-15 мс, то буфер будет заполняться быстрее, чем опустошаться. Отсюда и переполнение.

Думаю, для 115200 достатоно ждать 2 мс.

Smith2007
Offline
Зарегистрирован: 30.10.2017

При очередных модификациях попробую уменьшить до 2 мс

kraiv
Offline
Зарегистрирован: 02.12.2015

Благодарю, попробую, но честно говоря сомневаюсь, у меня передается просто нажатие кнопок, при этом отправляеся цифра от 1 до 5 и все... это с какой скоростью я нажимаю на кнопки, что бы переполнить буфер... монстр какой-то :)  Но задержку ввести попробую, спасибо.

CtFelix
Offline
Зарегистрирован: 06.09.2018

Добрый день,

Товарищи, подскажите пожалуйста,

Есть HC 05, настроен как мастер, при запуске подключается к телефону, можно ли как-то на ардуине отловить момент, что соединение с телефоном активно и скажем включить светодиод?

Второй вопрос, если первый вариант возможен, то можно ли как-то заставить HC 05 постоянно пытаться соедениться с телефоном? И если в радиусе появился телефон включить светодиод?

hugoboss317
Offline
Зарегистрирован: 21.03.2013

CtFelix пишет:

Добрый день,

Товарищи, подскажите пожалуйста,

Есть HC 05, настроен как мастер, при запуске подключается к телефону, можно ли как-то на ардуине отловить момент, что соединение с телефоном активно и скажем включить светодиод?

Второй вопрос, если первый вариант возможен, то можно ли как-то заставить HC 05 постоянно пытаться соедениться с телефоном? И если в радиусе появился телефон включить светодиод?

Зашёл с вопросом, но, хоть уже наверное не актуально, всёж отвечу.

В момент и после установки связи на пине STATE появляется, вполне себе устойчивая, единица.

Для того чтоб модуль искал только телефон и подключасля только к нему нужно выполнить некоторые манипуляции а именно:

А режиме АТ команд прописать МАС адресс телефона командой AT+BIND=000d,18,000001\r\n

затем лучше зафиксировать этот МАС как единственный для спаривания :)  AT+CMODE=0\r\n

Тут только сомнения можно ли подключится к телефону как к ведомому. Может лучше будет 05 переключик как ведомое а телефон сам будет к нему атоподключаться.

 

Меня интересует немного другое.

Как подключится к ведомому с паролем?

два модуля НС05 подключаются друг к другу хоть для этого нужен пароль. А вот к OBD адаптеру не может если запаролен.

XOR
Offline
Зарегистрирован: 25.04.2015

Привет! А ктонить победил INQ на V3 прошивке?

storm134
Offline
Зарегистрирован: 14.04.2017

Если нет задержки, то порт остается занятым и передача не закрывается. Следующие 12 байт попадают в неочищенный буфер и так пока не переполнится. После переполнения происходит отправка.

Буфер чтения можно увеличить записав в начале скетча

#define _SS_MAX_RX_BUFF 192 

//Теперь буфер чтения 192 байта.

byte ch = 0;

String val="";

...
loop() {
...
if (Serial.available()) {                  
    while (Serial.available()) {             
      ch = Serial.read();                  
      val += char(ch);                    
      _delay_ms(5);                      
    }

...

 

 

Вот так.