Arduino: Bluetooth-модули и управление контроллером по беспроводной связи

Arduino: Bluetooth-модули и управление контроллером по беспроводной связи Лодки

Основная активность, сопряжение arduino и android

Наследуем класс от AppCompatActivity и объявляем переменные:

public class MainActivity extends AppCompatActivity {
        private BluetoothAdapter bluetoothAdapter;
        private ListView listView;
        private ArrayList<String> pairedDeviceArrayList;
        private ArrayAdapter<String> pairedDeviceAdapter;
        public static BluetoothSocket clientSocket;
        private Button buttonStartControl;
}

Метод 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); 
         }
     });

 }


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

Смотрите про коптеры:  Самодельный FPV квадрокоптер

Android шаг 3

Доступ к удаленному БТ модулю получен, следующий наш шаг передать данные от андроида к нему. Для этого в onResume(), создадим сокет:

btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);

где UUID (Universally Unique Identifier) — это стандарт идентификации, используемый в создании программного обеспечения. Добавим в определение константу UUID:

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");


Чтобы не тормозить соединение отменим поиск других БТ устройств:

btAdapter.cancelDiscovery();	

Попытаемся подсоединиться:

btSocket.connect();

При не удаче закроем сокет:

btSocket.close();

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

	 //Класс отдельного потока для передачи данных  
	 private class ConnectedThred extends Thread{
		 private final BluetoothSocket copyBtSocket;
		 private final OutputStream OutStrem;
		 
		 public ConnectedThred(BluetoothSocket socket){
			 copyBtSocket = socket;
			 OutputStream tmpOut = null;
			 try{
				 tmpOut = socket.getOutputStream();
			 } catch (IOException e){}
			 
			 OutStrem = tmpOut;
		 }
		 
		 public void sendData(String message) {
			    byte[] msgBuffer = message.getBytes();
			    Log.d(LOG_TAG, "***Отправляем данные: "   message   "***"  );
			  
			    try {
			    	OutStrem.write(msgBuffer);
			    } catch (IOException e) {}
		}
		 
		 public void cancel(){
			 try {
				 copyBtSocket.close();
			 }catch(IOException e){}			 
		 }
		 
		 public Object status_OutStrem(){
			 if (OutStrem == null){return null;		
			 }else{return OutStrem;}
		 }
	 }  


В конструкторе public ConnectedThred(BluetoothSocket socket) создается объект управляющий передачей данных через сокет:

tmpOut = socket.getOutputStream();

Для отправки данных из главного activity вызывается метод sendData(String message) с параметром текстового сообщения, которое преобразуется к типу byte. Метод cancel() позволяет закрыть сокет.

Напишем, обработчики нажатия кнопок b1 и b2, содержащие вызов функции sendData(String message) и сделаем запись об этом в логе. Полный код приложения приведен ниже:

Android шаг 4

Получение данных также как и отправку, необходимо выполнять в отдельном потоке, чтобы избежать зависание главного activity. Принятые данные от БТ модуля мы будем выводить на экран главного activity в текстовом поле – MyText. Но возникает трудность — работа с view-компонентами доступна только из основного потока.

Handler — это механизм, который позволяет работать с очередью сообщений. Он привязан к конкретному потоку (thread) и работает с его очередью. Handler умеет помещать сообщения в очередь. При этом он ставит самого себя в качестве получателя этого сообщения. И когда приходит время, система достает сообщение из очереди и отправляет его адресату (т.е. в Handler) на обработку.

Объявим Handler:

Handler h;

Создадим свой Handler:

  h = new Handler() {
            public void handleMessage(android.os.Message msg) {
              switch (msg.what) {
              case ArduinoData:
	        	  byte[] readBuf = (byte[]) msg.obj;
	              String strIncom = new String(readBuf, 0, msg.arg1);                                         
	              mytext.setText("Данные от Arduino: "   strIncom);           
	              break;
              }
            };
          };

в нем реализуем метод обработки сообщений handleMessage. Мы извлекаем из сообщения атрибут what, obj и аргументы типа int. Преобразуем полученное сообщение в строку и выводим его в текстовое поле главного activity: mytext.setText(«Данные от Arduino: » strIncom);


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

public void run()
		 {
			 byte[] buffer = new byte[1024];
			 int bytes;
			 
			 while(true){
				 try{
					 bytes = InStrem.read(buffer);
					 h.obtainMessage(ArduinoData, bytes, -1, buffer).sendToTarget();
				 }catch(IOException e){break;} 
				 
			 } 			 
 }

Полный код приложения приведен ниже:

Javascript

Работа с Web Bluetooth API построена на Promise. Ниже я буду приводить поэтапные примеры кода. Полный исходный код можно будет найти в репозитории, на который будет оставлена ссылка.

Для начала нам необходимо подключиться к устройству. Мы запрашиваем устройства и в фильтре передаём имя устройства и UID сервиса, с которыми будем работать. Если не указать сервис заранее, то в дальнейшем с ним нельзя будет взаимодействовать.

navigator.bluetooth.requestDevice({
    filters:
      [
        { name: MY_BLUETOOTH_NAME },
        { services: [SEND_SERVICE] },
      ]
  })

После того как мы нажмём на кнопку “Connect”, у нас откроется окно (рис. 5), в котором необходимо выбрать устройство и нажать на кнопку подключения.

Рис. 5 (Окно с доступным к подключению устройством)

При подключении возвращается Promise, содержащий “device”, к которому можно подключиться. Окей, давайте запишем его в переменную и создадим соединение.

.then(device => {
      myDevice = device;

      return device.gatt.connect();
    })

После этого нам возвращается Promise, содержащий “server”. Затем мы у “server” запрашиваем “service”, передавая туда UID сервиса (который мы подсмотрели через приложение). Затем нам возвращается Promise, содержащий “service”, у которого мы запрашиваем “characteristic”, передавая её UID (который мы тоже подсмотрели через приложение).

.then(server => server.getPrimaryService(SEND_SERVICE))
.then(service => service.getCharacteristic(SEND_SERVICE_CHARACTERISTIC))

И вот только теперь мы можем уже начинать что-то делать. Например, я запоминаю характеристику в переменную и вешаю обработчики кликов на кнопки. В своих data-атрибутах они содержат код, который будет записан в характеристику при клике.

В обработчиках кликов по кнопкам содержится следующий код:

const code = Number(event.target.dataset.code);

  if (code === 1) {
    toggleLigthCharacteristic.writeValue(Uint8Array.of(code));

    return;
  }

  toggleLigthCharacteristic.readValue()
    .then(currentCode => {
      const convertedCode = currentCode.getUint8(0);

      toggleLigthCharacteristic.writeValue(
        Uint8Array.of(convertedCode === code ? 0 : code)
      );
    });

В характеристику необходимо передавать массив uint8, поэтому для преобразования кода, который будет передан в неё, необходимо использовать Uint8Array.

По задумке, код 1 заставляет светодиоды мигать тремя цветами и затем гаснуть. Но как погасить светодиод, если в него был передан код 3 и светодиод всё ещё горит? Или включить другой цвет?

Я считываю значение, лежащее в характеристике, преобразую его с помощью getUint8 и, если код совпадает, отправляю любое невалидное значение (например 0). Если же значение валидное, то преобразую его в массив unit8 и записываю в характеристику.

Для окончательного решения поставленной задачи необходимо всего лишь научиться отключаться от устройства. У нас уже есть eventListener на кнопке “Disconnect”, в котором происходит отключение от bluetooth-устройства, снимаются eventListeners, кнопки управления прячутся, а в переменные записывается undefined.

myDevice.gatt.disconnect();

toggleItemsEventListeners('removeEventListener');
toggleButtonsVisible();

toggleLigthCharacteristic = undefined;
myDevice = undefined;

Где можно применить связь андроида с ардуино

В первую очередь, необходимо задуматься о том, как применять возможность передачи сигнала с Андроид на Ардуино. Ведь прежде, чем изучать какие-то материалы, каждый здравый человек должен понимать, к чему это его приведёт в итоге. Даже если речь идёт про хобби.

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

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

В таком случае, связку Андроид Ардуино стоит расценивать в двух вариациях:

  1. Удалённое управление каким-либо устройством с помощью смартфона. Ещё его называют связью смартфон-МК. Всё та же техника, например, раздвижные жалюзи или освещение в комнате, которое будет выключаться по одному клику. Если вы захотите сделать последнее, то даже нет необходимости менять проводку или докупать специальные смарт-лампы, которые могут выгореть спустя месяц. Достаточно приобрести небольшой микроконтроллер Ардуино, модуль связи по беспровобному интернету или блютуз и изоленту. После чего достаточно будет спаять простейшую схему, которая замыкается в случае, если подаётся сигнал на МК.
    Сигнал этот будет подаваться с вашего телефона, замыкать контакты, и свет начнет гореть. Чтобы не было проблем и для дополнительной безопасности вашего жилища, можно написать скрипт, способный автоматически размыкать цепь, если устройство управления удаляется из поля видимости. Обычные выключатели всё так же будут работать, но только, когда цепь замкнута.
  2. Передача данных для информирования или связь МК-Смартфон. Здесь вы уже не управляете какой-то техникой, а скорее наоборот, различная техника позволяет получить определённые данные на ваш смартфон. Первое, что приходит на ум и простейшее применение, – датчик движения. Данный модуль имеется в стандартных датчиках для МК Ардуино, купить его не составит проблем, как и вмонтировать в проход. Затем останется написать код, подобие которого уже есть на многих англоязычных форумах, отправляющий СМСку или сообщение в социальных сетях, а также специальной утилите, если кто-то пересечет инфракрасный луч.
    Можно создать и более сложные и автоматизированные системы, которые будут передавать не только медиа-информацию о вашей квартире, но и сообщать, если в домашней оранжерее созреют овощи или фрукты. Всё зависит исключительно от фантазии самого инженера, но основа технологии всё та же – передача данных с одного устройства на другое.

Вот вы выбрали подходящий проект и взялись за его реализацию. Модули и МК уже заказаны, а пока они идут, можно заняться и разработкой ПО. Ведь голый Андроид не взаимодействует с Ардуино при помощи магии.

Двунаправленный обмен данными по bluetooth

Следующим шагом будет написание простенькой программы двунаправленного обмена данными между Arduino и компьютером. В схему я добавил светодиод, подключив его к 12 пину Arduino, через токоограничительный резистор. Но можно использовать и встроенный LED (обычно 13 пин).

char incomingByte;  // входящие данные
int  LED = 12;      // LED подключен к 12 пину

void setup() {
  Serial.begin(9600); // инициализация порта
  pinMode(LED, OUTPUT);
  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!");
    }
  }
}

Программа работает очень просто. После запуска или сброса устройства, в последовательный порт выводится сообщение с предложением нажать 1 или 0. В зависимости от нажатой цифры светодиод будет загораться или гаснуть. А также, от Arduino будет выводиться сообщение загорелся светодиод, или погас.

Видео работы:

Комплектующие для подключения по bluetooth

  1. Bluetooth модуль HC-06 (можно другие, работающие по последовательному протоколу UART. Например HC-05, HM-10,…)
Bluetooth модуль
модуль HC-06

Плата Ардуино, можно взять любую, имеющую выход Rx, Tx. Например, на базовых моделях Arduino UNO, NANO они находятся на выходах 0, 1.

Ардуино с подключенным Bluetooth
Ардуино с подключенным Bluetooth
  1. Bluetooth адаптер или встроенный в ПК модуль bluetooth.
Bluetooth адаптер для ПК
USB Bluetooth адаптер для ПК

Остальные части схемы подключаются по мере необходимости ввода данных в Ардуино или управления каким-то модулем извне.

Метод 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). Андроид, является «головным мозгом», в котором обрабатываются все данные и проводятся вычисления. На основании результатов вычислении по БТ каналу передаются команды, принимаемые БТ модулем и в дальнейшем поступающие по последовательному порту в Arduino.

Arduino обрабатывает поступившие команды и выполняет их при помощи «мышц» (Моторы светодиоды и др.). Кроме того в Arduino поступают данные от «органов чувств» (сенсоры, датчики и др.), которые он приводит в удобный вид и отправляет при помощи БТ модуля в «головной мозг». И так все повторяет до бесконечности.

image


Рисунок 1

Обоснование именно такой схемы робота следующее:

-БТ модуль и Arduino Nano имеют низкую стоимость, а также маленький объем и вес.

-Андроид, не дорогое и доступное устройство, уже имеется у огромного количества людей, в том числе и у меня.

-Андроид имеет свои сенсоры, датчики и экран для вывода информации

-Простота написания кода для приложений как для андроида так и для ардуино.

Для упрощения задачи построения робота, предлагаю воспользоваться методом «от простого к сложному», т.е. как и при изучении языка программирования создадим первую программу «Hello word». Конечно, это будет не одна программа, а как минимум две (для ардуино и андроида). В каждой последующей статье функционал робота будет увеличиваться.

Подключение к пк по последовательному соединению

Удобство соединения Ардуино по Bluetooth состоит в том, что оно происходит по тому же протоколу, что и через USB! Не придется переписывать программу приема данных для этого!Достаточно узнать номер COM порта и задать его в принимающей программе и все.

Кстати, скорость соединения по умолчанию у Bluetooth модуля установлена 9600 бод, поэтому для обеспечения совместимости с передачей по проводному и беспроводному соединению, лучше выбирать именно такую скорость. Если же этого не достаточно, то придется перепрограммировать Bluetooth модуль при помощи AT команд.

Ну а для поиска номера порта можно воспользоваться Диспетчером устройств Windows. Он доступен в панели управления Windows.Откройте ветку «Порты (COM и LPT)» и там найдутся две записи «Стандартный последовательный порт по соединению Bluetooth(COM..)«

Вот тут есть некое отличие от проводного соединения! Создаётся сразу два порта на одно устройство. Один из них для приема, а другой для передачи. Поэтому запомните оба номера и один из них позволит принимать данные через Bluetooth. Отправлять данные в Ардуино нужно по второму.

  1. Передача на ПК в текстовом формате
  2. Передача на ПК в бинарном формате

Если возникнут вопросы или дополнения, пишите в комментариях или в группе ВК.

(с) Роман Исаков, 2023

Подключение модуля hc-06

Для соединения модуля HC-06 или подобного с Ардуино достаточно подключить его к питанию 5 V и GND, а выводы RXD и TXD соединить крест накрест с соответствующими выводами Ардуино. То есть RXD -> Tx, а TXD -> Rx.

Как подключить Ардуино к компьютеру по Bluetooth
Выводы модуля HC-06

Важный момент! Базовые версии Ардуино имеют один UART и он используется для связи по USB (для программирования), поэтому при включенном Bluetooth модуле общаться по USB не удастся! Для программирования Ардуино предусмотрите возможность отключения питания Bluetooth модуля, например отключения линии 5 V. После загрузки прошивки и отключения от USB, питание модуля можно включить, а к Ардуино подключить питание от батареи.

Как подключить Ардуино к компьютеру по Bluetooth
Схема соединения Bluetooth модуля с Ардуино

Последнее приготовление

Итак, мы загрузили скетч, подключили схему к питанию. Что дальше? Для работы с Web Bluetooth API нам необходимо знать имя нашего устройства, и к какому сервису мы хотим получить доступ. Для этого можно воспользоваться приложением “nRF Connect”.

Включаем приложение и видим список bluetooth-устройств рядом с нами (рис. 2).

Рис. 2 (Список устройств, которое нашло приложение)

Устройство с именем “CC41-A” меня заинтересовало и не зря.

После подключения к устройству нам становится доступен список его сервисов (рис. 3). Вряд ли мы найдём что-то интересное в “Device information”, так что смело жмём в “Unknown service”.

Рис. 3 (Список сервисов устройства)

На скриншоте ниже (рис. 4) можно заметить самое главное для нас: запись в характеристику и её чтение.

Когда я решал задачу, описанную выше, то попробовал отправить в характеристику значение «2». В результате чего моя пара светодиодов начала гореть зелёным цветом. Почти успех. Теперь надо сделать тоже самое, но не через мобильное приложение, а через браузер.

Рис. 4 (Unknown характеристика)

Вот список данных, которые мы получили из приложения для продолжения выполнения задачи:

  1. Имя устройства.
  2. UID сервиса.
  3. UID характеристики.

Приготовления

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

Рис. 1 (Схема для сборки)

#include <SoftwareSerial.h>

int green_pin = 2;
int red_pin = 3;
int blue_pin = 4;
int BLINK_STEPS = 3;
int BLINK_DELAY = 100;

SoftwareSerial mySerial(7, 8); // RX, TX

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  pinMode(green_pin, OUTPUT);
  pinMode(red_pin, OUTPUT);
  pinMode(blue_pin, OUTPUT);
}

int code;

void loop() {
  if (mySerial.available()) {
    code = mySerial.read();

    shutDownAll();

    if (code > 0 && code < 5) {
     analogWrite(code, 200);
    }

    if (code == 1) {
      blinked();
    }
  }
}

void shutDownAll() {
  analogWrite(green_pin, 0);
  analogWrite(red_pin, 0);
  analogWrite(blue_pin, 0);
}

void blinked() {
  int steps = 0;

  while(steps <= BLINK_STEPS) {
   analogWrite(green_pin, 200);
   delay(BLINK_DELAY);
   analogWrite(green_pin, 0);
   delay(BLINK_DELAY);
   analogWrite(red_pin, 200);
   delay(BLINK_DELAY);
   analogWrite(red_pin, 0);
   delay(BLINK_DELAY);
   analogWrite(blue_pin, 200);
   delay(BLINK_DELAY);
   analogWrite(blue_pin, 0);
   delay(BLINK_DELAY);

   steps  = 1;
  }
}

Приложения на андроид для взаимодействия с ардуино

Разрабатывать утилиту мы будем не с нуля, ведь это не базис по программирования на java. Проще всего воспользоваться готовыми движками и средами с пользовательским интерфейсом, где вам, буквально, останется дописать 1-2 строчки кода, для расположенной кнопки, чтобы та заработала.

Для начала рассмотрим три базовых файла, которые вы встретите при проектировании программы:

  1. MainActivity.java – это весь код приложения на одноимённом языке, все функции и методы, которые вы записываете, сохраняются сюда.
  2. Activity_main.xml – макет, как несложно догадаться из расширения файла. Сюда сохраняется расположение кнопок, текста и прочих интерактивных компонентов, которые затем оживляются уже в коде.
  3. AndroidManifest.xml – этот файл также относится к макетам, но немного в другой сфере. Он определяет основные параметры для запуска приложения и разрешения, которые тому будут необходимы. В нашем случае это необходимость включить Bluetooth, ведь через него мы будем связываться с МК. Если вы делаете датчик, который должен отсылать информацию на большое расстояние, то, соответственно, необходимо включить и проверить работу беспроводного или мобильного интернета.

Примечание:

Так как Trema-модуль Bluetooth HC-05 установленный на роботе, подключён к аппаратной шине UART, то перед загрузкой скетча робота нужно отсоединить провод, либо от вывода TX модуля, либо от вывода RX на плате Tream-Power Shield, а после загрузки скетча, подсоединить его обратно.

Можно обойтись без добавления кнопки сопряжения к роботу «QUADRUPED», тогда в скетче нужно выполнять сопряжение автоматически при каждой подаче питания робота и пульта. Делается это следующим образом:

В скетче пульта исключите оператор «if» из предпоследней строки кода setup, оставив только тело оператора:

/* Было так:  */ if(varK){while(!objHC05.createMaster("QUADRUPED","1212")){;}} // Если кнопка джойстика нажата при старте ...
/* Стало так: */          while(!objHC05.createMaster("QUADRUPED","1212")){;}  // Теперь bluetooth модулю назначается роль мастера при каждом включении пульта!

В скетче робота исключите целиком все строки в которых встречается константа «pinK» или функция «funWaitMaster()», а код setup() перепишите так:

void setup(){                                                                             //
     funLimbFree();                                                                       // Ослабляем все суставы
     while( !objHC05.begin(Serial)                  ){;}                                  // Инициируем работу с bluetooth модулем, указывая имя объекта или класса для управления шиной UART. При провале инициализации функция begin() вернёт false и тогда оператор while запустит её вновь.
     while( !objHC05.createSlave("QUADRUPED","1212")){;}                                  // Устанавливаем bluetooth модулю роль ведомого с именем "QUADRUPED" и PIN-кодом 1212, ожидающего подключение мастера (список сопряжённых пар будет очищен).
     while( !objHC05.checkConnect()                 ){delay(1000);}                       // Проверка подключения к внешнему Bluetooth устройству.
}                                                                                         //

После внесения этих изменений к роботу можно не подключать кнопку, а при подаче питания не требуется нажимать на джойстик (или кнопку робота), но установка связи между пультом и роботом будет занимать больше времени.

Программа bluetooth rc car – управление роботом-машинкой со смартфона на android

В свой смартфон я установил программу Bluetooth RC Car. На мой взгляд  – это лучшая софтинка для управления роботом-машинкой.

Программа позволяет передавать команды при нажатии на кнопки или реагировать на данные с акселерометра в смартфоне, регулировать скорость движения ползунком, включать передние и задние фонари, включать и выключать звуковой сигнал, включать и выключать сигнал “аварийка”.

Для работы программы требуется Android версии 2.3.3 или выше. Размер программы 3 мегабайта.

Список команд:

  • F – вперед
  • B – назад
  • L – влево
  • R – вправо
  • G – прямо и влево
  • I – прямо и вправо
  • H – назад и влево
  • J – назад и вправо
  • S – стоп
  • W – передняя фара включена
  • w – передняя фара выключена
  • U – задняя фара включена
  • u – задняя фара выключена
  • V – звуковой сигнал включен
  • v – звуковой сигнал выключен
  • X – сигнал “аварийка” включен
  • x – сигнал “аварийка” выключен
  • 0 – скорость движения 0%
  • 1 – скорость движения 10%
  • 2 – скорость движения 20%
  • 3 – скорость движения 30%
  • 4 – скорость движения 40%
  • 5 – скорость движения 50%
  • 6 – скорость движения 60%
  • 7 – скорость движения 70%
  • 8 – скорость движения 80%
  • 9 – скорость движения 90%
  • q – скорость движения 100%

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

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

Принцип передачи команд: при нажатии на кнопку в программе, команда передается по Bluetooth один раз, а при отпускании кнопки сразу передается команда S-остановка.

Программирование платы arduino с помощью технологии bluetooth

Для беспроводного программирования платы Arduino первым делом мы должны написать программу чтобы плата Arduino отвечала на AT команды. Для этого подключите плату Arduino к компьютеру с помощью USB кабеля и загрузите в нее следующий код программы:

В первых двух строках этого кода программы происходит подключение библиотеки последовательной связи SoftwareSerial и указываются передающий и приемный контакты, с помощью которых будет происходить взаимодействие с модулем Bluetooth. Библиотека SoftwareSerial позволяет организовать последовательную связь (последовательный порт) на любых двух цифровых контактах платы Arduino. Также с помощью этой библиотеки можно организовать сразу несколько последовательных портов в плате Arduino.

Далее в функции setup мы установим скорость последовательной передачи данных для аппаратного и программного созданного (с помощью библиотеки SoftwareSerial) последовательных портов – 9600 и 38400 бод соответственно.

Затем в функции loop мы будем использовать два условия (с помощью оператора if). В первом условии мы будем проверять поступает ли какая либо информация от модуля HC05 – если да, то мы будем передавать ее по аппаратному последовательному порту платы Arduino.

Далее подключим модуль HC05 к плате Arduino чтобы она работала в режима приема (и исполнения) AT команд. Схема этого подключения представлена на следующем рисунке:

Перед подключением платы Arduino к компьютеру нажмите key button на Bluetooth модуле и затем подключайте плату к компьютеру. Держите key button в нажатом состоянии до тех пор пока светодиод на Bluetooth модуле не начнет мигать с интервалом 2 секунды.

Теперь откройте монитор последовательного порта и вводите в нем следующие представленные команды. В ответ на эти команды плата должна отвечать сообщением “OK” если команда была выполнена успешно.

AT ORGLAT ROLE=0AT POLAR=1,0AT UART=115200, 0, 0AT INIT

Если все представленные AT команды успешно протестированы, разберите схему и соберите новую схему, представленную на следующем рисунке:

Внешний вид этой схемы, собранной на макетной плате, выглядит следующим образом:

Используйте адаптер питания или батарейку 9V чтобы подать питание на плату Arduino. После этого зайдите в “устройства” (‘Devices’) вашего компьютера (ноутбука) и включите Bluetooth, после чего соединитесь по Bluetooth с модулем HC05.

После того, как Bluetooth соединение между устройствами будет установлено, необходимо определить COM порт компьютера/ноутбука, к которому подключился Bluetooth модуль HC05. Для этого зайдите в диспетчер устройств (‘Device Manager’) и проверьте в нем устройства, которые подключены по COM портам.

Теперь откройте Arduino IDE и в ней выберите пример программы с миганием светодиода, затем выберите необходимый COM порт и нажмите кнопку загрузки программы (upload button). Если все прошло хорошо, то встроенный в плату Arduino светодиод начнет мигать с интервалом в 1 секунду.

Сборка

Можно купить готовое шасси для машинки сразу вместе с моторами и колёсами. Останется только установить электронику и всё подключить.

Но намного интереснее создать это самому. Для изготовления подойдёт любой листовой материал, который вам будет легко обрабатывать, и который достаточно лёгкий. Например, оргалит, текстолит, фанера. Я выбрал оргстекло, что сделало мою машинку даже очень похожей на шасси из магазина.

Из инструментов могут понадобиться:

  • Ручной или электрический лобзик (я пользовался ручным), чтобы отрезать нужные куски от материала.
  • Дрель или шуроповёрт, свёрла.
  • Крепёжные элементы — болты, гайки и саморезы любого подходящего диаметра.

Получилось дёшево и сердито. А главное работает.

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

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

Платы в идеале лучше прикручивать короткими болтами с диаметром 3 мм. Но и таких у меня не оказалось. Поэтому пришлось делать в оргстекле отверстия 2 мм и прикручивать платы саморезами. Держится вполне нормально.

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

Аккумулятор крепится аналогично Bluetooth модулю, только снизу.

И обязательно прикручиваем мебельное поворотное колесо, которое станет опорным, и не будет приводным. Следите за тем, чтобы вся конструкция была в горизонтальном положении, когда стоит на всех трёх колёсах.

Создание приложения

Выбираем File->New->Project.
Window
Так как мы создаём приложение для android, выбираем Android-> Android Application Project, и нажимаем Next
Window2
Так как мы создаём приложение для android, выбираем Android-> Android Application Project, и нажимаем Next
Arduino: Bluetooth-модули и управление контроллером по беспроводной связи

Следующее диалоговое окно:
Window3
Application Name -> пишем имя приложение,
Project Name -> пишем имя проекта,
Package Name -> Ни чего не пишем он создается автоматически!
Minimum Required SDK -> это минимальные требование указываем нашу версию Android у меня 4.1 её я и выбираю.
Target SDK -> выбираем вашу версию Android
Compile with -> выбираем вашу версию Android
Theme: для начала я бы советовал выбрать None.
Нажимаем Next.
В следующем окне ничего менять не нужно. Просто жмем Next.
Window4
Application Name -> пишем имя приложение,
Project Name -> пишем имя проекта,
Package Name -> Ни чего не пишем он создается автоматически!
Minimum Required SDK -> это минимальные требование указываем нашу версию Android у меня 4.1 её я и выбираю.
Target SDK -> выбираем вашу версию Android
Compile with -> выбираем вашу версию Android
Theme: для начала я бы советовал выбрать None.
Нажимаем Next.
В следующем окне ничего менять не нужно. Просто жмем Next.
Arduino: Bluetooth-модули и управление контроллером по беспроводной связи

Далее нам предлагают создать свою иконку для приложения, можете изменить стандартный ярлык загрузив свою картинку, я же для начала предлагаю просто нажать Next.
Window5
В следующем необходимо выбрать пункт меню Blank Activity и нажимать Next.
Window6
В следующем необходимо выбрать пункт меню Blank Activity и нажимать Next.
Arduino: Bluetooth-модули и управление контроллером по беспроводной связи

Жмем Finish и через несколько секунд открывается главное окно нашей программы. Выбираем вкладку Activity_main.xml и видим наш редактор:
Window7

Схема подключения

Питание платы берётся от «Кроны» и подаётся на Arduino через пины VIN и GND. Также подаётся отдельно на драйвер двигателей через порты 12V и GND.

Blutooth модуль HC-06 получает питание в 3,3 вольта от Arduino. Если подключить к 5 вольтам, то тоже работает нормально. Выход RX модуля подключается к TX на Arduino, а TX — в RX, то есть наоборот.

На драйвере двигателей нужно снять две боковые перемычки — Enable. Пины под ними позволят нам управлять скоростью вращения двигателей. И эти пины подключаются к Arduino обязательно к ШИМ-портам (обозначенные знаком ~). На схеме это порты 3 и 5.

Питание моторов подаётся на Input драйвера от Arduino с портов 2 и 4, 6 и 7. А сами моторы подключаются к Output A и Output B драйвера.

Если после сборки и прошивки, вы подаёте на машинку сигнал двигаться вперёд, а оба колеса при этом вращаются в разных направления, то нужно поменять местами провода на одном из моторов в выходе Output.

Если при движении вперёд машинка едет назад, то нужно поменять местами провода Output обоих двигателей (хотя, кто знает, где у ней перед, а где зад…).

Если при повороте налево, машинка едет направо, то нужно поменять местами Output A и Output B.

Если подключить всё по схеме, то скетч переделывать не нужно будет.

Схема подключения робота quadruped:

Соберите механику, подключите Tream-Power Shield, сервоприводы, датчик расстояния и откалибруйте робота, как это описано на странице Сборка QUADRUPED. Электроника Калибровка. Далее на боковые панели установите Bluetooth HC-05 и кнопку, первый модуль подключается к шине UART (в примере используется аппаратная шина UART), а второй к любому выводу Arduino Uno (в примере используется вывод D12).

Вы можете изменить выводы 2 и 3 для подключения датчика HC-SR04 на любые другие, указав их в скетче при объявлении объекта objSensor.

СервоприводыTrema Power Shield
1 конечностьГоризонтальный сустав (№ 0)вывод 4 на белой колодке
Вертикальный сустав (№ 1)вывод 5 на белой колодке
2 конечностьГоризонтальный сустав (№ 2)вывод 6 на белой колодке
Вертикальный сустав (№ 3)вывод 7 на белой колодке
3 конечностьГоризонтальный сустав (№ 4)вывод 8 на белой колодке
Вертикальный сустав (№ 5)вывод 9 на белой колодке
4 конечностьГоризонтальный сустав (№ 6)вывод 10 на белой колодке
Вертикальный сустав (№ 7)вывод 11 на белой колодке

Вы можете изменить выводы 4-11 для подключения сервоприводов на любые другие, указав их в скетче при объявлении массива объектов pinServo[8]. Трехпроводные шлейфы сервоприводов устанавливаются следующим образом:

  • Оранжевый провод подключается к выводу на белой колодке.
  • Красный провод подключается к выводу на красной колодке.
  • Коричневый провод подключается к выводу на чёрной колодке.
BluetoothTrema Power Shield
Bluetooth HC-05вывод RXвывод TX на колодке Serial
вывод TXвывод RX на колодке Serial
вывод K (Key)вывод A0 на белой колодке
вывод V (Vcc)любой вывод на красной колодке
вывод G (GND)любой вывод на чёрной колодке

Вы можете изменить вывод A0 для подключения Bluetooth на любой другой, указав его в скетче при объявлении объекта objHC05.

Выводы RX и ТХ модуля подключаются проводами к выводам TX и RX колодки с надписью Serial. Трёхпроводной шлейф подключённый к выводам K, V, G, устанавливается следующим образом:

  • Вывод K (Key) подключается к выводу на белой колодке.
  • Вывод V (Vcc) подключается к выводу на красной колодке.
  • Вывод G (GND) подключается к выводу на чёрной колодке.
КнопкаTrema Power Shield
Trema-кнопкавывод S (Signal)вывод 12 на белой колодке
вывод V (Vcc)любой вывод на красной колодке
вывод G (GND)любой вывод на чёрной колодке

Вы можете изменить вывод D12 для подключения кнопки на любой другой, указав его в скетче при определении константы pinK.

Трёхпроводной шлейф подключённый к выводам S, V, G, устанавливается следующим образом:

  • Вывод S (Signal) подключается к выводу на белой колодке.
  • Вывод V (Vcc) подключается к выводу на красной колодке.
  • Вывод G (GND) подключается к выводу на чёрной колодке.

Представленная ниже схема совпадает со схемой из инструкции по сборке QUADRUPED, но к ней добавились два модуля: bluetooth (подключается к выводам A0, TX и RX) и кнопка (подключается к выводу D12).

Элементы схемы: «Э0»…«Э7» – сервоприводы, «Э8» – датчик расстояния, «Э9» – Trema bluetooth модуль, «Э10» Trema кнопка.

Управление:

Сразу после сборки, загрузки скетча и подачи питания на пульт, и QUADRUPED, суставы робота будут ослаблены, и он не будет реагировать на команды с пульта, так как Bluetooth модулям требуется сопряжение (создание пары). Сопряжение достаточно выполнить только один раз, bluetooth модули запомнят созданную пару в своей энергонезависимой памяти и будут пытаться соединится друг с другом при каждой последующей подаче питания.

  • Отключите питание пульта (если оно было подано), нажмите на джойстик (как на кнопку) и подайте питание пульта. После выполнения этих действий bluetooth модулю пульта будет назначена роль мастера и он начнёт поиск ведомого с именем «QUADRUPED» и PIN-кодом «1212».
  • Подключите питание робота (если оно не было подано), нажмите и удерживайте кнопку сопряжения не менее 1 секунды (её можно нажимать в любое время). После нажатия на кнопку, bluetooth модулю робота будет назначена роль ведомого с именем «QUADRUPED» и PIN-кодом «1212», и он будет ожидать подключение мастера.
  • Для выполнения повторного сопряжения (если оно потребуется) нужно выполнить те же действия как для пульта, так и для робота.
  • Как только связь будет установлена, суставы робота «оживут» и он будет выполнять команды пульта. Если Вы отключите питание пульта, то суставы робота ослабнут и вновь оживут при подаче питания пульта.

Управление роботом с пульта выполняется следующим образом:

  • Если отклонить джойстик вперёд, то и робот пойдёт вперёд, а скорость будет зависеть от степени отклонения джойстика.
  • Если отклонить джойстик назад, то и робот пойдёт назад, а скорость будет зависеть от степени отклонения джойстика.
  • Если отклонить джойстик вперёд и влево, или вправо, то и робот пойдёт вперёд заворачивая влево, или вправо. Скорость будет зависеть от степени отклонения джойстика вперёд, а радиус поворота от степени отклонения джойстика влево, или вправо.
  • Если отклонить джойстик назад и влево, или вправо, то и робот пойдёт назад заворачивая влево, или вправо. Скорость будет зависеть от степени отклонения джойстика назад, а радиус поворота от степени отклонения джойстика влево, или вправо.
  • Если отклонить джойстик влево или вправо, но не отклонять его вперёд, или назад, то робот начнёт разворачиваться на месте влево, или вправо, а скорость разворота будет зависеть от степени отклонения джойстика.
  • Если нажать на джойстик (при включённом питании), то все суставы конечностей робота установятся в центральные положения.
  • Если поворачивать ручку потенциометра по часовой стрелке, то корпус робота будет подниматься, вне зависимости от положения джойстика.
  • Если поворачивать ручку потенциометра против часовой стрелке, то корпус робота будет опускаться, вне зависимости от положения джойстика.
Оцените статью
Радиокоптер.ру
Добавить комментарий