Картонный робот под управлением смартфона

В данной статье мы с вами построим картонного робота на трех сервоприводах, управляемых Arduino. Робот будет шевелить руками и поворачивать голову. Для конструирования управления будем использовать сервис RemoteXY, который позволит управлять нашим роботом со смартфона по Bluetooth.

Картонный робот

Корпус робота

Робот состоит из четырех деталей, вырезанных из гофро-картона. Это туловище, голова и две руки. Все детали вырезаны при помощи ножа. Так же ножом необходимо надрезать места сгибов. Детали можно склеить пластиковым клеем используя пистолет для его разогрева. Для установки сервоприводов на туловище необходимо прорезать прямоугольные отверстия. Для закрепления сервоприводов в отверстиях используется тот же пластиковый клей. На голове и руках, там, где присоединяется вал сервопривода, установлены качалки, которые клеятся изнутри к корпусу при помощи все того же пластикового клея. Мы не будем приводить точных размеров и чертежей, у вас не должно вызвать трудности повторить конструкцию.

В голове прорежьте два отверстия, в которые установите два светодиода. Это будут глаза. Глаза так же будут зажигаться дистанционно

Картонный робот

Электрическая схема

Для устойчивой работы схемы, сервоприводы должны быть запитаны от отдельного источника питания 5V. Стабилизатор напряжения Arduino не может обеспечить необходимую силу тока для всех трех сервоприводов. Последовательно со светодиодами необходимо включить резистор номиналом 680 Ом.

Картонный робот

Графический интерфейс управления

Откройте редактор интерфейса на сайте RemoteXY.com и создайте интерфейс управления, приведенный на рисунке ниже. На интерфейсе расположите правый и левый слайдер для правой и левой руки, слайдер для вращения головы. Установите две кнопки для управления глазами. Так же установите переключатель. Его мы будем использовать для включения режима автоматического моргания глазами.

Картонный робот

Переименуйте слайдеры, назовите их slider_left, slider_right и slider_head соответственно. Так же переименуйте кнопки. Назовите их button_left и button_right соответственно.

Так как наш проект подразумевает использование библиотеки servo.h, выберите в настройках проекта формирование исходного кода для Arduino (Serial), library version. Напомню, что библиотека servo.h конфликтует с библиотекой SoftwareSerial.h, по этому мы ее использовать не будем.

Сформируйте и загрузите исходный код проекта графического интерфейса к себе на компьютер. Не забудьте загрузить и установить библиотеку RemoteXY для Arduino IDE. Скомпилируйте и загрузите скетч в плату Arduino. Используя мобильное приложение RemoteXY проверьте, что ваш смартфон может соединиться с вашим новым проектом. Не забудьте, что модуль Bluetooth необходимо подключить к аппаратному последовательному порту к пинам 0(RX) и 1(TX). Если смартфон соединился успешно, тогда идем дальше.

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


/* структура определяет все переменные вашего интерфейса управления */ 
struct { 
  
    /* input variable */
  unsigned char slider_left; /* =0..100 положение слайдера */
  unsigned char slider_right; /* =0..100 положение слайдера */
  unsigned char slider_head; /* =0..100 положение слайдера */
  unsigned char button_left; /* =1 если кнопка нажата, иначе =0 */
  unsigned char button_right; /* =1 если кнопка нажата, иначе =0 */
  unsigned char switch_1; /* =1 если переключатель включен и =0 если отключен */

    /* other variable */
  unsigned char connect_flag;  /* =1 if wire connected, else =0 */

} RemoteXY; 

Программа управления

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

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

Также очень важно учесть, что программа должна выполняться непрерывно. Именно по этому в функции loop, главном цикле программы, нельзя использовать паузы. Например, паузу часто используют в режиме моргания двух светодиодов-глаз, ожидая время между переключениями светодиодов. В нашем случае такой подход приведет к ошибкам. В каждом цикле loop вызывается функции RemoteXY_Handler (), которая отвечает за обмен данными со смартфоном через модуль Bluetooth. Если эта функция не будет вызвана в течении длительного времени, она не сможет корректно выполнить обмен данными. Как же решить проблему отсчета времени между переключениями светодиодов? Очень просто, используя встроенный таймер. Далее приведен исходный код программы управления.


///////////////////////////////////////////// 
//        RemoteXY include library         // 
///////////////////////////////////////////// 

/* определение режима соединения и подключение библиотеки RemoteXY */ 
#define REMOTEXY_MODE__SERIAL 
#include <RemoteXY.h> 

/* настройки соединения */ 
#define REMOTEXY_SERIAL Serial 
#define REMOTEXY_SERIAL_SPEED 9600 

/* конфигурация интерфейса  */ 
unsigned char RemoteXY_CONF[] = 
  { 6,0,79,0,1,5,4,0,5,7
  ,11,56,2,4,0,84,7,11,56,2
  ,4,128,20,13,60,11,2,129,0,26
  ,3,49,6,0,208,161,97,114,100,98
  ,111,97,114,100,32,82,111,98,111,116
  ,0,1,0,25,29,16,16,1,76,0
  ,1,0,60,29,16,16,1,82,0,2
  ,0,38,51,24,10,2,79,78,0,79
  ,70,70,0 }; 
   
/* структура определяет все переменные вашего интерфейса управления */ 
struct { 

    /* input variable */
  unsigned char slider_left; /* =0..100 slider position */
  unsigned char slider_right; /* =0..100 slider position */
  unsigned char slider_head; /* =0..100 slider position */
  unsigned char button_left; /* =1 if button pressed, else =0 */
  unsigned char button_right; /* =1 if button pressed, else =0 */
  unsigned char switch_1; /* =1 if switch ON and =0 if OFF */

    /* other variable */
  unsigned char connect_flag;  /* =1 if wire connected, else =0 */

} RemoteXY; 

///////////////////////////////////////////// 
//           END RemoteXY include          // 
///////////////////////////////////////////// 

#include <Servo.h> 

#define PIN_LED_LEFT 6
#define PIN_LED_RIGHT 7

#define PIN_LEFT_SERVO 8
#define PIN_RIGHT_SERVO 9
#define PIN_HEAD_SERVO 10

Servo left_servo;
Servo right_servo;
Servo head_servo;

unsigned char led_state = 0;
unsigned long led_time=0;
unsigned long prev_time=0;

void setup()  

  RemoteXY_Init ();  
   
  // TODO you setup code 
  
  pinMode (PIN_LED_LEFT, OUTPUT);
  pinMode (PIN_LED_RIGHT, OUTPUT);
  
  left_servo.attach(PIN_LEFT_SERVO);
  right_servo.attach(PIN_RIGHT_SERVO);
  head_servo.attach(PIN_HEAD_SERVO);

  RemoteXY.slider_left=50;
  RemoteXY.slider_right=50;
  RemoteXY.slider_head=50;
   


void loop()  
{  
  RemoteXY_Handler (); 
   
  // TODO you loop code 
  // используйте структуру RemoteXY для передачи данных 
 
  unsigned long time = millis();
  unsigned long d_time = time - prev_time;
  prev_time = time;
  
  
  if (RemoteXY.switch_1==0) {
    digitalWrite(PIN_LED_LEFT, (RemoteXY.button_left==0)?LOW:HIGH);
    digitalWrite(PIN_LED_RIGHT, (RemoteXY.button_right==0)?LOW:HIGH);
  }
  else {
    led_time+=d_time;
    if (led_time>500) {
      if (led_state==0) led_state=1;
      else  led_state=0;
      led_time-=500;
    }
    digitalWrite(PIN_LED_LEFT, (led_state==0)?LOW:HIGH);
    digitalWrite(PIN_LED_RIGHT, (led_state==1)?LOW:HIGH);    
  }

  left_servo.writeMicroseconds(RemoteXY.slider_left*20+500); 
  right_servo.writeMicroseconds(2500-RemoteXY.slider_right*20); 
  head_servo.writeMicroseconds(RemoteXY.slider_head*20+500); 

}

В начале программы определяются номера пинов, которые будут использованы для глаз-светодиодов и для управления тремя сервоприводами. Функция setup инициализирует пины светодиодов как выходы, инициализирует классы сервоприводов. Так же устанавливаются начальные положения слайдеров в среднее положение.

В функции loop первым делом вызывается обработчик RemoteXY_Handler. Далее вычисляется интервал времени, прошедший с начала предыдущего цикла функции loop, в миллисекундах. Как раз этот интервал используется для расчета момента времени, в который необходимо переключить светодиод. Если переключатель switch_1 не включен, то состояние кнопок button_left и button_right напрямую передается на пины управления глазами-светодиодами. Если switch_1 включен, реализуется алгоритм моргания глазами. Длительность свечения одного глаза равна 500 миллисекунд.

Далее, положения слайдеров управления руками и головой преобразуются в длительность импульсов для управления соответствующими сервоприводами. Слайдер изменяет свое положение от 0 до 100, в то время как длительность импульсов управления сервоприводом должна изменяться в пределах от 500 до 2500 мс. Обратите внимание, что сервопривод правой руки двигается в противоположном направлении, и это отражено в формуле преобразования.

Загрузки

Проект для Arduino - Cardboard Robot