Запрограммируем робота на основе Arduino.
Начну с теории и описания всего того, что нам пригодится.

Напомню Arduino – это аппаратная вычислительная платформа, основными компонентам которой являются простая плата ввода/вывода и среда разработки на языке Processing/Wiring. Документация на аппаратную часть и программный код опубликованы под лицензией «copyleft» но разработчики выразили желание, чтобы название «Arduino» было торговой маркой для официального продукта и не использовалось для производных работ без разрешения. В документе об использовании названия Arduino подчеркивается, что проект открыт для всех желающих.
До недавнего времени создание роботов считалось очень непростой процедурой, требующей от разработчика высокой квалификации и специального образования, а также длительного времени на разработку. Но с появлением плат Arduino это занятие может позволить себе почти каждый, кто хоть немного знаком с программированием! Проще некуда, но обо всем по порядку.
Плата Arduino состоит из микроконтроллера Atmel AVR и элементной обвязки для программирования и интеграции с другими схемами. На каждой плате обязательно присутствуют линейный стабилизатор напряжения 5 В и 16 МГц кварцевый генератор. В микроконтроллер предварительно прошит загрузчик, поэтому внешний программатор не нужен.
Проект Arduino постоянно развивается и имеет множество модификаций. На данный момент доступны 10 версий плат, но конкретно в данном проекте использовалась плата Arduino Diecimila. Она представляет собой небольшую электронную плату, ядром которой является микроконтроллер ATmega168. На плате есть: 14 цифровых входов/выходов, 6 из которых могут работать в режиме ШИМ (PWM) (а следовательно управлять аналоговыми устройствами вроде двигателей и передавать двоичные данные), 6 аналоговых входов, тактовый генератор на 16 МГц, разъёмы питания и USB, ICSP-порт (что-то вроде последовательного интерфейса для цифровых устройств), несколько контрольных светодиодов и кнопка сброса. Этого вполне достаточно, чтобы подключить плату к USB-порту компьютера, установить необходимое программное обеспечение (драйвер и среду разработки) и начать программировать.

Внешний вид платы Arduino Diecimila.
Краткая спецификация
Микроконтроллер: ATmega168
Рабочее напряжение: 5 В
Входное напряжение (рекомендуемое): 7-12 В
Входное напряжение (пределы): 6-20 В
Цифровые порты ввода/вывода: 14 портов (из них 6 с ШИМ-сигналом)
Аналоговые порты ввода: 6 портов
Ток для портов: 40 мА
Ток для 3.3В источника: 50 мА
ППЗУ (Flash Memory): 16 KB (из них 2 Кб используются загрузчиком)
ОЗУ (SRAM): 1 Кб
ПЗУ (EEPROM): 512 байт
Тактовая частота: 16 МГц
Что же нужно для того, чтобы сделать своего робота ?
Робота можно собрать, как это делают многие энтузиасты, но можно и переработать существующего. В качестве робота подойдет любая игрушка с подвижными деталями. В моём случае – это танк, с подвижными гусеницами, приводящимися в движение встроенными моторчиками (танк имел дистанционное управление). Вот этими моторчиками я и буду управлять с помощью платы.
Важным этапом, естественно, служит получение в своё распоряжение одной из плат Arduino. В моём случае это плата Arduino Diecimila. Также для подключения платы к компьютеру необходим USB кабель любой длины стандарта A-B. Через этот кабель будет осуществляться обмен данными между компьютером и микроконтроллером, а также подача питания на плату, т.е. внешний блок питания не обязателен. Еще один компонент, который необходим для управления моторами – это плата расширения MotorShield.

Плата расширения MotorShield и комплект деталей.

Что и как подключать к MotorShield.
Далее нужно определиться с целями: мне нужно к имеющемуся игрушечному танку приделать дистанционное управление, но не обычное «куда нажал – туда поехал», а такое, при котором танку передавались бы координаты на воображаемом поле и он самостоятельно бы их достигал. Т.е. нужно представить, что комната (или любой другой участок, по которому будет двигаться танк) р��збита на квадраты, представляющие собой систему координат. Тогда танку необходимо будет передавать координаты какого-либо квадрата и он должен будет повернуться к нему и проехать необходимое расстояние, чтобы стать в этот квадрат.

Игрушечный танк с материнской платой.

Материнская плата явно больше платы Arduino :).
Есть танк с моторами, есть плата, есть плата расширения. Необходимо средство для передачи координат. Это будет программа на компьютере пользователя, которая будет передавать данный на танк посредством Wi-Fi связи. Должен заметить, что Wi-Fi не понятен плате, поэтому на танке присутствует еще и обычная материнская плата (позже заменена на ноутбук ), которая будет от адаптера Wi-Fi транслировать данные в COM-порт, через который будет связь с платой Arduino. От нее сигналы уже будут поступать на плату расширения, и моторы должны будут закрутиться. Задача сводится к написанию двух программ: одной – для передачи данных от компьютера на Wi-Fi адаптер, другой – для обработки данных внутри микроконтроллера.

Итак, поехали!
Программу, отвечающую за обмен данными между ПК и микроконтроллером через COM-порт, писать можно на чём угодно. Пусть это будет Delphi.
Для краткости приведу исходный код только той функции, которая будет передавать танку команды, отвечающие за поворот и передвижение на нужные угол/расстояние. Функция принимает на вход текущие координаты (x0,y0), новые координаты (x1,y1) и текущий угол поворота танка alpha. Возвращать функция будет новый текущий угол. Текущие координаты и угол хранятся вне функции. Код откомментирован в нужных местах, поэтому описывать не стану.
Начну с теории и описания всего того, что нам пригодится.

Напомню Arduino – это аппаратная вычислительная платформа, основными компонентам которой являются простая плата ввода/вывода и среда разработки на языке Processing/Wiring. Документация на аппаратную часть и программный код опубликованы под лицензией «copyleft» но разработчики выразили желание, чтобы название «Arduino» было торговой маркой для официального продукта и не использовалось для производных работ без разрешения. В документе об использовании названия Arduino подчеркивается, что проект открыт для всех желающих.
До недавнего времени создание роботов считалось очень непростой процедурой, требующей от разработчика высокой квалификации и специального образования, а также длительного времени на разработку. Но с появлением плат Arduino это занятие может позволить себе почти каждый, кто хоть немного знаком с программированием! Проще некуда, но обо всем по порядку.
Плата Arduino состоит из микроконтроллера Atmel AVR и элементной обвязки для программирования и интеграции с другими схемами. На каждой плате обязательно присутствуют линейный стабилизатор напряжения 5 В и 16 МГц кварцевый генератор. В микроконтроллер предварительно прошит загрузчик, поэтому внешний программатор не нужен.
Проект Arduino постоянно развивается и имеет множество модификаций. На данный момент доступны 10 версий плат, но конкретно в данном проекте использовалась плата Arduino Diecimila. Она представляет собой небольшую электронную плату, ядром которой является микроконтроллер ATmega168. На плате есть: 14 цифровых входов/выходов, 6 из которых могут работать в режиме ШИМ (PWM) (а следовательно управлять аналоговыми устройствами вроде двигателей и передавать двоичные данные), 6 аналоговых входов, тактовый генератор на 16 МГц, разъёмы питания и USB, ICSP-порт (что-то вроде последовательного интерфейса для цифровых устройств), несколько контрольных светодиодов и кнопка сброса. Этого вполне достаточно, чтобы подключить плату к USB-порту компьютера, установить необходимое программное обеспечение (драйвер и среду разработки) и начать программировать.

Внешний вид платы Arduino Diecimila.
Краткая спецификация
Микроконтроллер: ATmega168
Рабочее напряжение: 5 В
Входное напряжение (рекомендуемое): 7-12 В
Входное напряжение (пределы): 6-20 В
Цифровые порты ввода/вывода: 14 портов (из них 6 с ШИМ-сигналом)
Аналоговые порты ввода: 6 портов
Ток для портов: 40 мА
Ток для 3.3В источника: 50 мА
ППЗУ (Flash Memory): 16 KB (из них 2 Кб используются загрузчиком)
ОЗУ (SRAM): 1 Кб
ПЗУ (EEPROM): 512 байт
Тактовая частота: 16 МГц
Что же нужно для того, чтобы сделать своего робота ?
Робота можно собрать, как это делают многие энтузиасты, но можно и переработать существующего. В качестве робота подойдет любая игрушка с подвижными деталями. В моём случае – это танк, с подвижными гусеницами, приводящимися в движение встроенными моторчиками (танк имел дистанционное управление). Вот этими моторчиками я и буду управлять с помощью платы.
Важным этапом, естественно, служит получение в своё распоряжение одной из плат Arduino. В моём случае это плата Arduino Diecimila. Также для подключения платы к компьютеру необходим USB кабель любой длины стандарта A-B. Через этот кабель будет осуществляться обмен данными между компьютером и микроконтроллером, а также подача питания на плату, т.е. внешний блок питания не обязателен. Еще один компонент, который необходим для управления моторами – это плата расширения MotorShield.

Плата расширения MotorShield и комплект деталей.

Что и как подключать к MotorShield.
Далее нужно определиться с целями: мне нужно к имеющемуся игрушечному танку приделать дистанционное управление, но не обычное «куда нажал – туда поехал», а такое, при котором танку передавались бы координаты на воображаемом поле и он самостоятельно бы их достигал. Т.е. нужно представить, что комната (или любой другой участок, по которому будет двигаться танк) р��збита на квадраты, представляющие собой систему координат. Тогда танку необходимо будет передавать координаты какого-либо квадрата и он должен будет повернуться к нему и проехать необходимое расстояние, чтобы стать в этот квадрат.

Игрушечный танк с материнской платой.

Материнская плата явно больше платы Arduino :).
Есть танк с моторами, есть плата, есть плата расширения. Необходимо средство для передачи координат. Это будет программа на компьютере пользователя, которая будет передавать данный на танк посредством Wi-Fi связи. Должен заметить, что Wi-Fi не понятен плате, поэтому на танке присутствует еще и обычная материнская плата (позже заменена на ноутбук ), которая будет от адаптера Wi-Fi транслировать данные в COM-порт, через который будет связь с платой Arduino. От нее сигналы уже будут поступать на плату расширения, и моторы должны будут закрутиться. Задача сводится к написанию двух программ: одной – для передачи данных от компьютера на Wi-Fi адаптер, другой – для обработки данных внутри микроконтроллера.

Итак, поехали!
Программу, отвечающую за обмен данными между ПК и микроконтроллером через COM-порт, писать можно на чём угодно. Пусть это будет Delphi.
Для краткости приведу исходный код только той функции, которая будет передавать танку команды, отвечающие за поворот и передвижение на нужные угол/расстояние. Функция принимает на вход текущие координаты (x0,y0), новые координаты (x1,y1) и текущий угол поворота танка alpha. Возвращать функция будет новый текущий угол. Текущие координаты и угол хранятся вне функции. Код откомментирован в нужных местах, поэтому описывать не стану.
Copy Source | Copy HTML
- Function MoveTank(x0, y0, x1, y1, alpha: integer): integer;
- var newAlpha: integer; // новый угол
- FlagsField : byte; // содержит код направления движения
- angle_tmp: integer;
- TmpStr: string;
- angle, dist: byte; // угол и расстояние, передаваемые танку
- begin
- // Вычисление нового текущего угла
- newAlpha := Round(ArcTan(Abs((x0-x1)/(y0-y1)))); // Поворот относительно текущего положения
- angle_tmp := (360 + newAlpha - alpha) mod 360; // Расстояние между заданными координатами
- dist := Round(10*Sqrt(Sqr(x0-x1) + Sqr(y0-y1)));
- FlagsField := 0; // Определение оптимального направления движения
-
- if angle_tmp <= 90 then FlagsField := 0 // передом, вправо
- else if angle_tmp < 180 then
- begin
- angle_tmp := 180 - angle_tmp;
- FlagsField := FlagsField or 4; // задом, вправо
- end
- else if angle_tmp < 270 then
- begin
- angle_tmp := angle_tmp - 180;
- FlagsField := FlagsField or 6; // задом, влево
- end
- else begin
- angle_tmp := angle_tmp - 270;
- FlagsField := FlagsField or 2; //передом, влево
- end;
-
- angle := angle_tmp;
-
- // Далее нужно отправить в COM-порт сначала флаги, затем данные.
-
- FlagsField:= FlagsField or 1; // для передачи угла
- TmpStr := Chr(FlagsField);
- ComPort_.Write(TmpStr);
- TmpStr := Chr(angle);
- ComPort_.Write(TmpStr);
-
- FlagsField:= FlagsField and 254; // для передачи расстояния
-
- TmpStr := Chr(FlagsField);
- ComPort_.Write(TmpStr);
- TmpStr := Chr(dist);
- ComPort_.Write(TmpStr);
-
- Result := newAlpha;
- end;
Следующий этап — написание программы для прошивки её в плату. Всё, что нам нужно, это принять данные с последовательного порта и обработать поступившую команду, включив вращение моторов танка в нужную сторону. Моторы включаются на определенное время и длительностью этого времени достигается движение на требуемое расстояние
В программе для приёма данных используется пин №9 (TxD). Соответственно 2й контакт СОМ порта материнской платы (RxD) необходимо подключить к пину №9 на Arduino. Ещё одно требование: нужно настроить СОМ порт материнской платы на скорость 9600 бод.
Для управления движением танка будем использовать два мотора — для левой и правой гусениц (разъемы M1 и M2 на Motor Shield). Для упрощения работы с моторами используем фреймворк AFMotor, легко подключаемый к нашему проекту одной строкой «#include «AFMotor.h»». Моторы обозначим цифрами 1 для левой и 2 для правой гусениц. В коде, приведенном ниже, видно, что работа с моторами не представляет собой ничего сложного.
Copy Source | Copy HTML
- #include "AFMotor.h" // библиотека для удобства обращения с движками
-
- #define TX 9 // пин на Arduino, куда подключен выход из COM-порта
-
- // кодирование команд от джойстика
-
- #define cmdForward 1
- #define cmdBackward 2
- #define cmdRapidLeft 3
- #define cmdRapidRight 4
- #define cmdLeft 5
- #define cmdRight 6
-
- // скорости вращения движков
- // MaxSpeed - обычное движение
- // MinSpeed - скорость одной из гусениц при резком повороте
- // HalfSpeed - скорость одной из гусениц при плавном повороте
-
- #define MaxSpeed 200
- #define MinSpeed 100
- #define HalfSpeed 150
-
- // движение танка со скоростями левой и правой гусениц LTS и RTS
- // в направлении Direction
-
- void MoveTank(byte LTS, byte RTS, byte Direction);
-
- // чтение одного байта с COM-порта
- byte COMread();
-
- // хранит команду, полученную с COM-порта
- byte Command = 0;
-
- // текущее направление движения
- byte CurrentDirection = FORWARD;
-
- // выбираем 1й и 2й разъемы на Motor Shield, куда подключены движки
- AF_DCMotor LeftTrack(1, MOTOR12_1KHZ);
- AF_DCMotor RightTrack(2, MOTOR12_1KHZ);
-
- void setup()
- {
- LeftTrack.setSpeed(MaxSpeed);
- RightTrack.setSpeed(MaxSpeed);
- pinMode(TX, INPUT);
- }
-
- void loop()
- {
- Command = COMread();
- switch (Command)
- {
- case cmdForward:
- MoveTank(MaxSpeed, MaxSpeed, FORWARD);
- CurrentDirection = FORWARD;
- break;
- case cmdBackward:
- MoveTank(MaxSpeed, MaxSpeed, BACKWARD);
- CurrentDirection = BACKWARD;
- break;
- case cmdRapidLeft:
- MoveTank(MinSpeed, MaxSpeed, CurrentDirection);
- break;
- case cmdRapidRight:
- MoveTank(MaxSpeed, MinSpeed, CurrentDirection);
- break;
- case cmdLeft:
- MoveTank(HalfSpeed, MaxSpeed, CurrentDirection);
- break;
- case cmdRight:
- MoveTank(MaxSpeed, HalfSpeed, CurrentDirection);
- break;
- default:
- LeftTrack.run(RELEASE); // останавливаем двигатели
- RightTrack.run(RELEASE);
- break;
- }
- }
-
- void MoveTank(byte LTS, byte RTS, byte Direction)
- {
- LeftTrack.setSpeed(LTS);
- RightTrack.setSpeed(RTS);
- LeftTrack.run(Direction);
- RightTrack.run(Direction);
- }
-
- byte COMread()
- {
- byte val = 0;
- while (digitalRead(TX));
- // ждем стартовый бит
- if (digitalRead(TX) == LOW)
- {
- delayMicroseconds(42);
- for (int k = 0; k < 8; k++)
- {
- delayMicroseconds(84);
- val |= digitalRead(TX) << k;
- }
- // ожидание 9го бита и стопового
- delayMicroseconds(168);
- return val;
- }
- }
Осталось только прошить эту программку в Arduino (а делается это нажатием одной кнопки в интерфейсе Arduino IDE) и можно развлекаться, засылая танк в тыл врага :).
Заключение
Конечно, можно не ограничиваться просто пересылкой координат. Можно добавить интерактивности, используя для управления танком джойстик. А используя веб-камеру, прикрепленную к башне танка, можно наблюдать за движением, сидя за компьютером. Но для этого понадобится дополнительное ПО. Но даже это не делает программирование Arduino чем-то непосильным. Работать с такой платой просто, легко, а главное — доступно! Хотя нет, главное — это получение море удовольствия как от результата, так и от самого процесса!
