-
Введение
-
Глава 1. Аппаратная основа
- Содержание Главы 1
- Подготовка
- Плата Arduino UNO
- Плата управления моторами
- Плата связи с датчиками
- Аппаратная основа на базе набора miniQ
- Аппаратная основа на базе набора Turtle
- Аппаратная основа на базе набора ShieldBot
- Как ученики строили своих miniQ роботов
- Этапы сборки
- Система электропитания робота
- Провода энкодеров и датчиков линии
- Завершение главы 1
-
Глава 2. Начало работ с системой программирования Arduino
- Содержание Главы 2
- Подготовка
- Общие правила организации систем управления
- Входные данные. Датчики
- Обработка данных. Микроконтроллер
- Выходные данные. Исполнительные устройства
- То, что нужно всегда помнить
- Начало работы с системой Arduino
- Загрузка программы-примера “Мигающий огонь”
- Модификация программы “Мигающий огонь”
- Алгоритм программы “Мигающий огонь”
- Завершение Главы 2
-
Глава 3. Управление тяговыми моторами
-
Глава 4. Связь с ультразвуковым датчиком расстояния
- Содержание Главы 4
- Подготовка
- Постановка задач
- Электрическое подключение датчиков расстояния
- Разработка алгоритма
- Исходный текст
- Адреса Echo и Trigger как глобальные переменные
- Отладка и испытание программы
- Руководство пользователя
- Приложение 4.1. Подсказки по сложному алгоритму
- Приложение 4.2. Исходный текст (для упрощённого алгоритма)
- Завершение главы 4
- Факультативная часть главы 4
-
Глава 5. Робот следует за рукой или лидером
- Содержание главы 5
- Подготовка
- Релейный регулятор
- Пропорциональный регулятор
- Утилиты
- UTILIT_OneRangeMeter ()
- UTILIT_Motors_Control ()
- UTILIT_Hand_Follow_Proportional (int _range_needed)
- Два факультативных упражнения после перерыва
- Программа следования за лидером
- Постановка задачи
- Макрос следования за Лидером
- Отладка и испытание программы Programm_modul_5_Leader_Follow.ino
- Если что-то не так
- Исследуем робота
- Важные замечания
- Приложение 5.1 Алгоритм пропорционального регулирования
- Приложение 5.2. Исходный текст утилиты регулятора для следования за рукой
- Приложение 5.3. Документация для макроса и утилит следования за лидером
- MACROS_Leader_Follow (int _distasnce_to_leader)
- UTILIT_LeftRightRangeMeter ()
- UTILIT_Leader_Follow_Proportional (int _range_needed)
- UTILIT_Motors_Control () & UTILIT_Motors_Stop ()
- Завершение главы 5
- Как можно улучшить нашего робота?
-
Глава 6. Структура программного обеспечения
- Содержание главы 6
- Подготовка
- Уровни программного обеспечения
- loop ()
- Задачи
- Макросы
- Утилиты
- Драйверы. Библиотеки. Калькуляторы
- Ввод-вывод
- Глобальные переменные
- Правила обмена информации между уровнями
- Практическое занятие 6.1. Учтём трение в механизмах
- Практическое занятие 6.2. Доворот в сторону лидера умножением
- Практическое занятие 6.3. Доворот в сторону лидера сложением
- Практическое занятие 6.4. Доворот в сторону лидера обнулением
- Практическое занятие 6.5. Делаем калькулятор
- Гонки за лидером
- Послесловие
- Список программ для Ардуино
- Лицензионное соглашение
Постановка задачи
Сначала краткое описание объекта управления – того, чем мы будем управлять с помощью нашей функции. У нашего робота есть два мотора – левый и правый.
- Если в оба мотора подать одинаковую мощность с положительным знаком, то робот поедет вперёд.
- Если мощности оставить теми же, а знаки поменять на отрицательные – робот поедет назад.
- Если мощности будут одинаковыми, а знаки противоположными, то робот будет вращаться на месте.
- Если мощности будут одного знака, но разных величин, то робот будет двигаться вперёд, или назад, одновременно поворачивая.
Теперь переведём описание объекта управления на язык действий функции-программы. Для этого сначала напишем, какими сигналами (или контактами) платы Arduino UNO управляются величины и знаки мощностей, подаваемые в моторы.
Для управления каждым мотором с помощью платы MotorShield используются два выхода платы Arduino UNO. Один задаёт направление вращения – там всё просто – выводите на него HIGH
– мотор вращается вперёд. Выводите LOW
– вращается назад.
То есть можно использовать знакомый нам оператор –
digitalWrite(port_number, value);
где port_number
– номер контакта платы Arduino UNO, а value
это либо HIGH
либо LOW
, в зависимости от того, куда мы хотим завертеть мотор.
Со скоростью вращения (или мощностью) немного сложнее. Скорость задаётся широтно-модулированным импульсом, который должен быть подан на другой вывод платы Arduino UNO.
Это делается с помощью оператора analogWrite (port_number, value);
где port_number
– номер контакта платы Arduino UNO, а value
– целое число от 0 до 255, в зависимости от того, какую мощность мы хотим подать в этот мотор. Если мы дадим 0, то мотор остановится, если 255, то мотор будет вращаться с максимальной скоростью.
ВНИМАНИЕ – передача оператору числа большего, чем 250 может вывести из строя мотор или плату MotorShield. То же самое произойдёт, если оператору подать отрицательное число.
Это ОЧЕНЬ ВАЖНО – наша функция должна содержать ограничитель. Ни при каких обстоятельствах в оператор analogWrite (port_number, value);
нельзя подавать отрицательное value
или value
больше, чем 250.
И ещё одно – наша функция должна быть универсальной. То есть такой, чтобы Вы могли один раз её написать, отладить и затем пользоваться в любой другой программе, вызывая по мере надобности и задавая в моторы любые варианты их вращения. Это означает, что при вызове функции ей нужно передавать входные параметры:
- Направление и скорость вращения левого мотора
- Направление и скорость вращения правого мотора
Давайте придумаем названия для наших входных параметров. Например:
_left_power
– мощность в левый мотор_right_power
– мощность в правый мотор
Теперь самое время придумать имя нашей функции. Давайте назовём её –
DRIVER_Motor_Shield_Control ()
Ну и припишем к имени тип функции, и её входные параметры –
void DRIVER_Motor_Shield_Control (int _left_power, int _right_power)
void
– это тип нашей функции – (так как функция ничего не возвращает, то тип – void)
int
– это тип входных переменных – (int это сокращение от английского integer – целый)
Сейчас самое время объяснить, что такое – Драйвер (DRIVER_). Чуть позже мы будем изучать структуру больших программ и там мы встретимся с разными функциями – Драйвер, Утилита, Макрос и другими.
Драйвер – это функция, которая имеет дело с какой-то частью аппаратуры робота (в нашем случае с тяговыми моторами). Драйвер вызывается функциями более высокого ранга, когда надо что-то изменить в аппаратуре или получить от неё какую-то величину.
Таким образом, постановка задачи для нашего драйвера будет звучать так:
- Драйвер
void DRIVER_Motor_Shield_Control (int _left_power, int _right_power)
должен обеспечить вывод на плату MotorShield сигналов управления двумя двигателями – Левым и Правым в соответствии с правилами платы MotorShield. - Входными параметрами драйвера являются два целых числа
int _left_power, int _right_power
. Знак числа определяет направление вращения двигателя (плюс – ВПЕРЁД, минус – НАЗАД). Модуль числа определяет мощность, подаваемую в двигатель. - Драйвер должен обеспечить ограничение чисел, передаваемых оператору языка для управления мощностью в пределах от 0 до 250, независимо от значений входных переменных
_left_power
и_right_power
. - Адреса портов управления двигателями определяются электрическими схемами плат ARDUINO UNO и MotorShield и являются следующими:
int Port_POWER_LEFT_MOTOR = 6; // Порт мощности на левый двигатель
int Port_ POWER _RIGHT_MOTOR = 5; // Порт мощности на правый двигатель
int Port_DIR_LEFT_MOTOR = 7; // Порт направления вращения левого
int Port_DIR_RIGHT_MOTOR = 4; // Порт направления вращения правого
- Для вращения двигателя вперёд драйвер должен задавать на вывод направления вращения –
HIGH
, для вращения назад –LOW
. - Переменные, заданные выше являются для драйвера локальными.
- Установка режимов портов вывода должна производиться внутри драйвера каждый раз при его вызове.