-
Введение
-
Глава 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. Делаем калькулятор
- Гонки за лидером
- Послесловие
- Список программ для Ардуино
- Лицензионное соглашение
Шаблон основной программы
Всё, что мы делали до сих пор в этой главе – теория. Нам же интересно не просто написать программу, а сделать так, чтобы она работала совместно с аппаратурой робота и выполняла те действия, которые нам необходимы.
Помните, в предыдущих главах мы упоминали логические ошибки. Из-за них робот делает не то, что хочется. Этап испытаний и отладки необходим, чтобы выявить логические ошибки в алгоритме и исходном тексте и исправить их. Иногда бывает, что логическая ошибка закралась в постановку задачи, но это довольно редкий случай.
Так что наше дело сейчас – алгоритм и исходный текст, а так же взаимодействие программы и аппаратной части. Сама по себе программа без связи с аппаратурой – это просто текст. А вот при взаимодействии с аппаратной частью она выполняет те действия, ради которых мы всё это и затеяли.
Итак, начинаем испытания и отладку драйвера.
void DRIVER_Motor_Shield_Control (int _left_power, int _right_power)
Для начала надо убедиться, что аппаратная часть собрана правильно. В нашем случае необходимо убедится, что работы первой главы выполнены в соответствии с описаниями этой главы.
Далее надо бы загрузить наш драйвер в память микроконтроллера и посмотреть, как он будет работать. Но драйвер, как он написан на предыдущей странице, загружать пока ещё нельзя. Для этого к нему придётся кое-что добавить.
Давайте запишем наш драйвер так –
void DRIVER_Motor_Shield_Control (int _left_power, int _right_power)
{
}
Вы видите имя с типом, декларацию входных переменных, фигурные скобки и прямоугольник, символизирующий текст драйвера. Мы так поступаем для удобства дальнейшего изложения. В реальной программе на месте этого прямоугольника должен быть полностью записанный исходный текст.
Вспомним главу 2 – а именно функции void setup () и void loop
()
.
В нашем драйвере все начальные установки производятся внутри него самого, так что setup
()
можно оставить пустым. Помещать исходный текст драйвера в loop ()
можно, но лучше поместить его под loop ()
как самостоятельную функцию.
Например, так
//***************************************************************
// Декларирование программ-функций
//***************************************************************
// ДРАЙВЕРЫ И КАЛЬКУЛЯТОРЫ
void DRIVER_Motor_Shield_Control (int _left_power, int _right_power); // управление моторами
//*****************************************************
void setup()
{
}
//*****************************************************
void loop()
{
DRIVER_Motor_Shield_Control (100, 100);
}
//******************************************************
//**Начало драйвера управления тяговыми моторами*********
//******************************************************
void DRIVER_Motor_Shield_Control (int _left_power, int _right_power)
{
}
//******************************************************
//****** Конец драйвера управления тяговыми моторами *****
//******************************************************
Рассмотрим поподробнее, что тут написано.
- Во-первых, начинается всё с раздела Декларирование программ-функций. Здесь мы как бы даём объявление – “Всем-всем, в нашей программе есть такие-то функции”.
- Во-вторых, у нас функция
setup ()
пустая. Это потому, что все начальные установки располагаются в самом драйвере. В дальнейшем по мере написания новых функций эта часть начнёт разрастаться. - В-третьих, в функции
loop ()
записан заголовок нашего драйвера и в круглых скобках стоит(100,100)
. Это значит, что в этом месте нашей программы мы вызываем наш драйвер для выполнения его работы – запустить оба мотора вперёд с мощностью плюс 100 каждый. Не забудьте точку с запятой. - В-четвёртых, текст драйвера записан отдельно, после функции
loop
()
.
У нас пока нет декларирования и определения портов ввода-вывода, так как порты управления моторами могут использоваться только платой MotorShield. По мере развития нашего робота у нас будут появляться порты, которые могут быть использованы разными функциями и аппаратными устройствами. И тогда строчки декларирования портов будут добавляться в самом начале программы – перед декларированием функций и перед функцией setup ()
.
ВАЖНОЕ СООБЩЕНИЕ – начиная с этой главы, у нас будет отдельное приложение – файл программы, с которым можно работать в системе Arduino IDE. Название файла “Programm_Modul_N_..........ino”
, где N – номер главы книги. На месте точек располагаются добавочные слова в случае, если в данной главе используются несколько файлов.
На самом деле это одна и та же основная программа, или шаблон, который будет создан в этой главе. Просто, в каждой новой главе мы будем прибавлять к основной программе новые функции. А в функции loop ()
, будут вызовы тех функций, которые пишутся и настраиваются или используются в данной главе.
Поэтому у каждой главы будет свой вариант программы. В соответствии с правилами системы Arduino IDE файл .ino располагается в папке с таким же именем.
Теперь мы сможем откомпилировать эту программу и загрузить её в плату Arduino UNO. Надеюсь, что синтаксических ошибок нет, и подключение к компьютеру есть. Если так, то после загрузки моторы должны закрутиться оба вперёд.
Не забудьте, что для этого на плату MotorShield надо подать напряжение от основной батареи через отдельную пару проводов на специальные колодки с винтовыми зажимами. ВАЖНО – соблюсти полярность питания. Чтобы робот не убежал от Вас, лучше поставить его на столе вверх колёсами.
Иногда моторы не крутятся после первого включения. Так бывает, если неправильно подключены провода к винтовым зажимам выходов платы MotorShield или неаккуратно соединены платы или неправильно собрана схема питания от основной батареи.
Возможно, придётся попотеть, разбираясь с проводами, схемами и описаниями из интернета и из первой главы, но это необходимый этап. Довольно часто профессиональные электронщики утешают себя, приговаривая: “Если прибор заработал с первого включения, то значит он либо неверно спроектирован, либо неверно собран”.
Далее надо убедиться, что управление моторами производится драйвером правильно. Для этого надо последовательно изменять параметры в вызове драйвера (там, где он записан в функции loop ()
) и смотреть, как при этом крутятся моторы.
- Записываем
DRIVER_Motor_Shield_Control (100, 0);
– левый крутится вперёд, правый стоит. - Записываем
DRIVER_Motor_Shield_Control (-100, 0);
– левый назад, правый стоит. - Записываем
DRIVER_Motor_Shield_Control (0, 100);
– левый стоит, правый вперёд. - Записываем
DRIVER_Motor_Shield_Control (0, -100);
– левый стоит, правый назад.
Если моторы крутятся не так, как написано, то надо соответственно поменять подключение проводов моторов к винтовым зажимам платы MotorShield. Не забывайте проводить компиляцию и загрузку после каждого изменения в программе.
Теперь у нас есть не просто драйвер, а готовый шаблон программы для дальнейшей работы. В следующих главах мы будем прибавлять к нему новые и новые функции. А пока кликните в интерфейсе Arduino IDE File -> Save As -> ………, выберите какое-то место в Вашем компьютере и придумайте название Вашей первой программе.
В нашем кружке мы завели себе одну флешку. На ней каждый имеет свою папочку-директорий, где хранятся его программы. Чтобы флешка не затерялась, к ней прикрепили маленькую игрушку. Игрушка была в виде маленького тигрёнка, поэтому мы назвали флешку – “Тигрёнок”.
И ещё одно – сейчас в исходном тексте программы у нас декларирована, вызвана и определена только одна функция. Других пока нет. По мере написания новых мы будем прибавлять их в раздел Декларирования, и он начнёт разрастаться. Нам удобно, чтобы все написанные нами функции были бы упомянуты в этом разделе. Даже те, которые в данной программе не используются.
Давайте договоримся так – в наших первых программах Вы тоже будете так делать. Когда опыта у Вас станет больше, Вы решите либо продолжать таким же образом, либо нет.
Тут жёстких правил нет – вопрос личного удобства.