Взаимодействие nRF24L01 с Arduino: удаленное управление серводвигателем

Взаимодействие nRF24L01 с Arduino: удаленное управление серводвигателем Квадрокоптеры

Что такое сервопривод?

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

Другими словами, сервопривод – это довольно сложная система. Он управляется однопроводным ШИМ-сигналом. Импульсы подаются с интервалом 20 мс и длительностью от 1 до 2 мс, что соответствует крайним угловым положениям (от 0* до 180*, соответственно). В среду для Arduino встроена библиотека Servo.h.

Arduino – машинка на управлении по bluetooth 4.0 (ble) со смартфона

Всем доброго утра.

Вот вам мой маленький проект Bluetooth автомобиля.

Проект сделан для обкатки технологии передачи данных со смартфона на Arduino по протоколу BLE (bluetooth 4.0)

Меня очень интересовали модели RU, и в коробке с неработающими аппаратами 433 МГц, которые я нашел по всему дому, я решил оживить этот аппарат.

Смотрите про коптеры:  Машинка на Arduino, управляемая Android-устройством по Bluetooth, — полный цикл (часть 1) / Хабр

Проект состоит из двух программных компонентов.

  • Приложение на Android, работающее по протоколу BLE.
  • Собственно код на Arduino

Для создания мобильного приложения на C# мы использовали фреймворк Xamarin.

Она не претендует на релизную версию для размещения в Play Market, поэтому не спешите судить.

Если кто-то хочет ознакомиться с кодом или внести новые функции в свой проект, пожалуйста, воспользуйтесь ссылкой

Конструкция управления с использованием Bluetooth 4.0

Для тех, кто хочет использовать приложение как есть, вот ссылка

Джойстик

.

Насколько я знаю, это приложение работает только на Android 6.0 и выше, с разрешением 1980×1020 (другие разрешения не тестировались), на устройствах с поддержкой BLE (как это проверить, смотрите в интернете), так что не пинайте.

В этом кратком руководстве я покажу, как использовать текущую версию.

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

  • Два стика – левый дроссель, правый руль.
  • После нажатия кнопки BLUETOOTH – окно поиска устройства и подключения.
  • После нажатия кнопки SETUP – окно с конечными точками и интервалом отправки данных на Arduino (создано для универсального использования с любой конфигурацией устройства)
  • Главное окно с индикатором подключения и привязками.

А теперь часть кода Arduino.

#include<SoftwareServo.h>#include<timer-api.h>#include<timer_setup.h>#include<SoftwareSerial.h>constint FwdPin =5;constint BwdPin =6;constint ServoPin =9;
SoftwareSerial mySerial(11,12);
SoftwareServo servo;

byte data[5];short prevXPos, prevYPos, xPos, yPos;bool light;voidsetup(){
  mySerial.begin(9600);sendCommand("AT");sendCommand("AT ROLE0");sendCommand("AT NAMEbluino");

  servo.attach(ServoPin);
  servo.setMaximumPulse(2200);pinMode(FwdPin, OUTPUT);pinMode(BwdPin, OUTPUT);timer_init_ISR_500Hz(TIMER_DEFAULT);}voidsendCommand(constchar* command){
  mySerial.println(command);delay(100);

  byte reply[100];int i =0;while(mySerial.available()){
    reply[i]= mySerial.read();
    i  =1;}}voidloop(){int i =0;while(i !=5){while(mySerial.available()){
        data[i]= mySerial.read();
        i  =1;}}
   xPos =(data[1]<<8)|(data[0]);
   yPos =(data[3]<<8)|(data[2]);
   light = data[4];
   SoftwareServo :: refresh ();}voidtimer_handle_interrupts(int timer){if(xPos <0){
    xPos = xPos *-1;}if(yPos <0){
    yPos = yPos *-1;if(prevYPos != yPos){
      prevYPos = yPos;analogWrite(FwdPin,0);analogWrite(BwdPin, yPos);}}else{if(prevYPos != yPos){
      prevYPos = yPos;analogWrite(FwdPin, yPos);analogWrite(BwdPin,0);}}if(prevXPos != xPos){
     prevXPos = xPos;
     servo.write(xPos);}}

Список китайских модулей, используемых в этой машине.

Мне также нужна сама Arduino (у меня UNO), я выбрал ее, потому что все мое питание происходит от 2s Li-po, и она может подавать до 10 вольт.

Мотор и корпус коллектора (как я писал выше, он достался мне от старой модели с мотором). Благодаря двигателю вы можете заменить драйвер на ESC.

Схему рисовать не буду (посмотрев в редактор, половину устройств нет, искать их лень).
Подключается все не сложно. По пинам скажу на bluetooth RXD -> pin 12, TXD -> pin 11, остальное понятно по коду.

Пример возрожденного станка из прошлого с новым оборудованием

Здесь

Circuit diagram

Circuit diagram for this Arduino Bluetooth Servo Motor Control project is given below:

Code and explanation

The complete code for Arduino Control Servo Motor Via Bluetooth is given at the end.

Arduino has library for Servo Motors and it handles all the PWM related things to rotate the servo, you just need to enter the angle to which you want to rotate and there is function servo1.write(angle); which will rotate the servo to desired angle.

Итак, мы начнем с определения библиотеки для серводвигателя, а библиотека Serial Software используется для определения выводов Rx и Tx.

#include <SoftwareSerial.h>#include <Servo.h>

В приведенном ниже коде мы инициализируем контакты Arduino для Rx и Tx, задаем переменные для сервопривода и другие вещи.

Servo myServo;
int TxD = 11;
int RxD = 10;
int servoposition;
int servopos;
int new1;
SoftwareSerial bluetooth(TxD, RxD);

Теперь установите все переменные и компоненты на начальную стадию. Здесь мы подключили сервопривод к девятому контакту Arduino и установили базовое положение сервопривода на 0 градусов. Скорость передачи данных для последовательной связи и связи Bluetooth также установлена на 9600.

void setup() {  int pos=0;  myServo.attach(9);  myServo.write(0);  Serial.begin(9600);       // start serial communication at 9600bps  bluetooth.begin(9600);}

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

If the value is 0 the servo will rotate to 0 degree. Similarly if we send 45, 90, 135 and 180 from the Bluetooth application, the servo will rotate to 45, 90, 135 and 180 degree angle respectively.

void loop() { if (bluetooth.available()){    String value = bluetooth.readString();    servoposition = value.toInt();    if (value.toInt() == 0){      Serial.println(servoposition);    myServo.write(0);      }      if (value.toInt() == 45){      Serial.println(servoposition);    myServo.write(45);      }
      if (value.toInt() == 90){      Serial.println(servoposition);    myServo.write(90);      }      if (value.toInt() == 135){      Serial.println(servoposition);    myServo.write(135);      }      if (value.toInt() == 180){      Serial.println(servoposition);    myServo.write(180);      }

If we send the value ‘1’ by pressing Start button then servo will rotate continuously until stop button is pressed. Here we are sending ‘2’ on pressing stop button, which will be read by the Arduino and it will break the while loop and servo will be stopped.

   while(value.toInt()==1){
    if (bluetooth.available())
   {
    value = bluetooth.readString();
    Serial.println(value);

    if (value.toInt()==2)
    {Serial.println("YYY");  break; }
   }
    servopos  ;
    delay(30);
    Serial.println(servopos);
    myServo.write(servopos);

    if (servopos ==180 )
    {servopos=0;break;}   
  }    
 }
}

Configuring roboremo app for controlling servo:

Шаг 1:- Скачайте приложение Roboremo из Android Play Store и установите его на свой смартфон. После установки вы увидите окно приложения, показанное на рисунке 1, а когда вы нажмете кнопку “Меню”, вы увидите окно, показанное на рисунке 2 ниже:

Figure1Figure2

Step 2:- Then click on connect button and you will see the window shown in figure3 below then you have to select ‘Bluetooth RFCOMM’ and then you will be able to connect your HC-06 bluetooth module with your android app ‘Roboremo’.

Figure3

Hc-06 bluetooth module

Bluetooth может функционировать в следующих двух режимах:

  1. Командный режим
  2. Рабочий режим

In Command Mode we will be able to configure the Bluetooth properties like the name of the Bluetooth signal, its password, the operating baud rate etc. The Operating Mode is the one in which we will be able to send and receive data between the PIC Microcontroller and the Bluetooth module.

Поэтому в данном руководстве мы рассмотрим только рабочий режим. В командном режиме будут восстановлены настройки по умолчанию. Имя устройства – HC-05 (я использую HC-06), пароль – 0000 или 1234, и, самое главное, скорость передачи данных по умолчанию для всех модулей Bluetooth – 9600.

Модуль работает при напряжении питания 5 В, а сигнальные выводы – при 3,3 В, поэтому в самом модуле установлен регулятор на 3,3 В. Поэтому нам не нужно беспокоиться об этом. Из шести выводов только четыре используются в режиме работы. Таблица подключения выводов показана ниже

S.NoPin on HC-05/HC-06Pin name on MCUPin number in PIC
1VccVdd31st pin
2VccGnd32nd pin
3TxRC6/Tx/CK25th pin
4RxRC7/Rx/DT26th pin
5StateNCNC
6EN (Enable)NCNC

Смотрите другие наши проекты, чтобы узнать больше о работе модуля Bluetooth HC-05 с другими микроконтроллерами

Смотрите также все проекты, связанные с bluetooth здесь.

Servo sg90 подключение серво и управление с телефона

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

Управление мотором происходит с помощью этого ползунка с экрана монитора или телефона.
Это немного изменённый код из видео про управление яркостью светодиода. Посмотреть его можно вот по этой ссылке. Здесь я не буду повторяться, а расскажу только то что было изменено и только то что касается сервомотора. Если, что вам будет не понятно то смотрите это видео.

Сначала вам нужно просто подключить серводвигатель и управлять им. Для этого скачайте скетч из библиотеки SERVO или мой скетч из архива. В описании вы всегда найдете ссылку на архив. Библиотеку не нужно устанавливать. Она входит в стандартную установку среды разработки ARDUINO IDE.

Я думаю, что скетч четко описан и прокомментирован. Сначала сервопривод центрируется. под углом 90 градусов. В течение 3 секунд положение поворачивается на 45 градусов. Затем, когда оно достигает конца, 180 градусов, оно снова возвращается к нулю, и цикл начинается заново.

Я использовал транспортир, чтобы нарисовать отметки, где сервопривод должен остановиться. Я не знаю, был ли у меня один неисправный сервопривод, или все они, но из 5 единиц, которые были у меня в наличии, ни одна не дала нужных результатов. Я не уверен, что это 0 и 180 градусов, даже если я перемещаю его вручную, и среднее значение не очень хорошее. Может быть, мне повезет, и я получу более качественные сервоприводы. Итак, посмотрим, работает ли двигатель – это показывает, что он правильно подключен, и мы можем переходить к следующему шагу.

Здесь мы задаём цикл от 0 до 180 градусов с шагом в 1 градус и паузой в 15 миллисекунд для того чтобы он успел переместиться в новое положение. Так как серво не будет ждать успеет ли переместиться в заданное положение, а начнёт выполнять новую команду. Поэтому надо обязательно дать время на выполнение предыдущей команды.
Дойдя до крайнего положения, мотор, после паузы в 3 секунды начнёт обратных ход.

Давайте посмотрим как это работает. Видим, что серво плавно, без рывков двигается от 0 до 180 градусов. Потом подождав, возвращается на место. Если у вас движение происходит рывками, то это значит у вас не хватает питания и надо подключить отдельное питание на 5 вольт.
У меня есть ещё одно видео, где я подробно рассматриваю два типа серв. Один – это сервы с движением от 0 до 180 градусов, а второй это сервомоторы непрерывного движение. Посмотреть можно здесь.

Изменять скорость движения можно двумя способами.
Первый это уменьшением паузы, а второй – это увеличением количество шагов пройденных за одну итерацию цикла. Увеличим скорость в 10 раз. Датчик стал двигаться быстрее- это сразу стало заметно.
Это происходит потому, что теперь мотор проходит не 180 шагов, а всего лишь 18 и соответственно пауз осталось тоже 18. За счёт этого и происходит увеличение скорости. И положение конечных точек осталось на месте. Всё так же 0 и 180. В следующем примере объясню о чём это я.

Теперь сделаем шаги с интервалом в 50.
Теперь мотор сделает всего лишь 3 шага. Это 0, 50, 100 и  150 в одну сторону.
И 180, 130, 80 и 30 в другую. И как я говорил количество пауз тоже уменьшилось. А ещё теперь мотор не может дойти до своих крайних точек.

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

Это делается путем загрузки второго скетча из архива. Во многом этот скетч является копией урока об управлении яркостью светодиода. Поэтому я не буду объяснять, как установить библиотеки и как настроить сеть. Здесь вам нужно ввести имя сети и пароль. Пожалуйста, посмотрите видео, если вы не понимаете, о чем я говорю.

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

  • Title – отвечает за заголовок страницы.
  • Установите шрифт Arial и выровняйте его по центру страницы.
  • Установите размер заголовка на это значение, а размер, жирность и цвет числовых значений – на это значение.
  • Установите ширину и цвет фона тела.
  • Здесь представлены различные настройки слайдера. Отступы, ширина, высота, цвет фона. Для FIREFOX существуют отдельные настройки.

Это заголовок 2 уровня.
Эта строка отвечает за отправку значений из слайдера. Оно как и практически всё в Ардуино в диапазоне от 0 до 1023.
Про javascript я рассказывать не буду – это довольно сложно. Скажу только, что эта строчка отвечает за вывод значения на экран. Так как сюда нельзя вставить функцию map, мне пришлось сделать деление на 5.68. Получил я эту цифру разделив 1023 на 180. А это get запрос в  который передаётся значение от слайдера и всё это отправляется на сервер.

В setup нам нужно только установить скорость, указать к какому контакту подключена серва и передать в get значение от 0 до 180. Вот здесь мы воспользуемся стандартной Ардуиновской функцией map.
Вот и все настройки. Теперь снова посмотрим как это работает. Уже зная и умея создавать такие сложные страницы.

Если вам интересна эта тема, то я могу снять ещё много видео про сервомоторы и не только.
Объём вашего интереса, я буду оценивать по количеству лайков и комментариев. Чем их будет больше, тем быстрее выйдет новое видео.
Ну, а если вам нравятся мои уроки, то ставьте лайк и делитесь моими видео с другими. Это очень поможет мне в продвижении канала, а меня будет стимулировать выпускать уроки чаще и интереснее.
Вы видите ссылки на видео, которые, я думаю будут вам интересны. Перейдя на любое из этих видео вы узнаете что-то новое, а ещё поможете мне.
Спасибо.
А пока на этом всё. До встречи в новых видео.  И ещё раз спасибо за то, что досмотрели до конца.
Пока!!!

Working of servo motor control using bluetooth:

In this project, we are controlling the Servo Motor using an Android application “Roboremo”. In this application’s interface, we have created 5 buttons to control the Servo motor as explained earlier. The working of every button is given in the below table:

S.No.Button NameSending Value Description
1. Start 1 This button is used to start rotating the servo from 0⁰ to 180⁰.
2. Stop 2 This button is used to stop the servo at any point.
3. 0⁰ 0 This button is used to rotate the servo to 0⁰.
4. 90⁰ 90 This button is used to rotate the servo to 90⁰.
5. 180⁰ 180 This button is used to rotate the servo to 180⁰.

So, by pressing these buttons on your Android app Roboremo, the data will be sent through the smartphone’s Bluetooth to HC-06 Bluetooth module. From that HC-06 module data is received by the Arduino and Arduino rotates the Servo at the angle defined in the code for the particular button.

Беспроводное управление серводвигателем с помощью nrf24l01

Тестовый макет для проекта
Тестовый макет для проекта

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

Работа проекта показана в демонстрационном видеоролике ниже. Вполне нормально, если эти модули не работают с первой попытки. Если возникли проблемы, проверьте код и макет еще раз, а затем воспользуйтесь приведенными выше рекомендациями по устранению неполадок.

Взаимодействие nrf24l01 с arduino

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

Вот схема подключения модуля nRF24L01 к Arduino. В качестве изменения я использовал Nano для передачи и UNO для приема. Однако для таких плат Arduino, как Mini и Mega, логика подключения остается прежней.

Видео

Оригинал статьи:

Знакомство с rf модулем nrf24l01

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

Благодаря интерфейсу SPI микросхема может взаимодействовать практически со всеми типами микроконтроллеров. Благодаря библиотекам Arduino сделать это становится намного проще. Стандартная распиновка модуля nRF24L01 показана ниже.

Распиновка модуля nRF24L01
Распиновка модуля nRF24L01

Модуль работает в диапазоне от 1,9 до 3,6 вольт (обычно 3,3 вольта). При использовании с батарейками модуль потребляет очень маленький ток – всего 12 мА, что делает его эффективным при использовании, поэтому он может работать даже с батарейками размером с монету.

Несмотря на то, что рабочее напряжение составляет 3,3 В, большинство выводов могут работать с напряжением 5 В и поэтому могут быть напрямую подключены к 5-В микроконтроллерам, таким как Arduino. Кроме того, в каждом модуле имеется шесть каналов связи (конвейеров).

В принципе, каждый модуль может одновременно взаимодействовать с шестью другими модулями. Благодаря этому модули подходят для создания звездных и ячеистых сетей в приложениях IoT. Кроме того, у них широкий диапазон адресов – 125 уникальных идентификаторов, поэтому в замкнутом пространстве мы можем использовать 125 таких модулей, не мешая друг другу.

Передающая часть: подключение модуля nrf24l01 к arduino nano

Передающая часть: подключение модуля nRF24L01  Arduino Nano. Схема соединений
Передающая часть: подключение модуля nRF24L01 Arduino Nano. Схема соединений

Передатчик и приемник подключены таким же образом. Дополнительно я использовал потенциометр, подключенный к выводам 5V и GND Arduino. На вывод A7 Arduino Nano поступает аналоговое выходное напряжение, которое изменяется в диапазоне от 0 до 5 вольт. Питание обеих плат осуществляется через порт USB.

Приемная часть: подключение модуля nrf24l01 к arduino uno

Приемная часть: подключение модуля nRF24L01  Arduino Uno. Схема соединений
Приемная часть: подключение модуля nRF24L01 Arduino Uno. Схема соединений

N RF24L01 взаимодействует с помощью SPI, как я упоминал ранее. Пины 11, 12 и 13 используются Arduino Nano и UNO для связи по SPI. Для этого подключите MOSI, MISO и SCK от nRF к контактам 11, 12 и 13 соответственно.

Можно изменить программу, чтобы использовать любой вывод CE или CS. Здесь я использовал выводы 7 и 8, но вы можете выбрать любой вывод. Модуль nRF питается от вывода 3,3 В на Arduino, что в большинстве случаев работает. Отдельный источник питания может решить вашу проблему.

Программирование nrf24l01 для arduino

Использовать эти модули с Arduino очень просто благодаря готовой библиотеке, созданной maniacbug на GitHub. Нажмите на ссылку, чтобы загрузить библиотеку в виде zip-папки, и добавьте ее в IDE Arduino с помощью Sketch → Include Library.

→ Добавьте . ZIP библиотеку. После добавления библиотеки в проект мы можем приступить к его программированию. Один модуль должен быть написан для передающей части, другой – для приемной. Однако модули могут служить как передатчиками, так и приемниками, как я уже говорил.

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

Все программы начинаются с заголовочных файлов. Поскольку nRF использует протокол SPI, мы включили заголовочный файл SPI вместе с только что загруженной библиотекой. Серводвигатели управляются с помощью библиотеки servo.

#include<SPI.h>#include"RF24.h"#include<Servo.h>

Здесь есть еще одна линия, которая имеет решающее значение: мы указываем контакты CE и CS. На схеме видно, что CE подключен к контакту 7, а CS – к контакту 8.

RF24 myRadio (7,8);

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

struct package
{int msg;};typedefstruct package Package;
Package data;

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

Работа с беспроводным приемопередающим модулем nrf24l01

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

  1. Большинство модулей nRF24L01 на рынке являются подделками. Самые дешевые, которые можно найти на Ebay и Amazon, являются худшими (не волнуйтесь, с помощью нескольких трюков мы можем заставить их работать).
  2. Основная проблема заключается в источнике питания, а не в вашем коде. Большинство примеров кода, доступных в Интернете, работают нормально.
  3. Обратите внимание, что модули с маркировкой NRF24L01 на самом деле являются Si24Ri (да, это китайский продукт).
  4. Клоны и поддельные модули будут потреблять больше тока, поэтому не разрабатывайте схему питания на основе спецификации nRF24L01, так как Si24Ri будет потреблять большой ток, около 250 мА.
  5. Остерегайтесь волн напряжения и скачков тока, эти модули очень чувствительны и могут легко сломаться (на данный момент я поджарил 2 модуля).
  6. Добавление пары конденсаторов (10 мкФ и 0,1 мкФ) между Vcc и Gnd на модуле помогает очистить источник питания; это подходит для большинства модулей.

Однако если у вас возникнут какие-либо проблемы, опишите их в комментариях.

Удаленное управление сервоприводом по последовательному порту ардуино

Вы можете отправлять команды через последовательный UART-порт Arduino для дистанционного управления приводом. С помощью USB, UART или Bluetooth вы можете управлять им с ПК, смартфонов, а также других устройств.

Модель такая же, как и в первом случае:

Эта программа получает от последовательного порта строку, представляющую угол желаемого отклонения сервопривода, а затем медленно перемещает рычаг на этот угол. Затем она снова ожидает команды. Используя эту информацию, можно определить угол поворота сервопривода.

#include

#define servo_pin 8
#define servo_speed 10 // Задержка перемещения рычага сервы
uint32_t servo_T = 0;
byte pos=90, newpos=90; // текущая и требуемая позиция сервы
Servo servo1;

void setup() {
servo1.attach(servo_pin);
servo_T = millis();
Serial.begin(9600); // Запуск последовательного порта
servo1.write(pos); // Установка сервы на угол 90*
delay(1000); // Ждем пока серва перейдет на нужный угол (не гарантировано!)
Serial.println(“Ready to command!”); // Подача сообщения о готовности в порт
}

void loop() {
if ( Serial.available()) { // Если принята команда
newpos = Serial.parseInt(); // Принять полученную строку и перевести её в целое число
newpos = constrain(newpos, 0, 180); // Ограничить число 0…180
}
if ((newpos != pos)&&(millis() – servo_T >= servo_speed)) { // Прерывание для обработки перемещения сервы, если позиция отличается
servo_T = millis();
if (newpos > pos){ // Если новая позиция больше текущей
pos ; // Повысить текущую на 1
} else { // …иначе
pos–; // Понизить на 1
}
pos = constrain(pos, 0, 180); // Ограничить число 0…180
servo1.write(pos); // Перемесить серву на полученный угол
Serial.print(“Status: “); // Показать текущий угол оператору через порт
Serial.println(pos);
if (pos == newpos) Serial.println(“Completed!”); // Если угол достиг цели – уведомить оператора
}
}

#include <Servo.h>

#define servo_pin 8
#define servo_speed 10 // Задержка перемещения рычага сервы
uint32_t servo_T = 0;
byte pos=90, newpos=90; // текущая и требуемая позиция сервы
Servo servo1;

void setup() {
	servo1.attach(servo_pin);
	servo_T = millis();
  	Serial.begin(9600); // Запуск последовательного порта
  	servo1.write(pos); // Установка сервы на угол 90*
  	delay(1000); // Ждем пока серва перейдет на нужный угол (не гарантировано!)
  	Serial.println("Ready to command!"); // Подача сообщения о готовности в порт
}

void loop() {
  if ( Serial.available()) { // Если принята команда
    newpos = Serial.parseInt(); // Принять полученную строку и перевести её в целое число
    newpos = constrain(newpos, 0, 180); // Ограничить число 0…180
  }
  if ((newpos != pos)&&(millis() - servo_T >= servo_speed)) { // Прерывание для обработки перемещения сервы, если позиция отличается
    servo_T = millis();
    if (newpos > pos){ // Если новая позиция больше текущей 
      pos  ; // Повысить текущую на 1
    } else { // …иначе
      pos--; // Понизить на 1
    }
    pos = constrain(pos, 0, 180); // Ограничить число 0…180
    servo1.write(pos); // Перемесить серву на полученный угол
    Serial.print("Status: "); // Показать текущий угол оператору через порт
    Serial.println(pos);
    if (pos == newpos) Serial.println("Completed!"); // Если угол достиг цели – уведомить оператора
  }
}

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

(c) Роман Исаков, 2020 год

Управление несколькими сервоприводами по блютуз – бредборд q&a

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

Помогите, ребята.

Я просмотрел много сайтов и не нашел ничего подобного.

код arduino ide:

#include <Wire.h>
#include <Multiservo.h>
String readString;
Multiservo myservo1,myservo2;

int servo1pos;
int servo2pos;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600); 
myservo1.attach(16);
myservo2.attach(17);

myservo1.write(7);
myservo2.write(7);
}

void loop() {
// put your main code here, to run repeatedly:

while (Serial.available()) {
delay(3);  //delay to allow buffer to fill 
if (Serial.available() >0) {
char c = Serial.read();  //gets one byte from serial buffer
readString = c; //makes the string readString

}

  if (readString.length() >0)
{
Serial.println(readString); //see what was received
int commaIndex = readString.indexOf(‘ ‘);
String firstValue = readString.substring(0, commaIndex);
servo1pos = firstValue.toInt();
if ((servo1pos > 0) & (servo1pos < 180)) {    
myservo1.write(servo1pos);
delay(15); 
}
}
if(readString.length() >0)
{
Serial.println(readString); //see what was received
int commaIndex = readString.indexOf(‘ ‘);
String firstValue = readString.substring(0, commaIndex);
servo2pos = firstValue.toInt();
if ((servo2pos > 0) & (servo2pos < 180)) {    
myservo2.write(servo2pos);
delay(15); 
}
}
//очистим строку
readString = “”;

}

код Android Studio MainActivity:

package com.example.manipulator;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Handler;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.bluetooth.*;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;



publicclassMainActivityextendsAppCompatActivity {private TextView mTextValue;
    public SeekBar mSeekBar1;
    public SeekBar mSeekBar2;

    finalint ArduinoData = 1;
    privatestaticfinalint REQUEST_ENABLE_BT = 0;
    final String LOG_TAG = "myLogs";
    public BluetoothAdapter btAdapter;
    private BluetoothSocket btSocket = null;
    privatestatic String MacAdress = "98:DA:60:00:52:37";
    privatestaticfinal UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private ConnectedThred MyThred = null;

    public TextView mytext;

    Handler h;

    privateint servo1pos,servo2pos;

    @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btAdapter = BluetoothAdapter.getDefaultAdapter();
        mytext = (TextView) findViewById(R.id.textView);


        if (btAdapter != null){
            if (btAdapter.isEnabled()){
                mytext.setText("Bluetooth включен");
            }else
            {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }

        }else
        {
            MyError("Fatal Error", "Bluetooth ОТСУТСТВУЕТ");
        }

        mTextValue = (TextView)findViewById(R.id.textView);


        mSeekBar1 = (SeekBar) findViewById(R.id.mSeekBar1);
        mSeekBar2 = (SeekBar)findViewById(R.id.mSeekBar2);

                                   
        mSeekBar1.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
            int progress = 0;

            @OverridepublicvoidonProgressChanged(SeekBar seekBar, int poresValue, boolean fromUser) {
                progress = poresValue;
                mTextValue.setText(String.valueOf(seekBar.getProgress()));
                servo1pos = seekBar.getProgress();
                MyThred.sendData(servo1pos   " :");

            }

            @OverridepublicvoidonStartTrackingTouch(SeekBar seekBar) {

            }

            @OverridepublicvoidonStopTrackingTouch(SeekBar seekBar) {
                servo1pos = seekBar.getProgress();
                MyThred.sendData(servo1pos   " :");
            }
        });


                                           
        mSeekBar2.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
            int progress = 0;

            @OverridepublicvoidonProgressChanged(SeekBar seekBar, int poresValue, boolean fromUser) {
                progress = poresValue;
                mTextValue.setText(String.valueOf(seekBar.getProgress()));
                servo2pos = seekBar.getProgress();
                MyThred.sendData(servo2pos   " :");

            }

            @OverridepublicvoidonStartTrackingTouch(SeekBar seekBar) {

            }

            @OverridepublicvoidonStopTrackingTouch(SeekBar seekBar) {
                servo2pos = seekBar.getProgress();
                MyThred.sendData(servo2pos   " :");
            }
        });
    }


    @OverridepublicvoidonResume() {
        super.onResume();

        BluetoothDevice device = btAdapter.getRemoteDevice(MacAdress);
        Log.d(LOG_TAG, "***Получили удаленный Device***" device.getName());

        try {
            btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
            Log.d(LOG_TAG, "...Создали сокет...");
        } catch (IOException e) {
            MyError("Fatal Error", "В onResume() Не могу создать сокет: "   e.getMessage()   ".");
        }

        btAdapter.cancelDiscovery();
        Log.d(LOG_TAG, "***Отменили поиск других устройств***");

        Log.d(LOG_TAG, "***Соединяемся...***");
        try {
            btSocket.connect();
            Log.d(LOG_TAG, "***Соединение успешно установлено***");
        } catch (IOException e) {
            try {
                btSocket.close();
            } catch (IOException e2) {
                MyError("Fatal Error", "В onResume() не могу закрыть сокет"   e2.getMessage()   ".");
            }
        }

        MyThred = new ConnectedThred(btSocket);
        MyThred.start();
    }

    @OverridepublicvoidonPause() {
        super.onPause();

        Log.d(LOG_TAG, "...In onPause()...");

        if (MyThred.status_OutStrem() != null) {
            MyThred.cancel();
        }

        try     {
            btSocket.close();
        } catch (IOException e2) {
            MyError("Fatal Error", "В onPause() Не могу закрыть сокет"   e2.getMessage()   ".");
        }
    }

    privatevoidMyError(String title, String message){
        Toast.makeText(getBaseContext(), title   " - "   message, Toast.LENGTH_LONG).show();
        finish();
    }

    @OverridepublicbooleanonCreateOptionsMenu(Menu menu) {
        
        getMenuInflater().inflate(R.menu.menu_main, menu);
        returntrue;
    }

    @OverridepublicbooleanonOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_settings) {
            returntrue;
        }

        returnsuper.onOptionsItemSelected(item);
    }


    privateclassConnectedThredextendsThread{privatefinal BluetoothSocket copyBtSocket;
        privatefinal OutputStream OutStrem;


        publicConnectedThred(BluetoothSocket socket){
            copyBtSocket = socket;
            OutputStream tmpOut = null;

            try{
                tmpOut = socket.getOutputStream();

            } catch (IOException e){}

            OutStrem = tmpOut;
            
        }


        publicvoidsendData(String message) {
            byte[] msgBuffer = message.getBytes();
            Log.d(LOG_TAG, "***Отправляем данные: "   message   "***"  );

            try {
                OutStrem.write(msgBuffer);
            } catch (IOException e) {}
        }

        publicvoidcancel(){
            try {
                copyBtSocket.close();
            }catch(IOException e){}
        }

        public Object status_OutStrem(){
            if (OutStrem == null){returnnull;
            }else{return OutStrem;}
        }
    }


    
}

Управление несколькими сервоприводами сигналом с датчика

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

Как видно из электрической схемы:

Данный алгоритм реализован в программе для Arduino:

// Сервоуправление с помощью датчика

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

// (с) radiocopter.ru

#include

#define servo_speed 200 // Установка скорости работы

Servo1_pin 8 определяется как выход сервопривода 1

#define servo2_pin 9 // выход 2 сервопривода

uint32_t servo_T = 0;

#define DAT_pin A0 // Вход потенциометра

Servo servo1;

Servo servo2;

voidsetup(){

servo1.attach(servo1_pin);

servo2.attach(servo2_pin);

servo_T = millis();

}

voidloop(){

if(millis() – servo_T >= servo_speed){

servo_T = millis();

int DAT = analogRead(DAT_pin); // Получение аналогового сигнала с потенциометра

Servo1.write(map(DAT, 0, 1024, 90, 180)); // Преобразование уровня напряжения от 0,1024 в угол от 90 до 180* и отправка на 1 сервопривод

Servo2.write(map(DAT, 0, 1024, 90, 0)); // Преобразование уровня напряжения от 0,1024 до 90 в 0* и отправка в servo2

}

}

// Управление сервоприводами с датчика
// (с) Роман Исаков, 2020
// (с) radiocopter.ru
#include <Servo.h>
#define servo_speed 200 // Установка скорости работы

#define servo1_pin 8 // Выход 1 сервы
#define servo2_pin 9 // Выход 2 сервы
uint32_t servo_T = 0;
#define DAT_pin A0 // Вход потенциометра

Servo servo1;
Servo servo2;

void setup() {
servo1.attach(servo1_pin);
servo2.attach(servo2_pin);
servo_T = millis();
}

void loop() {
if (millis() – servo_T >= servo_speed) {
servo_T = millis();
int DAT = analogRead(DAT_pin); // Получение аналогового сигнала с потенциометра
servo1.write(map(DAT, 0, 1024, 90, 180)); // Преобразование уровня напряжения от 0..1024 в угол от 90 до 180* и отправка на 1 серву
servo2.write(map(DAT, 0, 1024, 90, 0)); // Преобразование уровня напряжения от 0..1024 в угол от 90 до 0* и отправка на 2 серву
}
}

Управление сервоприводом по заданной программе

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

Давайте установим схему на место:

Для управления программами можно использовать следующую программу:

// Управление сервоприводом с помощью ПО

/ (с) Роман Исаков, 2020 г.

// (с) radiocopter.ru

#include

#define servo_pin 8 // Разъем для подключения сервы

#define servo_speed 500 // Скорость обработки команд

uint32_t servo_T = 0; // Служебная переменная

int pos = 0; // Номер текущей команды

int prog[] = {180, 100, 80, 90, 85, 90, 85, 90, 70, 60, 50, 40, 20, 10}; // Команды серве

Servo servo1; // объект сервопривода.

Отменить монтаж() {

servo1.attach(servo_pin); // Подключение сервы

servo_T = millis();

}

voidloop(){

int N = sizeof(prog)/sizeof(int); // число элементов массива prog

if(millis() – servo_T >= servo_speed){ // Программное прерывание по таймеру

servo_T = millis();

servo1.write(prog[pos]); // Отправка команды серве

Pos ; // Выбираем следующую команду

If(pos>=N) pos = 0; // Если вы дошли до конца, повторите с самого начала

}

}

// Программное управление сервоприводом
// (с) Роман Исаков, 2020
// (с) radiocopter.ru
#include <Servo.h>

#define servo_pin 8 // Разъем для подключения сервы
#define servo_speed 500 // Скорость обработки команд
uint32_t servo_T = 0; // Служебная переменная

int pos = 0; // Номер текущей команды
int prog[] = {180, 100, 80, 90, 85, 90, 85, 90, 70, 60, 50, 40, 20, 10}; // Команды серве

Servo servo1 ; // объект сервопривода

void setup() {
servo1.attach(servo_pin); // Подключение сервы
servo_T = millis();
}

void loop() {
int N = sizeof(prog)/sizeof(int); // число элементов массива prog
if (millis() – servo_T >= servo_speed) { // Программное прерывание по таймеру
servo_T = millis();
servo1.write(prog[pos]); // Отправка команды серве
pos ; // Выбор следующей команды
if (pos>=N) pos = 0; // Если дошли до конца – повторить сначала
}
}

Оцените статью
Радиокоптер.ру
Добавить комментарий