Рассмотрим как связать Bluetooth-модуль с Arduino, схему соединения, распиновку модуля, напишем скетч для работы с Bluetooth.
История
В 1996 году несколько стран участвовали в развитии беспроводной связи ближнего радиуса действия, и вместе они хотели некоторой унификации стандартов и названия, символизирующего единство.
В этом процессе принимали участие компании Intel, Ericsson и Nokia, а название Bluetooth было предложено как символ единства, т.к. в 10 веке король Гарольд Блютуз отвечал за объединение Скандинавии. Считается, что данное название не должно было остаться на постоянной основе, но оно так и осталось в дальнейшем.
Bluetooth был создан для обмена данными с близкого расстояния без необходимости использования проводов, таких как наушники, кардиомониторы и датчики. Работает в диапазоне ISM 2,4 ГГц. Данные разделены на один из 79 слотов между 2,4 и 2,4835 ГГц в полосах 1 МГц.
Bluetooth LE (Low Energy) был новой версией. В отличие от более раннего стандарта Bluetooth, LE не требует никаких контрактов или проблем с разработкой приложений, и вы можете распространять их через Play Store; он также требует очень мало энергии, поэтому он очень подходит для работы от батареи.
Bluetooth в Arduino
Некоторые платы Arduino имеют встроенную функцию Bluetooth, но в некоторых проектах может потребоваться использование внешних модулей Bluetooth.
Модуль приемопередатчика HC-05 Bluetooth является обычным вариантом, но в отличие от используемого здесь модуля Bluetooth nRF8001, он потребляет значительное количество энергии и не может быть подключен к смартфонам.
Описание проекта
Мы собираемся подключить Arduino Uno к модулю nRF8001 для отправки и получения данных с него, как если бы это был последовательный порт.
Другими словами, мы будем использовать встроенную способность действовать как UART. Мы добавим красный, зеленый и синий светодиоды, и, отправив «r», «b» или «g», мы будем импульсировать этот светодиод в течение нескольких мс.
Мы также будем вводить строки на последовательной консоли и отправлять их обратно на мобильный телефон.
Как работает nRF8001
Одной из интересных особенностей nRF8001 является то, что его интерфейс для пользователя является UART.
Другими словами, обычный старый серийный Tx и Rx, что делает его очень простым в использовании. Первые три контакта на плате - это интерфейс SPI, SCK - это просто часы, MISO - Master In Slave Out, а MOSI - Master Out Slave In.
Эти четыре контакта идут на Arduino, как показано на схеме, и это не подлежит обсуждению. REQ сигнализирует nRF, что Arduino хочет что-то сказать, а RDY сообщает Arduino, что nRF хочет что-то сказать и должен перейти к одному из выводов запроса прерывания Arduino, т. Е. 2 или 3.
RST является выводом сброса и сбрасывает nRF при запуске. REQ используется аналогично SS, с которым вы, возможно, сталкивались в других приложениях SPI. У Adafruit есть больше деталей относительно его nRF8001 по этой ссылке.
Распиновка nRF8001
Сам модуль nRF8001 выглядит вот так:

Схема соединения
Все детали мы соединяем согласно схемы ниже:
Таблица подключений:
nRF8001 | Arduino Uno |
---|---|
Vin | 5V |
GND | GND |
SCK | 13 |
MISO | 12 |
MOSI | 11 |
REQ | 10 |
RST | 9 |
RDY | 2 |
ACT | Не используется |
В собранном виде проект выглядел так:
Библиотеки
Требуется только одна библиотека - SPI-библиотека, которая автоматически устанавливается вместе с Arduino IDE. Но если у вас ее нет, вы можете скачать ее отсюда.
Вам также нужно будет скачать и установить приложение Nordic Android nRF UART 2.0 из Play Store на вашем Android телефоне. У меня нет iPhone, чтобы протестировать его, но оно должно работать и на устройствах Apple.

Скетч для Arduino
Мы будем использовать для работы такой скетч:
// адаптация примера "echodemo" в папке примеров библиотек
#include <SPI.h>
#include "Adafruit_BLE_UART.h"
//On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
#define BLE_REQ 10
#define BLE_RDY 2 // This should be an interrupt pin, on Uno thats #2 or #3
#define BLE_RST 9
Adafruit_BLE_UART BTLE = Adafruit_BLE_UART(BLE_REQ, BLE_RDY, BLE_RST);
#include <LiquidCrystal_I2C.h>
#define BL_ON 1
#define BL_OFF 0
#define ADDRESS 0x38
LiquidCrystal_I2C lcd(ADDRESS, 16, 2); // set the LCD I2C address
byte blueLED = 3;
byte redLED = 5;
byte greenLED = 4;
aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;
void setup(void)
{
lcd.init(); // initialize the lcd
lcd.setBacklight(BL_ON);
lcd.setCursor(0,0); //col, row
lcd.print("Bluetooth tests ");
Serial.begin(9600);
Serial.println(F("Bluefruit LE nRF8001 UART demo"));
BTLE.setDeviceName("Arduino"); /* 7 characters max! */
BTLE.begin();
pinMode(blueLED, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
//pre test flash LEDs:
digitalWrite(redLED, HIGH);
delay(200);
digitalWrite(redLED, LOW);
delay(200);
digitalWrite(greenLED, HIGH);
delay(200);
digitalWrite(greenLED, LOW);
delay(200);
digitalWrite(blueLED, HIGH);
delay(200);
digitalWrite(blueLED, LOW);
delay(200);
}
void loop()
{
// Tell the nRF8001 to do whatever it should be working on.
BTLE.pollACI();
// Ask what is our current status
aci_evt_opcode_t status = BTLE.getState();
// If the status changed....
if (status != laststatus)
{
// print it out!
if (status == ACI_EVT_DEVICE_STARTED) {
Serial.println(F("Advertising started"));
}
if (status == ACI_EVT_CONNECTED)
{
Serial.println(F("Connected!"));
}
if (status == ACI_EVT_DISCONNECTED)
{
Serial.println(F("Disconnected or advertising timed out"));
}
// OK set the last status change to this one
laststatus = status;
}
if (status == ACI_EVT_CONNECTED)
{
// Lets see if there's any data for us!
if (BTLE.available())
{
Serial.println();
Serial.print(BTLE.available()); //gets number of bytes available
Serial.println(F(" bytes available from BTLE"));
}
// OK while we still have something to read, get a character and print it out
//lcd.clear();
lcd.setCursor(0,1); //col, row
while (BTLE.available())
{
char c = BTLE.read();
Serial.print(c);
lcd.write(c);
if(c == 'r')
{
digitalWrite(redLED, HIGH);
delay(800);
digitalWrite(redLED, LOW);
}
if(c == 'g')
{
digitalWrite(greenLED, HIGH);
delay(800);
digitalWrite(greenLED, LOW);
}
if(c == 'b')
{
digitalWrite(blueLED, HIGH);
delay(800);
digitalWrite(blueLED, LOW);
}
if(c == 'c')
{
lcd.setCursor(0,1); //col, row
lcd.print(" "); //clear 2nd line
}
}
// Now see if we have any data from Arduino keybd/Serial console
if (Serial.available())
{
// Read a line from Serial
Serial.setTimeout(100); // 100 millisecond timeout
String s = Serial.readString();
// We need to convert the line to bytes, no more than 20 at this time
byte sendbuffer[20];
s.getBytes(sendbuffer, 20);
char sendbuffersize = min(20, s.length());
Serial.print(F("\nSending -> \""));
Serial.print((char *)sendbuffer);
Serial.println("\"");
// write the data:
BTLE.write(sendbuffer, sendbuffersize);
}
}
}
Хотя nRF8001 является 3.3В устройством, Vcc и контакты данных устойчивы к 5В, так что вы можете использовать и то, и другое. Эскиз для демонстрации проекта основан на примере, представленном в библиотеке в разделе «examples» как «echodemo».
После того, как вы загрузили проект и открыли последовательное окно, вы должны увидеть что-то подобное тому, что показано ниже на картинке.
Попробуйте набрать какой-нибудь текст и нажмите "send", и он появится в серийном окне. Введите текст в серийное окно и отправьте его, и оно появится на вашем телефоне.
В измененном примере ниже, я добавил красный, зеленый и синий светодиод на плату, и вы можете мигать ими, введя r, или b, или g с телефона. При вводе слова со всеми тремя, например, "grab" будут мигать все три. У меня старый Samsung Galaxy и работало всё просто отлично.
На этом всё. Оставляйте вопросы или комментарии ниже, наше сообщество поможет в любой ситуации.