Робот избегающий препятствия на ATmega32

Робот избегающий препятствия на ATmega32

В этой статье показано  изготовление простого робота, избегающего препятствия на плате Xboard v2.0. Данная плата хорошо подходит для небольших умных роботов, потому что она компактна, имеет четыре контроллера двигателей постоянного тока, может быть прошита по USB и имеет ещё много других функций. Также она очень проста в освоении и использовании. xAPI представляет собой набор функций на С, предназначенные для решения сложных программных задач, таких как работа с ШИМ, ЖК-дисплеем, дистанционным управление и т.д. Очень хорошо и легко для новичков. Её конструкция является открытой, поэтому если вы не хотите покупать Xboard v2.0, вы можете изготовить её самостоятельно. 

Цель нашего робота проста: необходимо двигаться в любом месте, избегая препятствий. Задача проста, и робот выполняет её полностью самостоятельно. У него есть мозг, который считывает информацию с датчиков, принимает решение и управляет двигателями.

Во время создания робота вы узнаете различные базовые методы, которые пригодятся вам в будущем.

Механическая часть робота

Робот собран в качественном металлическом корпусе, который можно приобрести в магазине робототехники. Робот приводится в движение двумя моторами-редукторами постоянного тока  200 RPM. Он использует систему дифференциальной передачи и имеет одно касторовое колесо спереди.  Колеса связаны непосредственно с валом двигателя.

Двигатели крепятся к шасси при помощи гайки, накручиваемой на резьбу возле вала.

Xboard v2.0 монтируется с помощью монтажного комплекта, который идет в комплекте и включает в себя болты, гайки и стойки. Xboard v2.0 сделана так, что её крепежные отверстия совпадают с отверстиями в корпусе.

Дифференциальная передача

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

Направление движения

Левое колесо

Правое колесо

Вперед

Против часовой стрелки

По часовой стрелке

Назад

По часовой стрелке

Против часовой стрелки

Поворот влево

По часовой стрелке

По часовой стрелке

Поворот вправо

Против часовой стрелки

Против часовой стрелки

На картинке это показано более наглядно.

Таким образом, перемещение и управление роботом осуществляется путем управления двумя двигателями, что легко делается при помощи xAPI. Подробнее об этом написано по ссылкам:

http://xboard.extremeelectronics.co.in/Motor1.htm

http://xboard.extremeelectronics.co.in/Motor2.htm

В статьях рассказано, как запустить двигатель по часовой стрелке или против неё. MotorA – правый двигатель, MotorB – левый двигатель. Фрагменты кода, показывающие работу с двигателями. 

Движение робота вперед:

MotorA(MOTOR_CW,255); // правый мотор вращается по часовой стрелке (CW) с макс. скоростью (255)

MotorB(MOTOR_CCW,255); // левый мотор вращается против часовой стрелки (CCW) с макс. скоростью (255)

Движение робота назад:

MotorA(MOTOR_CCW,255); // правый мотор вращается против часовой стрелки (CCW) с макс. скоростью

MotorB(MOTOR_CW,255); // левый мотор вращается по часовой стрелке (CW) с макс. скоростью (255)

Поворот на лево:

MotorA(MOTOR_CW,255); // правый мотор вращается по часовой стрелке (CW) с макс. скоростью (255)

MotorB(MOTOR_CW,255); // левый мотор вращается по часовой стрелке (CW) с макс. скоростью (255)

Поворот на право:

MotorA(MOTOR_CCW,255); // правый мотор вращается против часовой стрелки (CCW) с макс. скоростью

MotorB(MOTOR_CCW,255); // левый мотор вращается против часовой стрелки (CCW) с макс. скоростью (255)

О MotorA и MotorB можно узнать подробнее, перейдя по ссылке

Датчики

Бесконтактные датчики помогают роботу обнаруживать препятствия на своем пути. Датчики включают в себя ИК-передатчики и ИК-приемники. В качестве ИК-передатчика используется ИК-светодиод, который излучает свет в ИК-спектре, невидимом для человеческого глаза. ИК-приемник принимает эти лучи.

ИК-датчик

ИК-датчик состоит из ИК-приемника, Ик-передатчика и нескольких резисторов. Схема приведена ниже. Нам необходимо три таких датчика, установленных на переднюю часть робота.

Как вы можете видеть, датчик имеет два контакта: питание и выход. На выходе датчика может быть напряжение от 0 до 5В в зависимости от расстояния до препятствия и его типа. Напряжение приближается к 5В, когда препятствие рядом.

Номинал R1 150Ом, R2 22кОм. Цветовой код показан на схеме выше. Номиналы резисторов очень важны, поэтому используйте только резисторы указанного номинала. Короткий вывод ИК-приемника черного (полупрозрачного) цвета является положительным выводом. Это не ошибка, поэтому подключайте его именно так.

ИК-приемник и ИК-передатчик должны быть установлены так, чтобы ИК лучи от ИК-передатчика падали на препятствия и отражались в ИК-приемник. Их правильное расположение показано на картинке.

Выход датчика подключается к АЦП AVR микроконтроллера. АЦП превращает напряжение  в 10 битное цифровое значение от 0 до 1024. То есть, ориентируясь на значение с АЦП,  вы можете узнавать о наличии препятствий перед датчиком. Работа с АЦП Xboard v2.0 проста и описана по ссылке.

Если мы подключили датчик к ADC0, то получить информацию с него можно при помощи следующей функции:

int sensor_value;

sensor_value=ReadADC(0);//Read Channel number 0

При использовании резисторов указанных на схеме выше, значение sensor_value составляет около 660 когда перед датчиком нет препятствия,  и 745 когда до препятствия около 15 см. Если препятствие находится на расстоянии ближе чем 6 см, то значение 1023. Это максимальное значение, и даже если препятствие еще ближе, то значение не повышается.

Обратите внимание, что эти значения могут варьироваться в зависимости от типа препятствия. Некоторые объекты отражают ИК лучи лучше или хуже, чем другие. Некоторые объекты отражают ИК-лучи очень плохо, и не могут быть обнаружены.  Эти результаты были получены при использовании ладони в качестве препятствия. Например, ИК-лучи плохо отражает дерево, покрашенное в темные цвета, например двери.

Объединение и подключение ИК-датчиков

Три ИК-датчика крепятся на макетную плату, которая крепится на переднюю часть робота.  Один датчик установлен в центре плату, а два других справа и слева соответственно.

Для начала макетная плата обрезается до нужных размеров. Это можно сделать при помощи небольшой ножовки по металлу.

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

На другой стороне платы мы одеваем распорки на винты, чтобы иметь расстояние между   макетной платой и шасси.

Теперь макетную плату можно устанавливать на шасси

Обратите внимание, что я использую подстроечные резисторы вместо постоянных на 22кОм. Но вы должны использовать постоянные резисторы на 22кОм. Макетная плата подключается к Xboard v2.0 с использованием стандартного 8 выводного коннектора. Xboard v2.0 имеет 8 выводной разъем для датчиков. Также в этом разъеме есть выводы +5В и GND для датчиков. Его распиновка показана ниже.

Подключите правый датчик к ADC0, центральный датчик к ADC 1 и левый датчик к ADC 2. Датчики готовы, и теперь можно перейти к их тестированию.

Тестирование ИК-датчиков

Ниже приведена небольшая тестовая программа, которая считывает значение с трех датчиков и отображает его на ЖК-дисплее. Для понимания работы программы прочитайте статью Взаимодействие с ЖК-дисплеем при помощи xAPI.

#include “avr/io.h” #include “util/delay.h” #include “lcd.h” void InitADC() { ADMUX=(1<<REFS0); // For Aref=AVcc; ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Rrescalar div factor =128 } uint16_t ReadADC(uint8_t ch) { //Select ADC Channel ch must be 0-7 ch=ch&0b00000111; ADMUX&=0b11100000; ADMUX|=ch; //Start Single conversion ADCSRA|=(1<<ADSC); //Wait for conversion to complete while(!(ADCSRA & (1<<ADIF))); //Clear ADIF by writing one to it //Note you may be wondering why we have write one to clear it //This is standard way of clearing bits in io as said in datasheets. //The code writes ‘1’ but it result in setting bit to ‘0’ !!! ADCSRA|=(1<<ADIF); return(ADC); } void Wait() { uint8_t i; for(i=0;i<<20;i++) _delay_loop_2(0); } void main() { uint16_t adc_result[3]; //Array //Wait for LCD to Startup _delay_loop_2(0); //Initialize LCD LCDInit(LS_BLINK|LS_ULINE); LCDClear(); //Initialize ADC InitADC(); //Welcome and Intro LCDWriteString("xBoard Sensor"); LCDWriteStringXY(0,1,"Test Utility"); Wait(); Wait(); Wait(); Wait(); LCDClear(); LCDWriteString("S#1 S#2 S#3 "); while(1) { adc_result[0]=ReadADC(0); // Считываем значение с канала АЦП 0 adc_result[1]=ReadADC(1); // Считываем значение с канала АЦП 1 adc_result[2]=ReadADC(2); // Считываем значение с канала АЦП 2 LCDWriteIntXY(0,1,adc_result[0],4); // Отображаем значение LCDWriteIntXY(5,1,adc_result[1],4); // Отображаем значение LCDWriteIntXY(10,1,adc_result[2],4); // Отображаем значение Wait(); } }

Скомпилируйте и прошейте программу в Xboard v2.0. После этого подключите ЖК-дисплей и плату с датчиками. На экране должны быть значения с трех датчиков как показано ниже.

Когда вы подносите препятствие к одному из датчиков, значение с него должно увеличиваться, а когда препятствие совсем близко, то увеличиться до 1023. Запишите значения датчиков когда препятствия перед ними нет и когда препятствие на расстоянии около 15 см от него. Эти значения понадобятся вам для настройки программы робота.

Также я предоставил HEX файл, готовый для прошивки микроконтроллера ATmega32 (или ATmega16) и запуска в кратчайшие сроки.

Если на дисплее нет никакого текста, настройте контрастность потенциометром.

Если датчики работают не как ожидалось, проверьте соединения. Для проверки работы ИК-светодиодов используйте любую цифровую камеру, например Handicam или камеру мобильного телефона.  Невидимые для человеческого глаза ИК-лучи хорошо видны камере. Если светодиоды не излучают ИК-лучи, проверьте соединения.

Программная часть

Задача программы состоит в том, чтобы считывать значения с датчиков, принимать решения и управлять двумя двигателями. Таким образом, робот будет ездить по комнате, объезжая всё на своем пути.

Мы определили три константы, а именно RTHRES, CTHRES и LTHRES:

//Threshold Values For Sensor Triggering

#define RTHRES 195

#define CTHRES 275

#define LTHRES 195

Их постоянными величинами являются внесенные значение. Они должны быть уже записаны. Как их получить описано выше. Когда значение с датчика приближается к этому пороговому значению, программа воспринимает это как препятствие. Обратите внимание, что значения указанные выше могут не соответствовать вашим. Это нормально.

Программа начинается с инициализации подсистемы двигателя и подсистемы АЦП:

MotorInit();

InitADC();

Потом мы начинаем двигать робота вперед. Это делается при помощи обращения к функциям MotorA и MotorB. Первым аргументом является необходимое направление:

    MOTOR_STOP

    MOTOR_CW

    MOTOR_CCW

Вторым аргументом является необходимая скорость. Ее значение может от 0 до 255. Мы используем 25,5 чтобы двигаться на полной скорости.

Более подробную информацию о работе с двигателем при помощи xAPI можно найти в документации Xboard v2.0.

После того как наш робот начинает двигаться вперед, мы переходим в бесконечный цикл, проверяя, если какое-то препятствие перед роботом. Если да, то робот поворачивает.

Скачать прошивки и исходники проекта в Atmel Studio

Оригинал статьи на английском языке (перевод: Александр Касьянов для сайта cxem.net)


Категория: Аппаратура радиоуправления моделями
Метки:

Написать коментарий

*
= 3 + 9

Добавить изображение

Последние статьи