Управление по bluetooth. Уроки Arduino: управление устройствами со смартфона для чайников Управление блютуз реле на андроид
Машинка на Arduino, управляемая Android-устройством по Bluetooth, - код приложения и мк (часть 2)
О первый части
В первой части я описал физическую часть конструкции и лишь небольшой кусок кода. Теперь рассмотрим программную составляющую - приложение для Android и скетч Arduino.Вначале приведу подробное описание каждого момента, а в конце оставлю ссылки на проекты целиком + видео результата, которое должно вас разочаровать ободрить.
Android-приложение
Программа для андроида разбита на две части: первая - подключение устройства по Bluetooth, вторая - джойстик управления.Предупреждаю - дизайн приложения совсем не прорабатывался и делался на тяп-ляп, лишь бы работало. Адаптивности и UX не ждите, но вылезать за пределы экрана не должно.
Верстка
Стартовая активность держится на верстке, элементы: кнопки и layout для списка устройств. Кнопка запускает процесс нахождения устройств с активным Bluetooth. В ListView отображаются найденные устройства.
Экран управления опирается на верстку, в которой есть только кнопка, которая в будущем станет джойстиком. К кнопки, через атрибут background, прикреплен стиль, делающий ее круглой.
TextView в финальной версии не используется, но изначально он был добавлен для отладки: выводились цифры, отправляемые по блютузу. На начальном этапе советую использовать. Но потом цифры начнут высчитываться в отдельном потоке, из которого сложно получить доступ к TextView.
Файл button_control_circle.xml (стиль), его нужно поместить в папку drawable:
Также нужно создать файл item_device.xml, он нужен для каждого элемента списка:
Манифест
На всякий случай приведу полный код манифеста. Нужно получить полный доступ к блютузу через uses-permission и не забыть обозначить вторую активность через тег activity.
Основная активность, сопряжение Arduino и Android
Наследуем класс от AppCompatActivity и объявляем переменные:Public class MainActivity extends AppCompatActivity {
private BluetoothAdapter bluetoothAdapter;
private ListView listView;
private ArrayList
Метод onCreate() опишу построчно:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //обязательная строчка
//прикрепляем ранее созданную разметку
setContentView(R.layout.activity_main);
//цепляем кнопку из разметки
Button buttonStartFind = (Button) findViewById(R.id.button_start_find);
//цепляем layout, в котором будут отображаться найденные устройства
listView = (ListView) findViewById(R.id.list_device);
//устанавливаем действие на клик
buttonStartFind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//если разрешения получены (функция ниже)
if(permissionGranted()) {
//адаптер для управления блютузом
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(bluetoothEnabled()) { //если блютуз включен (функция ниже)
findArduino(); //начать поиск устройства (функция ниже)
}
}
}
});
//цепляем кнопку для перехода к управлению
buttonStartControl = (Button) findViewById(R.id.button_start_control);
buttonStartControl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//объект для запуска новых активностей
Intent intent = new Intent();
//связываем с активностью управления
intent.setClass(getApplicationContext(), ActivityControl.class);
//закрыть эту активность, открыть экран управления
startActivity(intent);
}
});
}
Нижеприведенные функции проверяют, получено ли разрешение на использование блютуза (без разрешение пользователя мы не сможем передавать данные) и включен ли блютуз:
Private boolean permissionGranted() {
//если оба разрешения получены, вернуть true
if (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.BLUETOOTH) == PermissionChecker.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_ADMIN) == PermissionChecker.PERMISSION_GRANTED) {
return true;
} else {
ActivityCompat.requestPermissions(this, new String {Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN}, 0);
return false;
}
}
private boolean bluetoothEnabled() {
//если блютуз включен, вернуть true, если нет, вежливо попросить пользователя его включить
if(bluetoothAdapter.isEnabled()) {
return true;
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 0);
return false;
}
}
Если все проверки пройдены, начинается поиск устройства. Если одно из условий не выполнено, то высветится уведомление, мол, «разрешите\включите?», и это будет повторяться, пока проверка не будет пройдена.
Поиск устройства делится на три части: подготовка списка, добавление в список найденных устройств, установка соединения с выбранным устройством.
Private void findArduino() {
//получить список доступных устройств
Set
Когда Bluetooth-модуль, повешенный на Arduino (подробнее об этом далее), будет найден, он появится в списке. Нажав на него, вы начнете создание socket (возможно, после клика придется подождать 3-5 секунд или нажать еще раз). Вы поймете, что соединение установлено, по светодиодам на Bluetooth-модуле: без соединения они мигают быстро, при наличии соединения заметно частота уменьшается.
Управление и отправка команд
После того как соединение установлено, можно переходить ко второй активности - ActivityControl. На экране будет только синий кружок - джойстик. Сделан он из обычной Button, разметка приведена выше.Public class ActivityControl extends AppCompatActivity {
//переменные, которые понадобятся
private Button buttonDriveControl;
private float BDCheight, BDCwidth;
private float centerBDCheight, centerBDCwidth;
private String angle = "90"; //0, 30, 60, 90, 120, 150, 180
private ConnectedThread threadCommand;
private long lastTimeSendCommand = System.currentTimeMillis();
}
В методе onCreate() происходит все основное действо:
//без этой строки студия потребует вручную переопределить метод performClick()
//нам оно не недо
@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
//обязательная строка
super.onCreate(savedInstanceState);
//устанавливаем разметку, ее код выше
setContentView(R.layout.activity_control);
//привязываем кнопку
buttonDriveControl = (Button) findViewById(R.id.button_drive_control);
//получаем информацию о кнопке
final ViewTreeObserver vto = buttonDriveControl.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//получаем высоту и ширину кнопки в пикселях(!)
BDCheight = buttonDriveControl.getHeight();
BDCwidth = buttonDriveControl.getWidth();
//находим центр кнопки в пикселях(!)
centerBDCheight = BDCheight/2;
centerBDCwidth = BDCwidth/2;
//отключаем GlobalListener, он больше не понадобится
buttonDriveControl.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
//устанавливаем листенер, который будет отлавливать прикосновения
//его код представлен ниже
buttonDriveControl.setOnTouchListener(new ControlDriveInputListener());
//создаем новый поток, он будет занят отправкой данных
//в качестве параметра передаем сокет, созданный в первой активности
//код потока представлен ниже
threadCommand = new ConnectedThread(MainActivity.clientSocket);
threadCommand.run();
}
Обратите внимание (!) - мы узнаем, сколько пикселей занимает кнопка. Благодаря этому получаем адаптивность: размер кнопки будет зависеть от разрешения экрана, но весь остальной код легко под это подстроится, потому что мы не фиксируем размеры заранее. Позже научим приложение узнавать, в каком месте было касание, а после переводить это в понятные для ардуинки значения от 0 до 255 (ведь касание может быть в 456 пикселях от центра, а МК с таким числом работать не будет).
Далее приведен код ControlDriveInputListener(), данный класс располагается в классе самой активности, после метода onCreate(). Находясь в файле ActivityControl, класс ControlDriveInputListener становится дочерним, а значит имеет доступ ко всем переменным основного класса.
Не обращайте пока что внимание на функции, вызываемые при нажатии. Сейчас нас интересует сам процесс отлавливания касаний: в какую точку человек поставил палец и какие данные мы об этом получим.
Обратите внимание, использую класс java.util.Timer: он позволяет создать новый поток, который может иметь задержку и повторятся бесконечное число раз через каждое энное число секунд. Его нужно использовать для следующей ситуации: человек поставил палец, сработал метод ACTION_DOWN, информация пошла на ардуинку, а после этого человек решил не сдвигать палец, потому что скорость его устраивает. Второй раз метод ACTION_DOWN не сработает, так как сначала нужно вызвать ACTION_UP (отодрать палец от экрана).
Чтож, мы запускаем цикл класса Timer() и начинаем каждые 10 миллисекунд отправлять те же самые данные. Когда же палец будет сдвинут (сработает ACTION_MOVE) или поднят (ACTION_UP), цикл Timer надо убить, чтобы данные от старого нажатия не начали отправляться снова.
Public class ControlDriveInputListener implements View.OnTouchListener {
private Timer timer;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
//получаем точки касания в пикселях
//отсчет ведется от верхнего левого угла (!)
final float x = motionEvent.getX();
final float y = motionEvent.getY();
//узнаем, какое действие было сделано
switch(motionEvent.getAction()) {
//если нажатие
//оно сработает всегда, когда вы дотронетесь до кнопки
case MotionEvent.ACTION_DOWN:
//создаем таймер
timer = new Timer();
//запускаем цикл
//аргументы указывают: задержка между повторами 0,
//повторять каждые 10 миллисекунд
timer.schedule(new TimerTask() {
@Override
public void run() {
//функцию рассмотрим ниже
calculateAndSendCommand(x, y);
}
}, 0, 10);
break;
//если палец был сдвинут (сработает после ACTION_DOWN)
case MotionEvent.ACTION_MOVE:
//обязательно (!)
//если ранее был запущен цикл Timer(), завершаем его
if(timer != null) {
timer.cancel();
timer = null;
}
//создаем новый цикл
timer = new Timer();
//отправляем данные с той же частотой, пока не сработает ACTION_UP
timer.schedule(new TimerTask() {
@Override
public void run() {
calculateAndSendCommand(x, y);
}
}, 0, 10);
break;
//если палец убрали с экрана
case MotionEvent.ACTION_UP:
//убиваем цикл
if(timer != null) {
timer.cancel();
timer = null;
}
break;
}
return false;
}
}
Обратите еще раз внимание: отсчет x и y метод onTouch() ведет от верхнего левого угла View. В нашем случае точка (0; 0) находится у Button тут:
Теперь, когда мы узнали, как получить актуальное расположение пальца на кнопки, разберемся, как преобразовать пиксели (ведь x и y - именно расстояние в пикселях) в рабочие значения. Для этого использую метод calculateAndSendCommand(x, y), который нужно разместить в классе ControlDriveInputListener. Также понадобятся некоторые вспомогательные методы, их пишем в этот же класс после calculateAndSendCommand(x, y).
Private void calculateAndSendCommand(float x, float y) {
//все методы описаны ниже
//получаем нужные значения
//четверть - 1, 2, 3, 4
//чтобы понять, о чем я, проведите через середину кнопки координаты
//и да, дальше оно использоваться не будет, но для отладки пригождалось
int quarter = identifyQuarter(x, y);
//функция переводит отклонение от центра в скорость
//вычитаем y, чтобы получить количество пикселей от центра кнопки
int speed = speedCalculation(centerBDCheight - y);
//определяет угол поворота
//вспомните первую часть статьи, у нас есть 7 вариантов угла
String angle = angleCalculation(x);
//если хотите вывести информацию на экран, то используйте этот способ
//но в финальной версии он не сработает, так как затрагивает отдельный поток
/*String resultDown = "x: "+ Float.toString(x) + " y: " + Float.toString(y)
+ " qr: " + Integer.toString(quarter) + "\n"
+ "height: " + centerBDCheight + " width: " + centerBDCwidth + "\n"
+ "speed: " + Integer.toString(speed) + " angle: " + angle; */
//viewResultTouch.setText(resultDown);
//все данные полученные, можно их отправлять
//но делать это стоить не чаще (и не реже), чем в 100 миллисекунд
if((System.currentTimeMillis() - lastTimeSendCommand) > 100) {
//функцию рассмотрим дальше
threadCommand.sendCommand(Integer.toString(speed), angle);
//перезаписываем время последней отправки данных
lastTimeSendCommand = System.currentTimeMillis();
}
}
private int identifyQuarter(float x, float y) {
//смотрим, как расположена точка относительно центра
//возвращаем угол
if(x > centerBDCwidth && y > centerBDCheight) {
return 4;
} else if (x < centerBDCwidth && y >centerBDCheight) {
return 3;
} else if (x < centerBDCwidth && y < centerBDCheight) {
return 2;
} else if (x > centerBDCwidth && y < centerBDCheight) {
return 1;
}
return 0;
}
private int speedCalculation(float deviation) {
//получаем коэффициент
//он позволит превратить пиксели в скорость
float coefficient = 255/(BDCheight/2);
//высчитываем скорость по коэффициенту
//округляем в целое
int speed = Math.round(deviation * coefficient);
//если скорость отклонение меньше 70, ставим скорость ноль
//это понадобится, когда вы захотите повернуть, но не ехать
if(speed > 0 && speed < 70) speed = 0;
if(speed < 0 && speed > - 70) speed = 0;
//нет смысла отсылать скорость ниже 120
//слишком мало, колеса не начнут крутиться
if(speed < 120 && speed > 70) speed = 120;
if(speed > -120 && speed < -70) speed = -120;
//если вы унесете палец за кнопку, ACTION_MOVE продолжит считывание
//вы сможете получить отклонение больше, чем пикселей в кнопке
//на этот случай нужно ограничить скорость
if(speed > 255) speed = 255;
if(speed < - 255) speed = -255;
//пометка: скорость > 0 - движемся вперед, < 0 - назад
return speed;
}
private String angleCalculation(float x) {
//разделяем ширину кнопки на 7 частей
//0 - максимально влево, 180 - вправо
//90 - это когда прямо
if(x < BDCwidth/6) {
angle = "0";
} else if (x > BDCwidth/6 && x < BDCwidth/3) {
angle = "30";
} else if (x > BDCwidth/3 && x < BDCwidth/2) {
angle = "60";
} else if (x > BDCwidth/2 && x < BDCwidth/3*2) {
angle = "120";
} else if (x > BDCwidth/3*2 && x < BDCwidth/6*5) {
angle = "150";
} else if (x > BDCwidth/6*5 && x < BDCwidth) {
angle = "180";
} else {
angle = "90";
}
return angle;
}
Когда данные посчитаны и переведены, в игру вступает второй поток. Он отвечает именно за отправку информации. Нельзя обойтись без него, иначе сокет, передающий данные, будет тормозить отлавливание касаний, создастся очередь и все конец всему короче.
Класс ConnectedThread также располагаем в классе ActivityControl.
Private class ConnectedThread extends Thread { private final BluetoothSocket socket; private final OutputStream outputStream; public ConnectedThread(BluetoothSocket btSocket) { //получаем сокет this.socket = btSocket; //создаем стрим - нить для отправки данных на ардуино OutputStream os = null; try { os = socket.getOutputStream(); } catch(Exception e) {} outputStream = os; } public void run() { } public void sendCommand(String speed, String angle) { //блютуз умеет отправлять только байты, поэтому переводим byte speedArray = speed.getBytes(); byte angleArray = angle.getBytes(); //символы используются для разделения //как это работает, вы поймете, когда посмотрите принимающий код скетча ардуино String a = "#"; String b = "@"; String c = "*"; try { outputStream.write(b.getBytes()); outputStream.write(speedArray); outputStream.write(a.getBytes()); outputStream.write(c.getBytes()); outputStream.write(angleArray); outputStream.write(a.getBytes()); } catch(Exception e) {} } }
Подводим итоги Андроид-приложения
Коротко обобщу все громоздкое вышеописанное.- В ActivityMain настраиваем блютуз, устанавливаем соединение.
- В ActivityControl привязываем кнопку и получаем данные о ней.
- Вешаем на кнопку OnTouchListener, он отлавливает касание, передвижение и подъем пальца.
- Полученные данные (точку с координатами x и y) преобразуем в угол поворота и скорость
- Отправляем данные, разделяя их специальными знаками
Скетч Arduino
Андроид-приложение разобрано, написано, понято… а тут уже и попроще будет. Постараюсь поэтапно все рассмотреть, а потом дам ссылку на полный файл.Переменные
Для начала рассмотрим константы и переменные, которые понадобятся. #include
Метод setup()
В методе setup() мы устанавливаем параметры пинов: будут работать они на вход или выход. Также установим скорость общения компьютера с ардуинкой, блютуза с ардуинкой.Void setup() { pinMode(dirLeft, OUTPUT); pinMode(speedLeft, OUTPUT); pinMode(dirRight, OUTPUT); pinMode(speedRight, OUTPUT); pinMode(pinRed, INPUT); pinMode(pinBlack, INPUT); pinMode(pinWhite, INPUT); pinMode(pinAngleStop, OUTPUT); pinMode(angleDirection, OUTPUT); pinMode(angleSpeed, OUTPUT); //данная скорость актуальна только для модели HC-05 //если у вас модуль другой версии, смотрите документацию BTSerial.begin(38400); //эта скорость постоянна Serial.begin(9600); }
Метод loop() и дополнительные функции
В постоянно повторяющемся методе loop() происходит считывание данных. Сначала рассмотрим основной алгоритм, а потом функции, задействованные в нем.Void loop() {
//если хоть несчитанные байты
if(BTSerial.available() > 0) {
//считываем последний несчитанный байт
char a = BTSerial.read();
if (a == "@") {
//если он равен @ (случайно выбранный мною символ)
//обнуляем переменную val
val = "";
//указываем, что сейчас считаем скорость
readSpeed = true;
} else if (readSpeed) {
//если пора считывать скорость и байт не равен решетке
//добавляем байт к val
if(a == "#") {
//если байт равен решетке, данные о скорости кончились
//выводим в монитор порта для отладки
Serial.println(val);
//указываем, что скорость больше не считываем
readSpeed = false;
//передаем полученную скорость в функцию езды
go(val.toInt());
//обнуляем val
val = "";
//выходим из цикла, чтобы считать следующий байт
return;
}
val+=a;
} else if (a == "*") {
//начинаем считывать угол поворота
readAngle = true;
} else if (readAngle) {
//если решетка, то заканчиваем считывать угол
//пока не решетка, добавляем значение к val
if(a == "#") {
Serial.println(val);
Serial.println("-----");
readAngle = false;
//передаем значение в функцию поворота
turn(val.toInt());
val= "";
return;
}
val+=a;
}
//получаем время последнего приема данных
lastTakeInformation = millis();
} else {
//если несчитанных байтов нет, и их не было больше 150 миллисекунд
//глушим двигатели
if(millis() - lastTakeInformation > 150) {
lastTakeInformation = 0;
analogWrite(angleSpeed, 0);
analogWrite(speedRight, 0);
analogWrite(speedLeft, 0);
}
}
}
Получаем результат: с телефона отправляем байты в стиле "@скорость#угол#" (например, типичная команда "@200#60#". Данный цикл повторяется каждый 100 миллисекунд, так как на андроиде мы установили именно этот промежуток отправки команд. Короче делать нет смысла, так как они начнут становится в очередь, а если сделать длиннее, то колеса начнут двигаться рывками.
Все задержки через команду delay(), которые вы увидите далее, подобраны не через физико-математические вычисления, а опытным путем. Благодаря всем выставленным задрежам, машинка едет плавно, и у всех команд есть время на отработку (токи успевают пробежаться).
В цикле используются две побочные функции, они принимают полученные данные и заставляют машинку ехать и крутится.
Void go(int mySpeed) {
//если скорость больше 0
if(mySpeed > 0) {
//едем вперед
digitalWrite(dirRight, HIGH);
analogWrite(speedRight, mySpeed);
digitalWrite(dirLeft, HIGH);
analogWrite(speedLeft, mySpeed);
} else {
//а если меньше 0, то назад
digitalWrite(dirRight, LOW);
analogWrite(speedRight, abs(mySpeed) + 30);
digitalWrite(dirLeft, LOW);
analogWrite(speedLeft, abs(mySpeed) + 30);
}
delay(10);
}
void turn(int angle) {
//подаем ток на плюс определителя угла
digitalWrite(pinAngleStop, HIGH);
//даем задержку, чтобы ток успел установиться
delay(5);
//если угол 150 и больше, поворачиваем вправо
//если 30 и меньше, то влево
//промежуток от 31 до 149 оставляем для движения прямо
if(angle > 149) {
//если замкнут белый, но разомкнуты черный и красный
//значит достигнуто крайнее положение, дальше крутить нельзя
//выходим из функции через return
if(digitalRead(pinWhite) == HIGH && digitalRead(pinBlack) == LOW && digitalRead(pinRed) == LOW) {
return;
}
//если проверка на максимальный угол пройдена
//крутим колеса
digitalWrite(angleDirection, HIGH);
analogWrite(angleSpeed, speedTurn);
} else if (angle < 31) {
if(digitalRead(pinRed) == HIGH && digitalRead(pinBlack) == HIGH && digitalRead(pinWhite) == HIGH) {
return;
}
digitalWrite(angleDirection, LOW);
analogWrite(angleSpeed, speedTurn);
}
//убираем питание
digitalWrite(pinAngleStop, LOW);
delay(5);
}
Поворачивать, когда андроид отправляет данные о том, что пользователь зажал угол 60, 90, 120, не стоит, иначе не сможете ехать прямо. Да, возможно сразу не стоило отправлять с андроида команду на поворот, если угол слишком мал, но это как-то коряво на мой взгляд.
Итоги скетча
У скетча всего три важных этапа: считывание команды, обработка ограничений поворота и подача тока на двигатели. Все, звучит просто, да и в исполнении легче чем легко, хотя создавалось долго и с затупами.1 Описание модуля bluetooth HC-06
Существует большое количество реализаций модулей Bluetooth. Каждая имеет свои особенности, но в общем и целом они все очень похожи. Рассмотрим представителя bluetooth модуля семейства HC-06 , который можно приобрести по отличной цене на этом сайте .
Данный модуль работает на частоте от 2,40 ГГц до 2,48 ГГц и поддерживает спецификацию bluetooth версии 2.1+EDR: пониженное потребление энергии, повышенный уровень защиты данных и лёгкое соединение Bluetooth-устройств. Устойчивый приём с модулем гарантирован в пределах 10 метров.
Назначение выводов bluetooth-модуля такое:
Последние два вывода могут быть не задействованы; часто можно встретить модули вообще без этих выводов.
2 Схема подключения bluetooth-модуля к Arduino
Подключим bluetooth модуль к Arduino по приведённой схеме. Обратите внимание, что передатчик (Tx) Ардуино подключается к приёмнику (Rx) модуля, и наоборот.
На выводе Status появляется высокий уровень, когда модуль сопряжён с другим bluetooth устройством, и низкий - когда не сопряжён. Можно считывать его значение, подключив к пину Arduino и назначив ему режим работы pinMode(pinStatus, INPUT) и таким образом узнавать состояние модуля. Но не на всех модулях индикатор статуса работает корректно, поэтому мы не будем его использовать в данном примере.
В результате должно получиться примерно как на фотографии.
3 Скетч для Arduino для работы по bluetooth
Напишем такой скетч и загрузим в память Arduino:
Const int ledPin = 13; // вывод встроенного светодиода char incomingbyte; // переменная для данных Bluetooth void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { if (Serial.available() > 0) { // если порт доступен incomingbyte = Serial.read(); // считываем с порта данные switch(incomingbyte) { case "1": // если приходит "1" digitalWrite(ledPin, HIGH); // break; case "0": // если приходит "0" digitalWrite(ledPin, LOW); // break; } } }
Включаем собранную схему с Arduino и подключённым к нему bluetooth-модулем. Правильно подключённый модуль сразу входит в режим ожидания подключения, о чём будет свидетельствовать ритмично мигающий светодиод статуса.
4 Сопряжение с bluetooth-устройством
Теперь нужно добавить bluetooth-устройство в список доверенных устройств. Включаем Bluetooth на компьютере, идём в Параметры Устройства Bluetooth .
Если в области уведомлений при включении bluetooth на компьютере появилась иконка bluetooth, то можно кликнуть по ней правой кнопкой мыши и выбрать пункт :
Убеждаемся, что наш bluetooth-модуль виден компьютеру. Выбираем его из списка и нажимаем кнопку Связать . В диалоговое окно вводим пароль по умолчанию 1234 . При успешном добавлении устройство появится в списке с пометкой Сопряжено .
Пароль по умолчанию для конкретного модуля может отличаться от "1234". Эту информацию должен предоставить изготовитель (продавец) модуля.
Если вы хотите подключиться к вашему модулю bluetooth со смартфона, то порядок действий аналогичный: включить bluetooth на смартфоне, обнаружить модуль, подключённый к Arduino, выполнить сопряжение с ним.
5 Подключаемся к bluetooth-модулю по bluetooth с компьютера
Для подключения к bluetooth модулю можно использовать различные программы, которые могут подключаться к COM-порту. Например, такие как HyperTerminal, PuTTY, Tera Term, Termite и другие. Они все бесплатные и свободно распространяются в интернете.
Удобство программы TeraTerm в том, что она автоматически выводит список COM-портов, которые назначены модулю bluetooth вашего компьютера. Запускаем программу, выбираем подключение Serial, из списка выбираем соответствующий bluetooth COM-порт, нажимаем OK.
Программа PuTTY при запуске также спрашивает номер порта (COM4, у вас будет свой), скорость подключения (9600), тип соединения (Serial). Затем нажимаем кнопку Соединиться .
В случае ошибки при подключении программа выведет соответствующее оповещение. Если соединение вашего компьютера с bluetooth-модулем произошло успешно, то вы увидите перед собой поле терминала. Введите с клавиатуры в это поле число 1 - и светодиод на 13 выводе Arduino загорится, введите 0 - погаснет.
6 Подключение со смартфона с помощью Bluetooth Terminal
Аналогично можно подключиться к модулю bluetooth со смартфона. Скачайте приложение для работы с bluetooth по терминалу, например Bluetooth Terminal . Подключайтесь к модулю и вводите команды 0 или 1.
Таким образом, мы научились подключаться по bluetooth к Arduino и передавать ему данные.
Эта статья будет иметь «итоговый» характер, то есть резюмировать столь невысокие, но мои достижения по работе с микроконтроллером Ардуино. Чтобы впоследствии, когда будет будет необходимо, можно было вернуться к этой платформе и реализовать не ней включение выключение каких-либо устройств.
Как я вижу сложившееся, с помощью Bluetooth модуля можно осуществлять управление устройствами для умного дома или сделать даже обычное открывание –закрывание ворот во дворе или гараже. То есть подъехал, открыл. Уезжаешь – закрыл. В принципе у меня пока нет ни частного дома, ни ворот, но как управлять ими я уже знаю:)
Итак, давайте теперь об этом я поведаю и вам.
Принцип включения выключении нагрузки по Bluetooth с помощью Arduino
Собственно принцип очень прост. Необходимо иметь какой либо девайс с возможностью установить управляющее ПО под системой Android. Скажем телефон или планшет. Далее берем Ардуино, а также блок Bluetooth, все это соединяем между собой и заливаем в Ардуино программку. Вот и все.
Схема подключения Arduino с модулем Bluetooth
Само собой в нашем случае первым делом будет физическое подключение, а затем и программное обеспечение. Так вот, начнем с подключения. Если у вас есть Ардуино UNO и модуль Bluetooth HC-06 или 05, то подключать надо будет следующим образом. При этом на схеме ни коим образом не отражено подключение для управляющих цепей. То есть приведено подключение непосредственно модуля Bluetooth HC-06 к Ардуинке.
Само собой если у вас управляющими будут выходы 11 и 13, как в нашем случае, смотрите статью далее, то к ним и будет подключаться силовой блок или просто светодиод. Важным будет то, что при подключении модуля RX на одном устройстве идет к TX на другом и наоборот. Учтите это!
Скетч для Arduino дабы он работал с модулем Bluetooth
Теперь о скетче, то есть о ПО, которое заставляет работать нашу аппаратную платформу, выразимся так. Все очень просто. Смотрим.
Int val; int LED = 13; int LED1 = 11; void setup() { Serial.begin(9600); pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); } void loop() { if (Serial.available()) { val = Serial.read(); // При символе "1" включаем светодиод 13 if (val == "1") { digitalWrite(LED, HIGH); } // При символе "0" выключаем светодиод 13 if (val == "0") { digitalWrite(LED, LOW); } // При символе "2" выключаем светодиод 11 if (val == "2") { digitalWrite(LED1, HIGH); } // При символе "0" выключаем светодиод 11 if (val == "3") { digitalWrite(LED1, LOW); } } }
Собственно здесь идет назначение переменных, два светодиода на 11 и на 13 ножку в нашем случае. Потом с помощью Serial.begin(9600) мы подключаем наш блютуф. Ну и собственно осталось найти программку для управления блютуф.
Программа для планшета или телефона (Android) для управления нагрузкой через Bluetooth
Вы собственно сами можете найти любую из программ, которая поддерживает управление блютуф модулем с телефона, это уже на ваше усмотрение. Я для себя нашел и прибрал (скачать ArduinoRC) тоже установочную программку. Именно ее я и поставил на телефон.
Собственно с помощью этой программки и можно будет задавать критерии-условия для скетча, а значит получать сигнал на выходных ножках 11 и 13. В нашем случае задействованы кнопки 0,1,2,3. Именно они включают и выключают светодиоды. Смотрите скетч.
Первый раз при подключении устройства возможно затребует пароль, типа 000 или 1234.
Траблы с заливкой программы в Arduino
Последнее о чем хотелось сказать и с чем столкнулся, то есть какая проблема возникла. Так это то, что при заливке программы необходимо было отключать модуль блютуф. Так как в противном случае при подключенном модуле и при заливке программы выпадала ошибка. Скетч просто не заливался.
Резюмируя все вышесказанное можно сделать вывод о том, что используя Ардуино и модуль блютуф к ней, можно одним нажатием пальчика на своем телефоне или планшете управлять многокиловатными нагрузками.
Теперь тоже самое в видео...
Bluetooth в Arduino позволяет объединять различные устройства по беспроводному каналу связи. Вы можете передавать сообщения от датчиков и контроллеров Arduino на Android устройства и наоборот, получать команды со смартфонов по bluetooth. В этой статье мы узнаем, как с помощью популярных и не очень недорогих bluetooth модулей HC05 и HC06 организовать беспроводную работу своего ардуино проекта. Вы не поверите, но подключение и программирование Bluetooth модулей совсем не сложное занятие и доступно даже начинающим. Давайте убедимся в этом.
Нередко в проектах возникает необходимость дистанционного управления или передачи данных с телефона или другого устройства. Одним из самых популярных и удобных способов является обмен данных через Bluetooth. Для связи платы Ардуино и компьютера используется интерфейс UART (Serial). Так как любая плата Ардуино имеет хотя бы 1 последовательный порт UART, для подключения Bluetooth модуля не требуются специализированные библиотеки и схемы.
Самыми популярными модулями являются устройства на основе чипа BC417. Эта серия называется HC. Модули HC-03 и HC-05 могут быть и сервером соединения, и клиентом, они обладают широким набором АТ команд.
Для подключения к ПК потребуются модуль Bluetooth, плата Ардуино, соединительные провода и компьютер. Скетч для управления платой Ардуино через смартфон и компьютер будет одинаковым, так как в обоих случаях данные в микроконтроллер буду поступать по протоколу UART. Схема подключения Bluetooth-модуля к плате представлена на рисунке. Пин RX на ардуино подключается к TDX, TX – к RDX, GND – к GND, 5V – к VCC.
При загрузке скетча нужно отключить Bluetooth-модуль, иначе будет появляться ошибка доступа к Ардуино. Также нужно установить на смартфон или планшет, поддерживающий ОС Android, приложение для отправки данных на модуль. После установки приложения нужно загрузить скетч и подключить модуль к плате Ардуино. Пример кода мигания светодиода:
Int val; void setup() { Serial.begin(9600); pinMode(13, OUTPUT); // 13 пин – светодиод, объявляется как выход } void loop() { if (Serial.available()) // проверка поданных команд { val = Serial.read(); if (val == "1") {digitalWrite(13, HIGH);} // при 1 включается светодиод if (val == "0") {digitalWrite(13, LOW);} // при 0 выключается светодиод } }
Теперь нужно настроить соединение телефона и модуля. Для установки соединения нужно зайти в настройки телефона и включить Bluetooth. Как только устройство будет найдено, нужно ввести пароль – обычно это «1234» или «0000». После этого нужно зайти в приложение, нажать на кнопку «подключить Bluetooth» и выбрать нужное устройство. При успешном сопряжении на модуле светодиод начнет мигать медленнее, примерно 1 раз в 2 секунды.
В скетче светодиод включается и выключается при получении цифр «1» и «0». Кроме цифр также можно использовать буквы латинского алфавита с учетом регистра.
Аналогичным образом можно подключаться к модулю при помощи компьютера. Для этого существуют различные программы, которые подключатся к COM-порту. При запуске программы запрашивают номер порта, скорость и тип подключения. При успешном подключении на экране появится поле терминала, в которое нужно ввести с клавиатуры цифры/буквы, включающие светодиод.
Описание модуля Bluetooth HC 06
Все существующие типы модулей Bluetooth имеют свои особенности, но по функциям и действию они похожи. Одним из видов модулей является Bluetooth HC 06. Со стороны Ардуино модуль выглядит как обычный последовательный интерфейс, поэтому можно сразу наладить взаимодействие с устройством на компьютере.
Основные характеристики модуля:
- Питание 3,3В – 6 В;
- Максимальное входное напряжение 5 В;
- Максимальный ток 45 мА;
- Скорость передачи данных 1200–1382400 бод;
- Рабочие частоты 2,40 ГГц – 2,48ГГц;
- Поддержка спецификации bluetooth версии 2.1;
- Малое потребление энергии;
- Высокий уровень защиты данных;
- Дальность связи 30 м;
- Для подключения к смартфону используются следующие данные – пароль «1234», скорость передачи данных 9600, имя модуля HС-06.
Модуль имеет следующие контакты:
- VCC , GND – плюс и минус питания;
- RX и TX – приемник и передатчик;
- MCU-INT – выводит статус;
- Clear (Reset) – сбрасывание и перезагрузка модуля. Последние два вывода обычно не задействованы в работе, поэтому сейчас производятся модули без этих контактов.
Модуль HC-06 используется только в режиме slave, то есть он не может самостоятельно подключаться к другим устройствам Bluetooth. Все настройки для подключения «пароль, скорость передачи данных» можно изменить при помощи АТ-команд.
В комплектацию модуля не входят соединительные провода.
Сравнение модулей Bluetooth HC 05 и HC 06
Модули HC 05 и HC 06 являются наиболее используемыми, их чаще остальных можно найти в продаже. Принцип действия этих модулей схож, оба модуля основаны на одинаковом чипе, но есть и важные отличия. В первую очередь, модуль HC 05 может работать в двух режимах работы – и в качестве ведущего (master), и в качестве ведомого (slave).
Оба модуля представляют собой две спаянные платы. Одна из них – заводская с микросхемой, другая нужна для самодельных устройств, она оснащена ножками GPIO со стандартным шагом 2,54 мм и стабилизатором напряжения.
Модуль HC-05 стоит несколько дороже, но он имеет большее количество полезных рабочих функций.
Распиновка модуля HC-05:
- EN – управление питанием;
- Питание VCC;
- RX, TX;
- STATE – индикация;
- KEY – активирует режим управления при помощи АТ-команд. При KEY=0 – передача данных, при KEY=1 – АТ-команды.
Скорость передачи АТ команд по умолчанию для HC-05 равна 38400, для HC-06 – 9600. Важным моментом является то, что в конце АТ команд для HC-05 должны быть символы CRLF.
Основные характеристики HC-05:
- Рабочие частоты 2,4 – 2,48 ГГц;
- Мощность передачи 0,25 – 2,5мВт;
- Дальность 10 м;
- Максимальная скорость обмена данными 115200 бод;
- Питание 3,3В;
- Ток 30-40 мА;
- Рабочие температуры от -25С до 75С.
Подключение обоих модулей к плате Ардуино одинаково.
Вариант подключение модуля с использованием делителя.Представлен вариант для Arduino Nano, но он подойдет и к плате Uno.
Заключение
В этой статье мы рассмотрели варианты подключения и работы с одними из самых распространенных Ардуино модулей Bluetooth HC05, HC06 . Никаких особенных сложностей с этими модулями у вас быть не должно – просто подключайте его к пинам с аппаратным или программным UART, после чего используйте традиционные библиотеки (Serial для модуля, подключенного к 0, 1 пинам, SoftwareSerial в случае присоединения к другим).
Подключение Bluetooth к вашему Arduino-проекту может существенно увеличить ваши возможности по взаимодействию с другими устройствами. Вы сможете контролировать состояния датчиков и изменять параметры системы без перезагрузки контроллера. И. конечно же, вы сможете без проблем создать роботы и машинки на ардуино, управляемые через bluetooth со смартфона. Будем надеяться, что вы сможете сделать свой первый проект после прочтения этой статьи.
В этой статье представлена пошаговая инструкция, которая поможет вам самостоятельно создать приложение для Android-смартфона, предназначенное для управления чем-либо через Bluetooth. Для демонстрации мы подробно разберем пример мигания светодиодом на Arduino по командам с телефона или планшета. В результате выполнения наших инструкций вы научитесь делать вот так:
Для управления домашним роботом достаточно добавить кнопок и обработать их команды на стороне Arduino.
Что для этого потребуется
- Любая Arduino-совместимая плата
- Bluetooth-модуль
- Устройство на котором установлена ОС Android
В качестве Bluetooth-модуля лучше всего использовать HC-05. Его легко купить в китайском интернет магазине или на eBay. Модуль питается от 3.3 В, но его линии I/O могут работать и с 5-вольтовой логикой, что позволяет подключать его UART к Arduino.
Bluetooth-модуль HC-05
Подключение Bluetooth-модуля к Arduino
Так теперь нам нужно подключить нашу Arduino с Bluetooth. Если на Arduino нет вывода с 3.3В, а только 5В то нужен будет поставить стабилизатор чтобы снизить питание. Назначение выводов HC-05 легко найти в интернете. Для использования рекомендуем вам сделать плату с выведенными линиями питания, Rx и Tx. Подключение к Arduino необходимо производить в следующем порядке:
- вывод Arduino 3.3В или (5В через стабилизатор!) — к 12 пину модуля Bluetooth
- вывод Arduino GND — к 13 пину модуля Bluetooth
- вывод Arduino TX — к 2 пину модуля RX Bluetooth
- вывод Arduino RX — к 1 пину модуля TX Bluetooth
После подключения необходимо проверить работоспособность Bluetooth модуля. Подключим Светодиод к 12 выводу Arduino и загрузим на плату следующий скетч:
Char incomingByte; // входящие данные int LED = 12; // LED подключен к 12 пину void setup() { Serial.begin(9600); // инициализация порта pinMode(LED, OUTPUT); //Устанавливаем 12 вывод как выход Serial.println("Press 1 to LED ON or 0 to LED OFF..."); } void loop() { if (Serial.available() > 0) { //если пришли данные incomingByte = Serial.read(); // считываем байт if(incomingByte == "0") { digitalWrite(LED, LOW); // если 1, то выключаем LED Serial.println("LED OFF. Press 1 to LED ON!"); // и выводим обратно сообщение } if(incomingByte == "1") { digitalWrite(LED, HIGH); // если 0, то включаем LED Serial.println("LED ON. Press 0 to LED OFF!"); } } }