Робот Мариачи
- Платформы: Arduino Leonardo ETH
- Языки программирования: Arduino (C++)
- Тэги: Arduino Leonardo ETH, робот, уведомитель, маракасы, конструктор ПВХ.
Что это?
В этой статье мы расскажем вам как собрать музыкального робота Мариачи, который умеет подключаться к разным веб-серверам, считывать данные и в зависимости от заданных условий играть на маракасах. А условия могут быть самыми разнообразными:
- Новое сообщение в социальных сетях
- Ваше видео набрало очередную сотню просмотров
- Кто-то хочет добавить вас в друзья
В нашем случае Мариачи будет оповещать нас о новых заказах в магазине Амперка.
Что нам понадобится?
- Микросервопривод FS90 2 шт.
- Маракасы
- Конструктор ПВХ
Как собрать?
- Возьмите платформу Arduino Leonardo ETH и нижнюю панель кубa (7x7), соедините её с помощью винтов и гаек, так чтобы гайки располагались между панелью и платформой.
- Установите Troyka Shield через контактные колодки сверху на Arduino Leonardo ETH.
- Боковые панели куба (7x7) соедините с нижней панелью (7x7). Заднюю панель куба (7x3) закрепите между левой и правой панелями внизу, напротив разъёмов USB, Ethernet и внешнего питания платформы Arduino Leonardo ETH, заранее отделив бокорезами секции, мешающие ей устойчиво зафиксироваться.
- Возьмите микросервопривод FS90 и с помощью двух специальных панелей для крепления сервоприводов, двух панелей (3x3) и двух панелей (3x2) нашего конструктора сделайте домик для микросервопривода. Это будет плечо робота. Повторите процесс со вторым микросервоприводом.
- Из комплектации микросервопривода возьмите качельку овальной формы и через специальную панель (5x2) с вырезом для неё, закрепите к валу сервопривода болтиком также входящим в комплектацию сервомотора. Далее к этой панели с помощью двух панелей конструктора (5x2) и одной панели (6x2) соберите кисть робота. В итоге мы получили руку робота, где кисть — подвижная часть, а плечо — статичная. Повторите процесс со вторым микросервоприводом.
- Теперь к левой и правой боковым стенкам куба закрепите руки робота. Подключите микросервоприводы левой и правой руки через 3-проводные шлейфы к
8
и9
пину Troyka Shield соответственно. - Возьмите два красных светодиода «Пиранья» и прикрутите их с помощью акриловых болтов к панели для крепления двух Troyka-модулей.
- Далее используя панель с закреплёнными светодиодами, две панели (6x3) и две панели (3x3) конструктора ПВХ сделайте голову роботу, заранее подключив 3-проводные шлейфы от светодидов.
- Возьмите заднюю панель куба (7x2) и установите её между левой и правой панелями в верхней части. Далее возьмите панель крестиков (1x6) и установите между задними панелями (7x3) и (7x2). С помощью заранее выведенных 3-проводных шлейфов из головы робота подключите светодиоды «Пиранья» к
5
и6
пину Troyka Shield. Установите верхнюю панель куба (7x7) на левую и правую панели. - Так как регулятор напряжения, установленный на плате Arduino Leonardo ETH, не может выдавать ток, обеспечивающий стабильную работу сервомоторов, мы будем запитывать всю конструкцию от отдельного источника питания на
5V
. Для этого возьмите гнездо питания 2,1 мм и с помощью проводов «папа-папа» через верхнюю панель куба соедините пин5V
Arduino сплюсом
клеммника, а пинGND
Arduino сминусом
клеммника. В результате должна получиться такая схема: - Возьмите четыре панели крестиков (1x3) и установите две из них на нижнюю часть головы робота, а другие две на верхнюю часть куба.
- Установите голову робота через панели крестиков (1x3) на верхнюю панель куба. Соедините переднюю панель куба (6x7) с нижней панелью.
- Используя две панели (3x7) и четыре панели (2x4) конструктора ПВХ сделаем ноги для робота.
- Поставьте робота на ноги.
- Какой же музыкант без инструмента и шляпы. Установите в руки робота маракасы и сделайте для своего Мариачи праздничное сомбреро
Настройка Arduino IDE на работу с платой Arduino Leonardo ETH
Из за конфликта между Arduino LLC и Arduino SRL для работы платы Arduino Leonardo ETH в стандартной Arduino IDE от Arduino.cc, надо выполнить некоторые настройки.
- Зайдите в директорию, где установлена Arduino IDE. В стандартной установке она находиться по адресу
C:\Program Files\Arduino\
. - Далее зайдите в поддиректорию среды Arduino IDE по адресу
\hardware\arduino\avr\
. - Найдите в ней файл
boards.txt
и откройте его с помощью любого текстового редактора. - Добавьте в него текст, приведённый ниже.
############################################################## leonardoeth.name=Arduino Leonardo ETH leonardoeth.vid.0=0x2a03 leonardoeth.pid.0=0x0040 leonardoeth.vid.1=0x2a03 leonardoeth.pid.1=0x8040 leonardoeth.upload.tool=avrdude leonardoeth.upload.protocol=avr109 leonardoeth.upload.maximum_size=28672 leonardoeth.upload.maximum_data_size=2560 leonardoeth.upload.speed=57600 leonardoeth.upload.disable_flushing=true leonardoeth.upload.use_1200bps_touch=true leonardoeth.upload.wait_for_upload_port=true leonardoeth.bootloader.tool=avrdude leonardoeth.bootloader.low_fuses=0xff leonardoeth.bootloader.high_fuses=0xd8 leonardoeth.bootloader.extended_fuses=0xcb leonardoeth.bootloader.file=caterina/Caterina-LeonardoEthernet.hex leonardoeth.bootloader.unlock_bits=0x3F leonardoeth.bootloader.lock_bits=0x2F leonardoeth.build.mcu=atmega32u4 leonardoeth.build.f_cpu=16000000L leonardoeth.build.vid=0x2a03 leonardoeth.build.pid=0x8040 leonardoeth.build.usb_product="Arduino Leonardo ETH" leonardoeth.build.board=AVR_LEONARDO leonardoeth.build.core=arduino leonardoeth.build.variant=leonardo leonardoeth.build.extra_flags={build.usb_flags} ##############################################################
- Перезапустите Arduino IDE.
Ответ веб-сервера Амперки
В данном проекте мы используем метод GET
на URL Амперки. Пример ответа сервиса приведён ниже.
HTTP/1.1 200 OK Server: nginx/1.6.0 Date: Fri, 10 Jul 2015 14:27:55 GMT Content-Type: text/html; charset=utf-8 Content-Length: 1 Connection: close 2
Цифра 2
— это количество необработанных заказов. Наша задача отлавливать эту цифру в приходящих данных с сервера и фиксировать её изменения каждую минуту.
Алгоритм
- Сразу после подачи питания устанавливаем Ethernet-соединение.
- Соединяемся с сервером и отправляем ему HTTP-запрос.
- Считываем все пришедшие данные и находим среди них информацию о количестве заказов.
- Если это был первый ответ сервера, то записываем текущее количество заказов в переменную, которая будет хранить это значение при новом HTTP-запросе.
- Если текущее количество заказов больше предыдущего, то робот начнёт молотить маракасами в течении некоторого времени.
- Если количество заказов больше нуля, зажигаем светодиоды.
- Иначе — гасим светодиоды.
- Повторяем HTTP-запрос и его обработку каждую минуту.
Исходный код
Для работы ниже приведённого скетча вам понадобиться скачать и подключить библиотеку Ethernet2.
- musicrobot.ino
#include <SPI.h> // библиотека для подсоединения Arduino Leonardo ETH к Интернету #include <Ethernet2.h> // библиотека для работы с сервоприводами #include <Servo.h> // интервал между отправками HTTP-запроса в миллисекундах #define INTERVAL 60000 // даём разумное имя пинам к которым подключены светодиоды #define LED_1 5 #define LED_2 6 // даём разумное имя пинам к которым подключены сервомоторы #define SERV_L 8 #define SERV_R 9 // создадим два объекта для управления сервоприводами // левая и правая рука робота Servo myservo_L; Servo myservo_R; // MAC-адрес контроллера, напечатан на обратной стороне платы byte mac[] = { 0x90, 0xA2, 0xDA, 0x10, 0x01, 0x00 }; // впишите сюда адрес вашего сервера char server[] = "your.server.ru"; // переменная для хранения последнего состояния подключения boolean lastConnected = false; // количество заказов char buff[5] = {0}; // индекс массива buff[] int i = 0; // первый для проверки первый ли раз был запуск программы boolean flag = 0; // состояние работы программы int state = 0; // переменная для хранения времени работы программы // с последней отправки HTTP-запроса long previousMillis = 0; // переменная для хранения времени работы программы // с момента запуска функции движения руками long robotTime = 0; // текущее количество заказов int value = 0; // предыдущее количество заказов int previous_value = 0; // задаем статический IP-адрес // на тот случай, если у DHCP выдать IP-адрес не получится IPAddress ip(192, 168, 0, 177); // создаём клиента, который будет подключаться // к необходимому для нас серверу и порту // портом по умолчанию для HTTP является 80 EthernetClient client; void setup() { // очищаем буфер clearbuff(); // настраиваем пины светодиодов в режим выхода pinMode(LED_1, OUTPUT); pinMode(LED_2, OUTPUT); // открываем последовательный порт для мониторинга действий в программе Serial.begin(9600); // запускаем Ethernet-соединение: if (Ethernet.begin(mac) == 0) { // если не удалось сконфигурировать Ethernet при помощи DHCP Serial.println("Failed to configure Ethernet using DHCP"); // продолжать дальше смысла нет, поэтому вместо DHCP // попытаемся сделать это при помощи IP-адреса: Ethernet.begin(mac, ip); } // даем Ethernet 3 секунды на инициализацию delay(3000); // получаем и выводим локальный IP адрес Serial.print("My IP address: "); Serial.println(Ethernet.localIP()); // отправляем HTTP-запрос httpRequest(); } void loop() { // если от сервера есть какие-нибудь байты, // считываем их и выводим в Serial-порт if (client.available()) { char c = client.read(); Serial.print(c); // отслеживаем в пришедших байтах // данных которые показывают количество необработанных заказов // в нашем случае пустой строки testSymbol(c); } // если сервер отключился и последнее состояние подключение истинно if (!client.connected() && lastConnected) { // останавливаем работу клиента client.stop(); lastConnected = false; Serial.println(); Serial.println("Disconnect"); Serial.println(); buff[i]='\0'; value = atoi(buff); state = 0; // очищаем буфер clearbuff(); // если программа выполняется впервые, то // записываем текущее количества заказов if (flag == 0) { previous_value = value; flag = 1; } // если текущее количество заказов больше предыдущего // вызываем функцию движения руками робота if (value > previous_value) { robotHands(); } // если текущее количество заказов больше 0 if (value > 0) { // зажгём светодиоды digitalWrite(LED_1, HIGH); digitalWrite(LED_2, HIGH); } else { // погасим светодиоды digitalWrite(LED_1, LOW); digitalWrite(LED_2, LOW); } // записываем текущее количество заказов previous_value = value; } // проверяем не прошел ли нужный интервал времени if (millis() - previousMillis > INTERVAL) { // отправляем HTTP-запрос httpRequest(); // сохраняем текущее время previousMillis = millis(); } } // функция отправки HTTP-запроса void httpRequest() { // если подключение установлено, сообщаем об этом на Serial-порт: if (client.connect(server, 80)) { Serial.println("Connected"); // делаем HTTP-запрос: // сюда вписывайте свои данные client.println("GET /yourorders/ HTTP/1.1"); client.println("Host: your.server.ru"); // если ваш сервер не требует авторизации, следующую строчку можете пропустить client.println("Authorization: your basic access authentication"); client.println("Connection: close"); client.println(); lastConnected = true; } else { // если соединения с сервером нет, пишем об этом на Serial-порт: Serial.println("Connection failed"); } } // функция очистки буфера void clearbuff() { for (int t = 0; t < 5; t++) { // очищаем буфер, // присваивая всем индексам массива значение 0 buff[t] = 0; } // для записи с 0 индекса массива // после очистки массива i = 0; } // функция отслеживания пустой строки void testSymbol(char c) { if (c == '\n' && state == 0) { // если новый символ «перевод строки» // и программа находится в нулевом состоянии // переходим в первое состояние state = 1; } else if (c == '\r' && state == 1) { // если новый символ «возврат каретки» // и программа находится в первом состоянии // переходим во второе состояние state = 2; } else if (c == '\n' && state == 2) { // если новый символ «перевод строки» // и программа находится во втором состоянии // переходим в третье состояние state = 3; } else if (state == 3) { // если программа в третьем состоянии // это значит что пришедшие данные // будут содержать информацию о количестве заказов // считываем их в массив buff[i] = c; i++; } else { state = 0; } } void robotHands() { // сохраняем текущее время работы программы robotTime = millis(); // покаместь не прошла 1 секунда while (millis() - robotTime < 5000) { // подключаем сервоприводы myservo_L.attach(SERV_L); myservo_R.attach(SERV_R); // зажигаем светодиоды digitalWrite(LED_1, HIGH); digitalWrite(LED_2, HIGH); // устанавливаем угол 120 градусов myservo_L.write(120); myservo_R.write(120); // ждём 300 миллисекунд delay(300); // гасим светодиоды digitalWrite(LED_1, LOW); digitalWrite(LED_2, LOW); // устанавливаем угол 60 градусов myservo_L.write(60); myservo_R.write(60); // ждём 300 миллисекунд delay(300); } // останавливаем сервомоторы myservo_L.detach(); myservo_R.detach(); }
Демонстрация работы устройства
Что дальше?
В данном проекте можно использовать любую другую плату с выходом в интернет. Если у вас, например, уже есть Iskra Neo, можно добавить к ней Ethernet Shield 2 или даже GPRS Shield, немного изменив скетч. Так как светодиоды подключены к пинам, поддерживающим ШИМ, вы можете плавно регулировать их яркость в зависимости от вашей задачи. А добавив ещё один сервопривод можно заставить робота вращать головой.