Робот на платформе радиоуправляемого "Мерседеса"


12.07.2010, 19:54



29.07.2004 датчик вращения ведущих колес

04.08.2004 ИК-сенсор (бампер)

Собрать самостоятельно платформу - не такое простое дело. Поэтому пришлось взять радиоуправляемую машинку стоимостью примерно 10 долларов, снять кузов, отпаять плату радиоуправления и уже на базе готового шасси строить робота. Конечно, я знаю, что по канонам робототехники (читай статьи) это не совсем то, что требуется. Но всё-таки на Западе купить мотор с редуктором, сервопривод или готову платформу проще простого. У нас в Украине это или очень сложно, или достаточно дорого. Поэтому прошу прощения за небольшое отступление от правил.

Вот как выглядел Мерседес (а это был именно он) после того, как я убрал радиоуправление (видно на фото пульт и плата) и поставил первую плату. Она была достаточно простая- AT90S2313, кварц, L293D, разъемы и выключатель питания, шлейф к программатору.

Вначале плата работала нормально. Точнее, при простых операциях вроде включить двигатель, включить поворот, и так далее, но потом начались сбои. Я засомневался, может ли данная схема нормально работать? Потом был другой проект- Монстр-1, у которого двигатели сильно "шумели" и не давали микроконтроллеру нормально работать.

Поэтому я занялся разработкой плат. Первой была плата управления на основе AT90S2313. Я сделал печатную плату. Не без проблем, конечно, но сделал. Не нашел пока что хорошей программы для разводки. Они либо слишком сложные, либо простые. Так что я пока в поиске. Пока использовал Layout 3.0, но проблема была в том, что "на глаз" трудно рассчитать установочные размеры деталей, в результате чего разъем программатора закрыл места для 2-х светодиодов.

Вторая плата была плата управления двигателями. Я использовал ту же L293, только поставил 8 диодов N5819, сделал отводы для применения раздельного питания логики этой микросхемы и питания двигателей и добавил схему опторазвязки. В результате на плате может быть до 3-х разъемов питания. Пока напряжение питания невысокое, я сделал перемычку и логика питается вместе с двигателями. После тестовых испытаний оказалось, что эта схема может не самая дешевая, но зато очень надежная.

Третьей платой была тоже плата управления двигателями, но на основе микросхемы L298, которая может управлять более мощными двигателями и идет сразу с теплоотводом ( L293 ещё нужно придумать, как охлаждать). В плате используются также диоды и опторазвязка. Небольшое нововведение- плата двухсторонняя, на нижней стороне я расположил диоды в SMD-исполнении. Получилось очень даже неплохо.

Фото не очень получились, но это всё, что есть.

Так вот, я соединяю плату 1 (мозг) и плату 2 (двигатели) , подключаю всё это к платформе бывшего Мерседеса и я получаю как раз то, что и требовалось.

Теперь задача посложнее. Колёса Мерса крутятся очень быстро. Если включить двигатель хотя бы на 2-3 секунды, он разгоняется так, что пролетает всю комнату и ударяется о стену (дверь, шкаф, стул). При этом может развить как саму платформу, так и платы. Что я делаю? Классика, я делаю ШИМ (широтно-импульсную модуляцию). Я попробую привести пример программы, но не уверен, что даже специалисты её поймут. Я писал программу по блок-схеме, но пока не смог нарисовать её в редакторе. Да и не уверен пока, что программа действует. Я её прогнал, конечно на модели, но всё же...

В чем задумка. Написать программу, которая работала бы так, как работали драйвера в ДОСе или как работают многозадачные операционные системы. Второй вариант мне кажется предпочтительней. Прерывания в МК есть, но их моежт не хватить на все случаи жизни. И я рискнул работать не с прерываниями, а читать порт, просто делать это достаточно быстро. Дребезг контактов можно отсекать и программным путем.

Программа разделена на блоки. Каждый блок имеет свои переменные (ячейки памяти) и свои константы (описаны в начале программы). Например, мы устанавливаем константу работы двигателя в режиме ШИМ- робот будет управлять работой двигателя. В следующей версии программы я сделаю из константу переменную и программа сама сможет изменять скорость вращения колёс. Например, "глаза" робота видят препятствие, но он ещё не "доехал" до него. Программа может снизить скорость вращения двигателя, робот подъедет к препятствию, коснётся его, сработает либо контактный датчик, либо датчик вращения колёс и робот будет точно знать что это именно препятствие, а не что-нибудь другое. Таким же образом можно сделать торможение- резко включить двигатель назад на короткое время. Робот резко остановится. Робот может двигаться не по идеально гладкой поверхности, а по ковру, по наклонной поверхности вверх или вниз. Для движения по таким участкам робот может корректировать мощность, подаваемую на двигатели, ориентируюсь на датчик вращения колес (частота вращения). Да, осциллографа у меня пока нет, поэтому если что-то не соответствует действительности, извините и поправьте.

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

Я решил поставить дату 09.07.2004г. Если сделаю новую программу, добавлю внизу.


.include "2313def.inc"
.EQU     c_go_forward=$04    ; оба вперед
.EQU    c_go_left=$01        ; левый 
.EQU    c_go_right=$02        ; правый 
.EQU    c_go_back=$08        ; оба назад

.EQU    c_motor_mode=$03
.EQU    c_motor_freq=$10

.EQU    c_sensor_shaft_pin=1
.EQU    c_sensor_shaft_wait1=$00
.EQU    c_sensor_shaft_wait2=$01

.EQU    c_sensor_contact_pin=2

.EQU    m_sensor_shaft_wait1=$0070
.EQU    m_sensor_shaft_wait2=$0071
;.EQU    m_sensor_shaft_bcount1=$0070

.EQU    m_motor=$0080
.EQU    m_motor_new=$0081
.EQU    m_motor_count1=$0082
.EQU    m_motor_count2=$0083
.EQU    m_motor_stage=$0084
.EQU    m_motor_bcount1=$0085
.EQU    m_motor_bcount2=$0086
.EQU    m_motor_bcount3=$0087


.EQU    c_wait1=$22
.EQU    c_wait2=$ff


.DEF    temp=R30
.DEF    temp2=R29

;====================================
;    I N I T 
;====================================
; готовим порт В для вывода
    ldi temp,$0F
    out DDRB,temp

; готовим порт D для входа
    ldi temp,$00
    out DDRD,temp

; включаем резисторы- на входе будет 1
    ldi temp,$7F
    out PORTD,temp

; инициализация стека
    ldi temp,RAMEND
    out SPL,temp

; инициализация новых переменных
    ldi temp,1        ; 1
    sts m_motor_stage, temp    ; стадия работы мотора

; начало
    ldi temp, c_go_forward    ; движение вперед
    sts m_motor, temp
    sts m_motor_new, temp

start:

;------- проверка режима работы
    ldi temp, c_motor_mode    ; загрузить режим работы мотора в темп
    cpi temp, 0        ; режим полный?
    brne l_motor2        
;------- режим полный
    lds temp, m_motor_new    ; загрузить переменную мотор новый в темп
    lds temp2, m_motor    ; загрузить текущее значение мотора
    sub temp, temp2        ; сравнить старое значение с новым
    breq l_motor_end

    lds temp, m_motor_new    ; загрузить переменную мотор новый в темп
    sts m_motor, temp
    out PORTB, temp        ; вывести temp в порт
    rjmp l_motor_end    

;------- режим ШИМ
l_motor2:
    lds temp, m_motor_stage    ; какая стадия работы?
    cpi temp, 0        ; если 0-
    breq l_motor2_11 
    lds temp, m_motor    ; загрузить значение мотора
l_motor2_11:
    out PORTB, temp        ; вывести temp в порт
    ; минус счетчики
    lds temp, m_motor_count1    ; загрузить счетчик младший
    dec temp            ; минус 1
    sts m_motor_count1, temp ; сохранить младший байт    
    cpi temp, 0        ; равно 0 ?
    brne l_motor_end    ; если нет- на конец цикла
    ; eq 0 - init 
    ldi temp, c_motor_freq    ; загрузить константу младшей части 
    sts m_motor_count1, temp ; сохранить младший байт

    lds temp, m_motor_count2    ; загрузить старший байт
    dec temp            ; минус 1
    sts m_motor_count2,temp        ; save
    cpi temp, 0            
    brne l_motor_end        

    ; меняем стадию работы
;l_motor3_0:        
    lds temp, m_motor_stage    ; какая стадия работы?
    cpi temp, 0     ; если=0
    brne l_motor3_1    ; если 1=
    ldi temp,1
    sts m_motor_stage, temp ; стадия=1
    ldi temp, c_motor_mode    ; частота - старшая часть 
    rjmp l_motor3_2

l_motor3_1:    
    ldi temp,0
    sts m_motor_stage, temp ; стадия=0
    ldi temp2, c_motor_mode    ; частота - старшая часть 
    ldi temp,10    ; если 0- пауза, время паузы равно 10 минус время работы
    sub temp, temp2    ;
    
l_motor3_2:    
    ; установка для ШИМ
    lsl temp
    lsl temp
    lsl temp
    lsl temp
    sts m_motor_count2, temp ; частота - старшая часть 

    ldi temp, c_motor_freq    ; частота - mладшая часть 
    sts m_motor_count1, temp ;

l_motor_end:

    rjmp start

; подпрограмма задержки
f_wait:
loop71:    

    ldi r27,c_wait1
loop72:    
    
    ldi r26,c_wait2

loop73:    dec r26
    nop
    nop
    nop
    cpi r26,0
    brne loop73    ;---------------

    dec r27
    cpi r27,0
    brne loop72    ;----------------

    dec r28
    cpi r28,0
    brne loop71    ;----------------
    ret
    .exit    

29.07.2004 Датчик вращения ведущих колес

Я приклеил маленький магнит к колесу, а на корпус установил геркон, контакты которого подключил к общему проводу и одному из входов.

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

Программно реализовано достаточно просто- используя 2 ячейки памяти (AТ90S2313), я веду обратный отсчет от факта изменения датчика (1/0). Если пауза затягивается, идет переход на ту часть программы, которая отвечает за разворот (поворот). При каждом изменении датчика я инициализирую переменные обратного отсчета.

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

 

; инициализация
.EQU    c_sensor_shaft_pin=3        ; на каком пине shaft сенсор
.EQU    c_sensor_shaft_wait=$A0        ; задержка пока есть контакт


.EQU    m_sensor_shaft_wait1=$0070    ;counter
.EQU    m_sensor_shaft_wait2=$0071    ;counter
.EQU    m_sensor_shaft_mem=$0072     ; memory stage (1/0)


.DEF    temp=R30
.DEF    temp2=R29




; часть программы, которая обрабатывает данные с сенсора


    lds temp2, m_sensor_shaft_mem    
    in temp,PIND    ; прочитать порт Д

    sbrs temp, c_sensor_shaft_pin    ; если установлен сенсор
    rjmp l_ssensor2    

    cpi temp2,1
    breq l_ssensor3    

    ldi temp,1    
    sts m_sensor_shaft_mem, temp    ; save 1
    rjmp l_ssensor4


l_ssensor2:
    cpi temp2,0 
    breq l_ssensor3    

    clr temp
    sts m_sensor_shaft_mem, temp    ; save 0
    rjmp l_ssensor4


l_ssensor3:
    ; count  test jump


    lds temp, m_sensor_shaft_wait1    ; младшая часть
    cpi temp,0
    brne l_ssensor31
    ldi temp, $ff    ; частота - mладшая часть 

    sts m_sensor_shaft_wait1, temp ; сохранить младший байт

    lds temp, m_sensor_shaft_wait2    ; старшая часть
    cpi temp,0
    brne l_ssensor32
    rjmp l_back    ; счетчики - нули, перейти на обработку разворота


l_ssensor31:
    dec temp
    sts m_sensor_shaft_wait1, temp ; сохранить младший байт
    rjmp l_ssensor5


l_ssensor32:
    dec temp
    sts m_sensor_shaft_wait2, temp ; сохранить st байт
    rjmp l_ssensor5


l_ssensor4:
    ; инициализировать счетчики
    ldi temp, $ff
    sts m_sensor_shaft_wait1, temp
    ldi temp,c_sensor_shaft_wait    
    sts m_sensor_shaft_wait2, temp     
l_ssensor5:


 


04.08.2004 ИК-сенсор (бампер)

В Интернете я нашел множество схем ИК-сенсоров, но большинство их них были на МК PIC. Я с ними близко не знаком, разбираюсь пока с Atmel, поэтому использовал схему от www.roboclub.ru, основанную на ATiny12. Сенсор получается достаточно дорогостоящим, но, думаю, что вскоре я разработаю свой вариант. Главное- это стабильный генератор. Его можно собрать и на элементах ЛА3, и на микросхеме 555, но я не уверен, что сенсор будет работать стабильно. У меня уже есть осциллгограф, поэтому буду надеяться, что рани или поздно все получится. С этой схемой я разобрался в основном после того, как просмотрел все сигналы на осциллографе. Поэтому рекомендую приобрести или взять в аренду (я купил за $50 аппарат С1-49 выпуска 1970 года).

Вот тут я попытался изобразить схему.

Печатная плата вам не нужна, да и не умею я делать красиво. Кстати, платы я делаю по технологии "пленка-лазерный принтер-утюг-хлорное железо".

От плата:

Вот как это выглядит совместно с роботом:

Робот отлично "видит" стены, другие препятствия. Если он упирается в какой-нибудь предмет и не может сам разобраться, я беру в руки пульт ДУ и помогаю ему. Дальнобойность пульта меня поражает (а может это наоборот, чувствительность датчика?) - если я вижу робота, то и робот видит сигнал. А если робот уехал в коридор или другую комнату, то и там я его могу "достать" при помощи пульта ДУ.

Тут по поводу пульта ДУ у меня уже есть идеи. Нужно как-то кодировать сигнал, потому что он будет пересекаться с сигналами других роботов, а в случае боевого робота он должен наоборот, "идти" на вражеский сигнал, а если видит отражение своего, реагировать как на препятствия. Интересно, ведь от вражеского робото тоже будет отражаться сигнал!?! Тут нужно подумать.

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

;----- бампер начало

    in temp, c_sensor_bumper_inpin    ; прочитать порт bumper
    sbrc temp, c_sensor_bumper_pin1    ; если не установлен сенсор
;    rjmp l_bsensor2
    rjmp program_stop
    rjmp l_bsensor5


    sbrc temp, c_sensor_bumper_pin2    ; если не установлен сенсор
;    rjmp l_bsensor3
    rjmp program_stop
    rjmp l_bsensor5


l_bsensor5:
;----- бампер конец


Ключевые слова:
робот на платформе
Роботы своими руками
робот


Вернуться в рубрику:

Роботы своими руками


Хотите видеть на нашем сайте больше статей? Кликните Поделиться в социальных сетях! Спасибо!

Смотрите также:

Обратите внимание полезная информация.

Робототехника для каждого. 2024г.