Шагающий и танцующий робот на Arduino

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

Внешний вид шагающего и танцующего робота на основе платы Arduino

Также вы можете использовать программу, приведенную в конце статьи, чтобы управлять движениями робота с помощью положения его сервомоторов и используя для этого последовательный монитор (Serial monitor). Если у вас есть 3D принтер, то вы можете сделать этот проект очень впечатляющим, но если у вас его нет, то вы можете изготовить компоненты корпуса робота из любого доступного материала: пластмасса, дерево, жесткий картон и т.д.

Необходимые компоненты

Плата Arduino Nano
Сервомотор SG90 (4 шт.)
Соединительные колодки (типа папа)
Bluetooth модуль (HC-05/HC-06)
3D принтер (опционально)

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

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

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

Печать на 3D принтере необходимых компонентов

3D принтеры, появившиеся сравнительно недавно, дают большой простор для разнообразных DIY (сделай сам) проектов.

Мы в нашем проекте полностью напечатали тело робота на 3D принтере. Все необходимые STL файлы для этого вы можете скачать по следующей ссылке. Вы можете загрузить эти файлы программным обеспечением вашего 3D принтера (например, Cura) и непосредственно напечатать их. Принтер, который мы использовали, называется FABX v1, который доступен по приемлемой цене и может печатать в объеме до 10 кубических сантиметров. Мы использовали программное обеспечение Cura чтобы напечатать STL файлы. Мы сделали следующие настройки в данном программном обеспечении для печати нашего проекта:

Настройки 3D принтера для печати комплектующих робота

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

Внешний вид напечатанных компонентов робота

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

Работа схемы

Схема устройства представлена на следующем рисунке.

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

Сборка робота

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

Motor Number (номер мотора) Motor place (место мотора) Motor position (позиция мотора)
1 Left Hip motor 110
2 Right Hip motor 100
4 Right Ankle Motor 90
5 Right Hip motor 80

Эти углы можно выставить с помощью программы, приведенной в конце статьи. Просто загрузите программу в плату Arduino (когда все соединения уже сделаны) и напечатайте в окне последовательного монитора (serial monitor) (бодовая скорость: 57600):

1, 100, 110

2,90,100

4,80,90

5,70,80

Окно последовательного монитора у вас после установки всех сервомоторов в необходимые позиции должно выглядеть примерно так:

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

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

Названия сервомоторов робота

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

Объяснение программы для Arduino

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

Полный текст программы приведен в конце статьи, либо вы можете скачать его по этой ссылке. Здесь же объяснены наиболее важные части программы. С помощью этой программы можно управлять движениями робота при помощи монитора последовательной связи (serial monitor) или технологии Bluetooth. Также вы на основе этой программы можете запрограммировать свой собственный набор движений для робота.

В следующих строчках кода мы укажем плате Arduino какие сервомоторы к каким ее контактам подключены. В нашем случае сервомоторы 1, 2, 4 и 5 подключены к контактам 3, 5, 9 и 10.

servo1.attach(3);

servo2.attach(5);


servo4.attach(9);


servo5.attach(10);

В следующих строчках кода инициализируем последовательную связь с Bluetooth на скорости 9600 бод/с (под именем “Bot_BT”) и последовательную связь на скорости 57600 (для управления через монитор последовательного порта).

Bot_BT.begin(9600); //start the Bluetooth communication at 9600 baudrate
Serial.begin(57600);

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

К примеру, если мы хотим повернуть сервомотор №1 (left hip motor) с его позиции по умолчанию (60 градусов) на позицию 110 градусов, то мы можем просто написать в окне монитора последовательной связи (serial monitor) команду “1,110,60” и нажать клавишу ввода (Enter). Пробуя разные команды таким образом вы можете составить свой индивидуальный набор движений для робота и потом оформить их в виде функции.

switch (motor)
{
case 1: // For motor one
{ Serial.println("Executing motor one");
if(num1<num2) // Clock wise rotation
{ for ( pos =num1; pos<=num2; pos+=1)
{
servo1.write(pos);
delay( 20);
}}
if(num1>num2) // вращение против часовой стрелки
{
for ( pos =num1; pos>=num2; pos-=1)
{
servo1.write(pos);
delay( 20);
}}
break;
}
////////JUST DUPLICATE FOR OTHER SERVOS////
case 2: // For motor 2
{
Serial.println("Executing motor two");
if(num1<num2)
{
for ( pos =num1; pos<=num2; pos+=1)
{
servo2.write(pos);
delay( 20);
}}
if(num1>num2)
{
for ( pos =num1; pos>=num2; pos-=1)
{
servo2.write(pos);
delay( 20);
}}
break;
}
case 4: // for motor four
{
Serial.println("Executing motor four");
if(num1<num2)
{
for ( pos =num1; pos<=num2; pos+=1)
{
servo4.write(pos);
delay (20);
}}
if(num1>num2)
{
for ( pos =num1; pos>=num2; pos-=1)
{
servo4.write(pos);
delay (20);
}}
break;
}
case 5: // for motor five
{
Serial.println("Executing motor five");
{
for ( pos =num1; pos<=num2; pos+=1)
if(num1<num2)
{
servo5.write(pos);
delay (20);
}}
if(num1>num2)
{
for ( pos =num1; pos>=num2; pos-=1)
{
servo5.write(pos);
delay (20);
}}
break;
}

Следующие строки позволяют расшифровать поступающие команды по последовательному порту (из окна монитора последовательной связи) и распределить поступающие параметры по необходимым переменным.

if(Serial.available()>0) // считываем что поступает по последовательному порту
{
gmotor= Serial.parseInt();
Serial.print(" selected Number-> ");
Serial.print(gmotor);
Serial.print(" , ");
gnum1= Serial.parseInt();
Serial.print(gnum1);
Serial.print(" degree , ");
gnum2= Serial.parseInt();
Serial.print(gnum2);
Serial.println(" degree ");
flag=1;
}

Если мы получаем информацию по Bluetooth, то мы сохраняем ее в переменной “BluetoothData”. Затем значение этой переменной сравнивается с заранее определенными значениями чтобы выполнить необходимые действия.

if (Bot_BT.available()) //считываем что поступает по Bluetooth
{
BluetoothData=Bot_BT.read();
Serial.print("Incoming from BT:");
Serial.println(BluetoothData);
}

В следующем участке кода происходит вызов необходимой функции в соответствии с командой, поступившей по последовательному порту или через Bluetooth. Как было показано раньше, переменная gmotor будет содержать данные, поступившие по последовательному порту, а переменная BluetoothData – данные, поступившие через Bluetooth. Числа с 10 по 13 и с 49 по 54 – это заранее определенные значения.

К примеру, если вы введете в окне монитора последовательной связи число 49, то произойдет вызов функции say_hi() и робот выполнит соответствующие движения.

Все запрограммированные функции доступны на странице “Bot_Functions” – вы можете открыть ее и посмотреть что происходит внутри каждой функции. Все эти функции составлены с учетом наших экспериментов по управлению серводвигателями робота.

if (flag ==1 )
call(gmotor,gnum1,gnum2); //вызов соответствующего сервомотора для действия
//выполнение функции в соответствии с командой, поступившей по последовательному порту или через Bluetooth
if (gmotor ==10)
left_leg_up();
if (gmotor ==11)
right_leg_up();
if (gmotor ==12)
move_left_front();
if (gmotor ==13)
move_right_front();
if (BluetoothData ==49 || gmotor ==49)
say_hi();
if (BluetoothData ==50 || gmotor ==50)
walk1();
if (BluetoothData ==51 || gmotor ==51)
walk2();
if (BluetoothData ==52 || gmotor ==52)
dance1();
if (BluetoothData ==53 || gmotor ==53)
dance2();
if (BluetoothData ==54 || gmotor ==54)
{test();test();test();}

Программирование Android приложения с помощью Processing

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

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

Примечание: ваш Bluetooth модуль должен иметь имя “HC-06”, иначе приложение не сможет с ним соединиться.

После установки приложения на мобильный телефон вы можете соединить ваш телефон по Bluetooth с Bluetooth модулем (подключенным к Arduino) и после этого запустить приложение. Это будет выглядеть примерно следующим образом:

Вид запущенного приложения для управления танцующим роботом

Если же вы хотите сделать приложение более привлекательным или соединить его с другим Bluetooth-устройством (названным не “HC-06”), то вам в этом случае будет необходимо внести изменения в исходный код приложения.

Принцип работы танцующего робота

После того как схема собрана и программа загружена в плату Arduino вы можете насладиться управлением роботом. Для управления из Android приложения вам необходимо нажимать в нем соответствующие кнопки (см. рисунок выше), а для управления из окна монитора последовательной связи вам следует в этом окне вводить необходимые команды как показано на следующем рисунке:

Вид команд для управления роботом, вводимым в окне монитора последовательной связи

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

Робота можно запитать от адаптера на 12V или с помощью батареи на 9V, которую несложно будет разместить внутри корпуса робота.

Вид различных движений робота

Более подробно весь этот процесс можно посмотреть в видео в конце статьи.

Исходный код программы для Arduino

#include <Servo.h> //header to srive servo motors
#include <SoftwareSerial.h>// import the serial library
SoftwareSerial Bot_BT(12, 11); // RX, TX
int ledpin=13; // led on D13 will show blink on / off
int BluetoothData; // the data given from Computer
//lets declare the servo objects
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
//End of declaration
long gmotor,gnum1,gnum2;
int pos,pos2;
int flag=0;
int poss1,poss2,poss3,poss4;
void setup()
{
servo1.attach(3);
servo2.attach(5);;
servo4.attach(9);
servo5.attach(10);
//**Initial position of all four servo motors**//
servo1.write(110);
servo2.write(100);
servo4.write(90);
servo5.write(80);
//**inititialised**//
Bot_BT.begin(9600); //start the Bluetooth communication at 9600 baudrate
Bot_BT.println("Blue Bob is ready to take actions");
Serial.begin(57600);
Serial.println("Biped Servo programming by CircuitDigest.com");
Serial.println("Enter any of the following commands for theier respective actions");
Serial.println("1. Servomotor Number, From angle, To angle -> To control one particular Servo");
Serial.println(" Servomotor Number -> 1,2,4,5");
Serial.println(" From angle -> 0 to 180");
Serial.println(" To angle -> 0 to 180");
Serial.println("2. Servomotor Number, From angle, To angle -> To control one particular Servo");
Serial.println("3. Enter 10 -> To lift left leg up");
Serial.println("4. Enter 11 -> To lift right leg up");
Serial.println("5. Enter 12 -> To move left leg front");
Serial.println("6. Enter 13 -> To move right leg front");
Serial.println("7. Enter 49 -> To say Hi ;-)");
Serial.println("8. Enter 50 -> To Walk with style 1");
Serial.println("9. Enter 51 -> To Walk with style 2");
Serial.println("10. Enter 52 -> To Dance with style 1");
Serial.println("11. Enter 53 -> To Dance with style 2");
Serial.println("12. Enter 54 -> To Say Bye!!");
}
//***Function for each Servo actions**//
void call(int motor, int num1, int num2) // The values like Motor number , from angle and to angle are received
{
Serial.println("Passing values...");
flag =0;
switch (motor)
{
case 1: // For motor one
{ Serial.println("Executing motor one");
if(num1<num2) // Clock wise rotation
{ for ( pos =num1; pos<=num2; pos+=1)
{
servo1.write(pos);
delay( 20);
}}
if(num1>num2) // Anti-Clock wise rotation
{
for ( pos =num1; pos>=num2; pos-=1)
{
servo1.write(pos);
delay( 20);
}}
break;
}
////////JUST DUPLICATE FOR OTHER SERVOS////
case 2: // For motor 2
{
Serial.println("Executing motor two");
if(num1<num2)
{
for ( pos =num1; pos<=num2; pos+=1)
{
servo2.write(pos);
delay( 20);
}}
if(num1>num2)
{
for ( pos =num1; pos>=num2; pos-=1)
{
servo2.write(pos);
delay( 20);
}}
break;
}
case 4: // for motor four
{
Serial.println("Executing motor four");
if(num1<num2)
{
for ( pos =num1; pos<=num2; pos+=1)
{
servo4.write(pos);
delay (20);
}}
if(num1>num2)
{
for ( pos =num1; pos>=num2; pos-=1)
{
servo4.write(pos);
delay (20);
}}
break;
}
case 5: // for motor five
{
Serial.println("Executing motor five");
{
for ( pos =num1; pos<=num2; pos+=1)
if(num1<num2)
{
servo5.write(pos);
delay (20);
}}
if(num1>num2)
{
for ( pos =num1; pos>=num2; pos-=1)
{
servo5.write(pos);
delay (20);
}}
break;
}
}
}
void loop()
{
if(Serial.available()>0) //Read whats coming in through Serial
{
gmotor= Serial.parseInt();
Serial.print(" selected Number-> ");
Serial.print(gmotor);
Serial.print(" , ");
gnum1= Serial.parseInt();
Serial.print(gnum1);
Serial.print(" degree , ");
gnum2= Serial.parseInt();
Serial.print(gnum2);
Serial.println(" degree ");
flag=1;
}
if (Bot_BT.available()) //Read whats coming in through Bluetooth
{
BluetoothData=Bot_BT.read();
Serial.print("Incoming from BT:");
Serial.println(BluetoothData);
}
if (flag ==1 )
call(gmotor,gnum1,gnum2); //call the respective motor for action
//Execute the functions as per the commond received through the Serial monitor or Bluetooth//
if (gmotor ==10)
left_leg_up();
if (gmotor ==11)
right_leg_up();
if (gmotor ==12)
move_left_front();
if (gmotor ==13)
move_right_front();
if (BluetoothData ==49 || gmotor ==49)
say_hi();
if (BluetoothData ==50 || gmotor ==50)
walk1();
if (BluetoothData ==51 || gmotor ==51)
walk2();
if (BluetoothData ==52 || gmotor ==52)
dance1();
if (BluetoothData ==53 || gmotor ==53)
dance2();
if (BluetoothData ==54 || gmotor ==54)
{test();test();test();}
//End of executions//
gmotor=0; //To prevet repetetion
BluetoothData = 0; //To prevet repetetion
//stay_put(); //bring the Bot to initial posotion if required
}
/*---------------------------------------------------------------------------*/
// Code for Bot Functions......
//***Function to lift the left leg**//
void stay_put()
{
servo5.attach(10);
servo1.write(110);
servo2.write(100);
servo4.write(90);
servo5.write(80);
delay(20);
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void left_leg_up()
{
Serial.println("left leg up");
poss1 = 80;
poss2 = 110;
do{
servo5.write(poss1);
servo4.write(poss2);
poss1++;
poss2++;
delay(20);
}while(poss1 <100 || poss2<140);
call(4,130,100);
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void right_leg_up()
{
Serial.println("right leg up");
poss1 = 80;
poss2 = 100;
do{
servo4.write(poss2);
servo5.write(poss1);
poss1--;
poss2--;
delay(20);
}while(poss1 >50 || poss2>60);
call(5,50,80);
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void move_left_front()
{
Serial.println("moving left front");
poss1=120;poss2=110;poss3=110;
do{
servo2.write(poss1);
servo1.write(poss2);
servo5.write(poss3);
poss1--;
poss2--;
poss3--;
delay(20);
}while(poss1 >100 || poss2>80 || poss3>80 );
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void move_right_front()
{
poss1=80;poss2=100;poss3=60;
do{
servo1.write(poss1);
servo2.write(poss2);
servo4.write(poss3);
poss1++;
poss2++;
poss3++;
delay(20);
}while(poss1 <110 || poss2<120 || poss3<90);
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void say_hi()
{
stay_put();
right_leg_up();
call(5,80,50); //wave up
call(5,50,80); //wave down
call(5,80,50); //wave up
call(5,50,80); //wave down
stay_put();
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void walk1()
{
stay_put();
char temp=10; //number of steps to make * 2
do{
right_leg_up();
move_right_front();
left_leg_up();
move_left_front();
temp--;
}while(temp>0);
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void walk2()
{
stay_put();
char temp=10; //number of steps to make * 2
do{
move_right_front();
move_left_front();
temp--;
}while(temp>0);
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void dance1()
{
stay_put();
char temp=3; //number of steps to make * 2
do{
poss1 = 80;
poss2 = 60;
do{
servo1.write(poss1);
servo2.write(poss2);
poss1++;
poss2++;
delay(20);
}while(poss1 <140 || poss2<120);
poss1 = 140;
poss2 = 120;
do{
servo1.write(poss1);
servo2.write(poss2);
poss1--;
poss2--;
delay(20);
}while(poss1 >80 || poss2>60);
temp--;
}while(temp>0);
stay_put();
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void dance2()
{
stay_put();
char temp=3; //number of steps to make * 2
do{
right_leg_up(); right_leg_up();
stay_put();
left_leg_up();left_leg_up();
stay_put();
temp--;
}while(temp>0);
stay_put();
}
//**_____End of Function______**//
//***Function to lift the left lef**//
void test()
{
poss1 = 40;
poss2 = 130;
do{
servo5.write(poss1);
servo4.write(poss2);
poss1++;
poss2--;
delay(5);
}while(poss1 <120 || poss2>50);
poss1 = 120;
poss2 = 50;
do{
servo5.write(poss1);
servo4.write(poss2);
poss1--;
poss2++;
delay(5);
}while(poss1 >40 || poss2<130);
}
//**_____End of Function______**//

Видео, демонстрирующее работу схемы

(Проголосуй первым!)
Загрузка...
67 просмотров

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *