roboforum.ru

Технический форум по робототехнике.

Прога мобильного робота на бейсике

Прога мобильного робота на бейсике

space » 12 авг 2008, 21:51

Это почти такая же программа мобильного робота как и на си. Только не стал делать движение на свет. А во стольном всё тоже самое. Вообщем вот:
Код: Выделить всёРазвернуть
$regfile = "m16def.dat"                    'используем мк ATmega16
$crystal = 16000000                    'частота кварцевого резонатора 16mHz
$lib "lcd4.lbx"                    'используем 4-х битное подключение дисплея с помощью альтернативной библиотеки
$baud = 19200                    'Скорость COM-порта
' указываем конфигурацию подключения дисплея к портам МК
Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.2 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 16 * 2                    'используем дисплей на 2 строчки по 16 знакомест в каждой

Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Config Pina.0 = Output : Fr Alias Porta.0                   'PA 0 устанавливаем на выход и присваиваем имя Fr(вперёд-вправо);
Config Pina.1 = Output : Br Alias Porta.1                   'PA 1 устанавливаем на выход и присваиваем имя Br(назад-вправо);
Config Pina.2 = Output : Bl Alias Porta.2                   'PA 2 устанавливаем на выход и присваиваем имя Bl(назад-влево);
Config Pina.3 = Output : Fl Alias Porta.3                   'PA 3 устанавливаем на выход и присваиваем имя Fl(вперёд-влево).

Config Pind.2 = Input : Bumper_r Alias Pind.2               'PD 0 устанавливаем на вход и присваиваем имя Bumper_r(правый бампер);
Config Pind.3 = Input : Bumper_l Alias Pind.3               'PD 1 устанавливаем на вход и присваиваем имя Bumper_l(левый бампер).

Config Pinc.2 = Input : Кнопка_старт Alias Pinc.2           'PC 2 устанавливаем на вход и присваиваем имя Кнопка_старт;
Config Pinc.3 = Input : Кнопка_стоп Alias Pinc.3            'PC 3 устанавливаем на вход и присваиваем имя Кнопка_стоп;
Config Pinc.4 = Input : Кнопка_3 Alias Pinc.4               'PC 4 устанавливаем на вход и присваиваем имя Кнопка_3;
Config Pinc.5 = Input : Кнопка_4 Alias Pinc.5               'PC 5 устанавливаем на вход и присваиваем имя Кнопка_4.

Config Pinb.0 = Output : Red_0 Alias Portb.0                'PB 0 устанавливаем на выход и присваиваем имя Red_0;
Config Pinb.1 = Output : Red_1 Alias Portb.1                'PB 1 устанавливаем на выход и присваиваем имя Red_1;
Config Pinb.2 = Output : Red_2 Alias Portb.2                'PB 2 устанавливаем на выход и присваиваем имя Red_2.

Enable Interrupts                    ' разрешаем прерывания

Dim Rand As Byte

Print "Start RoBi"                    ' выводим стартовую надпись в терминали через COM-порт

Cls                    'команда очистки дисплея
Cursor Off                    ' отключаем корсор на LCD
Lcd "I am RoBi!"                    'выводим надпись
Lowerline                    ' переходим на нижнюю строчку
Lcd "Gotov k rabote."                    'выводим надпись

Основная_программа:
Do                    'Основной цикл программы
Rand = Rnd(50)

If Rand = 48 Then : Gosub Стоп : Waitus 10 : End If
If Rand = 1 Then : Gosub Стоп : Waitus 10 : End If
If Rand = 49 Then : Gosub Вперёд : Wait 2 : End If
If Rand = 17 Then : Gosub Вперёд : Wait 1 : End If
If Rand = 27 Then : Gosub Вперёд : Wait 2 : End If
If Rand = 32 Then : Gosub Вперёд : Wait 1 : End If
If Rand = 44 Then : Gosub Назад : Wait 1 : End If
If Rand = 4 Then : Gosub Назад : Wait 1 : End If
If Rand = 45 Then : Gosub Вправо : Wait 1 : End If
If Rand = 2 Then : Gosub Вправо : Wait 1 : End If
If Rand = 22 Then : Gosub Влево : Wait 1 : End If
If Rand = 3 Then : Gosub Влево : Wait 1 : End If

Debounce Bumper_r , 0 , L                    'сработал правый датчик, переходим на выполнение команды Bl
Debounce Bumper_l , 0 , R                    'сработал левый датчик, переходим на выполнение команды Br

Loop

'' -----------------------------------------------------------------------------
'' Включение комбинации моторов для движения в заданном направлении
'' -----------------------------------------------------------------------------
Стоп:                    ' стоим на месте
Fr = 0 : Br = 0 : Bl = 0 : Fl = 0 :
Return
Вперёд:                    ' едим вперёд
Fr = 1 : Br = 0 : Bl = 0 : Fl = 1 :
Return
Вперёд_вправо:                    ' поварачиваем вправо
Fr = 0 : Br = 0 : Bl = 0 : Fl = 1 :
Return
Вперёд_влево:                    ' поворачиваем влево
Fr = 1 : Br = 0 : Bl = 0 : Fl = 0 :
Return
Назад:                    ' назад
Fr = 0 : Br = 1 : Bl = 1 : Fl = 0 :
Return
Назад_вправо:                    ' поворачиваем назад-вправо
Fr = 0 : Br = 1 : Bl = 0 : Fl = 0 :
Return
Назад_влево:                    ' поворачиваем назад-влево
Fr = 0 : Br = 0 : Bl = 1 : Fl = 0 :
Return
Вправо:                    ' разворот на метсе вправо
Fr = 0 : Br = 1 : Bl = 0 : Fl = 1 :
Return
Влево:                    ' разворот на месте влево
Fr = 1 : Br = 0 : Bl = 1 : Fl = 0 :
Return

R:                    ' выполнять после срабатывания правого датчика
Gosub Назад                    ' переходим в подпрограмму "Назад"
Wait 1                    ' выполняем её в течение 2,5 секунд
Gosub Назад_влево
Wait 1
Gosub Стоп
Goto Основная_программа                    ' переходим к началу основного цикла после выполнения команд
L:
Gosub Назад
Wait 1
Gosub Назад_вправо
Wait 1
Gosub  Стоп
Goto Основная_программа

Хочу сделать старт и остановку по нажатию кнопок. Пробовал по разному используя оператора выхода и перехода(If ... Then ... Else ... End if). Но не получается.
Например такой вариантик был:
Код: Выделить всёРазвернуть
If Кнопка_старт = 1 Then : Gosub Выбор_направления
Else
Gosub Основная_программа : End if

Но бесполезняк. Есть у кого идеи? Может по другому моно сделать?

Добавлено спустя 17 минут 25 секунд:
Кстати прогу, та которую выкладывал рабочай 100%. Проверял

Re: Прога мобильного робота на бейсике

EdGull » 12 авг 2008, 21:56

а тебе в Основная_программа зачем ду-луп?

Re: Прога мобильного робота на бейсике

space » 12 авг 2008, 22:07

Если я основной цикл уберу, то сервы будут крутиться только вперёд без смены направления, если же с циклом, то всё норм. Наверняка можно и без него, но я то этого не знаю, так как только учусь :)

Re: Прога мобильного робота на бейсике

space » 13 авг 2008, 18:38

Пробовал сделать со светодиодами и всё получилось. По нажатию кнопки старт светик горит, а по нажатию кнопки стоп, светик гаснит.
Всё оказалось легко и просто.

Код: Выделить всёРазвернуть
$regfile = "m16def.dat"
$crystal = 16000000

Config Pinb.0 = Output : Red_0 Alias Portb.0
Config Pinc.2 = Input : Кнопка_старт Alias Pinc.2
Config Pinc.3 = Input : Кнопка_стоп Alias Pinc.3

Основная:
Do

If Кнопка_старт = 0 Then : Gosub Горит : End If
If Кнопка_стоп = 0 Then : Gosub Не_горит : End If

Loop

Горит:
Red_0 = 1
Goto Основная

Не_горит:
Red_0 = 0
Goto Основная
End


Добавлено спустя 2 часа 12 минут 21 секунду:
Вот сделал:
Код: Выделить всёРазвернуть
$regfile = "m16def.dat"
$crystal = 16000000

Config Pina.0 = Output : Fr Alias Porta.0                   'PA 0 устанавливаем на выход и присваиваем имя Fr(вперёд-вправо);
Config Pina.1 = Output : Br Alias Porta.1                   'PA 1 устанавливаем на выход и присваиваем имя Br(назад-вправо);
Config Pina.2 = Output : Bl Alias Porta.2                   'PA 2 устанавливаем на выход и присваиваем имя Bl(назад-влево);
Config Pina.3 = Output : Fl Alias Porta.3                   'PA 3 устанавливаем на выход и присваиваем имя Fl(вперёд-влево).

Config Pinc.2 = Input : Кнопка_старт Alias Pinc.2
Config Pinc.3 = Input : Кнопка_стоп Alias Pinc.3
Dim Rand As Byte
Do                                                          'Основной цикл программы

Основная_программа:

If Кнопка_старт = 0 Then : Gosub Выбор_направления : End If
If Кнопка_стоп = 0 Then : Gosub Ожидание : End If

Loop
End

Выбор_направления:
Rand = Rnd(50)

If Rand = 48 Then : Gosub Стоп : Waitus 10 : End If
If Rand = 1 Then : Gosub Стоп : Waitus 10 : End If
If Rand = 49 Then : Gosub Вперёд : Wait 2 : End If
If Rand = 17 Then : Gosub Вперёд : Wait 1 : End If
If Rand = 27 Then : Gosub Вперёд : Wait 2 : End If
If Rand = 32 Then : Gosub Вперёд : Wait 1 : End If
If Rand = 44 Then : Gosub Назад : Wait 1 : End If
If Rand = 4 Then : Gosub Назад : Wait 1 : End If
If Rand = 45 Then : Gosub Вправо : Wait 1 : End If
If Rand = 2 Then : Gosub Вправо : Wait 1 : End If
If Rand = 22 Then : Gosub Влево : Wait 1 : End If
If Rand = 3 Then : Gosub Влево : Wait 1 : End If

Goto Основная_программа

Ожидание:                                                   ' стоим на месте
Fr = 0 : Br = 0 : Bl = 0 : Fl = 0 :
Goto Основная_программа

'' -----------------------------------------------------------------------------
'' Включение комбинации моторов для движения в заданном направлении
'' -----------------------------------------------------------------------------

Стоп:                                                       ' стоим на месте
Fr = 0 : Br = 0 : Bl = 0 : Fl = 0 :
Return
Вперёд:                                                     ' едим вперёд
Fr = 1 : Br = 0 : Bl = 0 : Fl = 1 :
Return
Вперёд_вправо:                                              ' поварачиваем вправо
Fr = 0 : Br = 0 : Bl = 0 : Fl = 1 :
Return
Вперёд_влево:                                               ' поворачиваем влево
Fr = 1 : Br = 0 : Bl = 0 : Fl = 0 :
Return
Назад:                                                      ' назад
Fr = 0 : Br = 1 : Bl = 1 : Fl = 0 :
Return
Назад_вправо:                                               ' поворачиваем назад-вправо
Fr = 0 : Br = 1 : Bl = 0 : Fl = 0 :
Return
Назад_влево:                                                ' поворачиваем назад-влево
Fr = 0 : Br = 0 : Bl = 1 : Fl = 0 :
Return
Вправо:                                                     ' разворот на метсе вправо
Fr = 0 : Br = 1 : Bl = 0 : Fl = 1 :
Return
Влево:                                                      ' разворот на месте влево
Fr = 1 : Br = 0 : Bl = 1 : Fl = 0 :
Return


Но направление не меняется. То есть нажимаю старт и моторы начинают крутиться вперёд, если нажать ещё раз старт, то направление движения меняется и т. д. При нажатие кнопки стоп работа останавливается.
Кто-нибудь знает как обойти этот момент, чтоб нормально направление менялось после нажатия старта?

Re: Прога мобильного робота на бейсике

Кирилл » 13 авг 2008, 23:10

можешь еще раз четко и конкретно сформулировать что не получается?

Re: Прога мобильного робота на бейсике

space » 13 авг 2008, 23:23

Конкретно не работает смена направления(а конкретней подпрограмма(Выбор_направления:) вылужу кусочек ниже). Без кнопок всё работало замечательно.
Код: Выделить всёРазвернуть
Dim Rand As Byte
Do                                                          'Основной цикл программы

Основная_программа:

If Кнопка_старт = 0 Then : Gosub Выбор_направления : End If
If Кнопка_стоп = 0 Then : Gosub Ожидание : End If

Loop
End

Выбор_направления:
Rand = Rnd(50)

If Rand = 48 Then : Gosub Стоп : Waitus 10 : End If
If Rand = 1 Then : Gosub Стоп : Waitus 10 : End If
If Rand = 49 Then : Gosub Вперёд : Wait 2 : End If
If Rand = 17 Then : Gosub Вперёд : Wait 1 : End If
If Rand = 27 Then : Gosub Вперёд : Wait 2 : End If
If Rand = 32 Then : Gosub Вперёд : Wait 1 : End If
If Rand = 44 Then : Gosub Назад : Wait 1 : End If
If Rand = 4 Then : Gosub Назад : Wait 1 : End If
If Rand = 45 Then : Gosub Вправо : Wait 1 : End If
If Rand = 2 Then : Gosub Вправо : Wait 1 : End If
If Rand = 22 Then : Gosub Влево : Wait 1 : End If
If Rand = 3 Then : Gosub Влево : Wait 1 : End If

Goto Основная_программа

Если я нажимаю старт, то начинает работать под программа выбора направления. Но работает не так, если без кнопок направления движения меняется само(вправо едит 1 секунду, назад 1 или вперёд 1), то с кнопками оно не меняется. Как я уже писал, моторы при нажатии старта начинают крутиться вперёд постнояно, а должны примерно так(вперёд 1с., назад 0,5с., вправо 1с. и т. д.). Если допустим нажать ещё раз старт, то направление движение меняется, нажму ещё раз оно опять меняется, а должно меняться само.
И вот я не пойму в чём здесь причина. Надеюсь теперь понятно.

Re: Прога мобильного робота на бейсике

Vooon » 13 авг 2008, 23:54

Страшное спагетти.

Re: Прога мобильного робота на бейсике

Кирилл » 14 авг 2008, 01:19

при использовании gosub нада не забывать про return!
Код: Выделить всёРазвернуть
Gosub Routine
Print "Back from Routine"

Routine:                                                    'start a subroutine
Print "This will be executed"
Return

Re: Прога мобильного робота на бейсике

space » 14 авг 2008, 16:35

А я и не забываю. Вместо return у меня стоит "Goto Основная_программа". В принципе попробую заменить на return мож поможет

Re: Прога мобильного робота на бейсике

blindman » 14 авг 2008, 17:10

Это на ассемблере такие вещи можно делать, да и то если хорошо знаешь что делаешь. И если уж пишешь программу, забудь про "мож поможет". Пиши правильно. Подпрограмма должна завершаться оператором возврата. Всегда.

Re: Прога мобильного робота на бейсике

Duhas » 14 авг 2008, 17:20

пиши ret\reti, оно тебе поможет !!!! :good: :crazy:

Re: Прога мобильного робота на бейсике

space » 14 авг 2008, 18:29

:Yahoo!: :Yahoo!: :Yahoo!:
Я сделал это. Поздравьте меня :Yahoo!:
Пускай прога выглядит громостка и коряво, но она мною написана и отлично работает. :crazy: :Yahoo!:
Код: Выделить всёРазвернуть
$regfile = "m16def.dat"                                     'используем мк ATmega16
$crystal = 16000000                                         'частота кварцевого резонатора 16mHz
$lib "lcd4.lbx"                                             'используем 4-х битное подключение дисплея с помощью альтернативной библиотеки
$baud = 19200                                               'Скорость COM-порта
' указываем конфигурацию подключения дисплея к портам МК
Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.2 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 16 * 2                                         'используем дисплей на 2 строчки по 16 знакомест в каждой

Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Config Pina.0 = Output : Fr Alias Porta.0                   'PA 0 устанавливаем на выход и присваиваем имя Fr(вперёд-вправо);
Config Pina.1 = Output : Br Alias Porta.1                   'PA 1 устанавливаем на выход и присваиваем имя Br(назад-вправо);
Config Pina.2 = Output : Bl Alias Porta.2                   'PA 2 устанавливаем на выход и присваиваем имя Bl(назад-влево);
Config Pina.3 = Output : Fl Alias Porta.3                   'PA 3 устанавливаем на выход и присваиваем имя Fl(вперёд-влево).

Config Pind.2 = Input : Bumper_r Alias Pind.2               'PD 0 устанавливаем на вход и присваиваем имя Bumper_r(правый бампер);
Config Pind.3 = Input : Bumper_l Alias Pind.3               'PD 1 устанавливаем на вход и присваиваем имя Bumper_l(левый бампер).

Config Pinc.2 = Input : Кнопка_старт Alias Pinc.2           'PC 2 устанавливаем на вход и присваиваем имя Кнопка_старт;
Config Pinc.3 = Input : Кнопка_стоп Alias Pinc.3            'PC 3 устанавливаем на вход и присваиваем имя Кнопка_стоп;
Config Pinc.4 = Input : Кнопка_3 Alias Pinc.4               'PC 4 устанавливаем на вход и присваиваем имя Кнопка_3;
Config Pinc.5 = Input : Кнопка_4 Alias Pinc.5               'PC 5 устанавливаем на вход и присваиваем имя Кнопка_4.

Config Pinb.0 = Output : Red_0 Alias Portb.0                'PB 0 устанавливаем на выход и присваиваем имя Red_0;
Config Pinb.1 = Output : Red_1 Alias Portb.1                'PB 1 устанавливаем на выход и присваиваем имя Red_1;
Config Pinb.2 = Output : Red_2 Alias Portb.2                'PB 2 устанавливаем на выход и присваиваем имя Red_2.

Enable Interrupts                                           ' разрешаем прерывания

Dim Rand As Byte

Print "Start RoBi"                                          ' выводим стартовую надпись в терминали через COM-порт

Cls                                                         'команда очистки дисплея
Cursor Off                                                  ' отключаем корсор на LCD
Lcd "I am RoBi!"                                            'выводим надпись
Lowerline                                                   ' переходим на нижнюю строчку
Lcd "Gotov k rabote."                                       'выводим надпись

Do                                                          'Основной цикл программы
Основная_программа:
If Кнопка_старт = 0 Then : Gosub Выбор_направления : End If
Loop
End

Do
Выбор_направления:
Rand = Rnd(50)
If Rand = 48 Then : Gosub Стоп : Waitus 10 : End If
If Rand = 1 Then : Gosub Стоп : Waitus 10 : End If
If Rand = 49 Then : Gosub Вперёд : Wait 2 : End If
If Rand = 17 Then : Gosub Вперёд : Wait 1 : End If
If Rand = 27 Then : Gosub Вперёд : Wait 2 : End If
If Rand = 32 Then : Gosub Вперёд : Wait 1 : End If
If Rand = 44 Then : Gosub Назад : Wait 1 : End If
If Rand = 4 Then : Gosub Назад : Wait 1 : End If
If Rand = 45 Then : Gosub Вправо : Wait 1 : End If
If Rand = 2 Then : Gosub Вправо : Wait 1 : End If
If Rand = 22 Then : Gosub Влево : Wait 1 : End If
If Rand = 3 Then : Gosub Влево : Wait 1 : End If
If Кнопка_стоп = 0 Then : Gosub Останавливаемся : End If

Debounce Bumper_r , 0 , L                                   'сработал правый датчик, переходим на выполнение команды Bl
Debounce Bumper_l , 0 , R                                   'сработал левый датчик, переходим на выполнение команды Br
Loop

Останавливаемся:                                            ' стоим на месте
Fr = 0 : Br = 0 : Bl = 0 : Fl = 0 :
Goto Основная_программа

'' -----------------------------------------------------------------------------
'' Включение комбинации моторов для движения в заданном направлении
'' -----------------------------------------------------------------------------

Стоп:                                                       ' стоим на месте
Fr = 0 : Br = 0 : Bl = 0 : Fl = 0 :
Return
Вперёд:                                                     ' едим вперёд
Fr = 1 : Br = 0 : Bl = 0 : Fl = 1 :
Return
Вперёд_вправо:                                              ' поварачиваем вправо
Fr = 0 : Br = 0 : Bl = 0 : Fl = 1 :
Return
Вперёд_влево:                                               ' поворачиваем влево
Fr = 1 : Br = 0 : Bl = 0 : Fl = 0 :
Return
Назад:                                                      ' назад
Fr = 0 : Br = 1 : Bl = 1 : Fl = 0 :
Return
Назад_вправо:                                               ' поворачиваем назад-вправо
Fr = 0 : Br = 1 : Bl = 0 : Fl = 0 :
Return
Назад_влево:                                                ' поворачиваем назад-влево
Fr = 0 : Br = 0 : Bl = 1 : Fl = 0 :
Return
Вправо:                                                     ' разворот на метсе вправо
Fr = 0 : Br = 1 : Bl = 0 : Fl = 1 :
Return
Влево:                                                      ' разворот на месте влево
Fr = 1 : Br = 0 : Bl = 1 : Fl = 0 :
Return

R:                                                          ' выполнять после срабатывания правого датчика
Gosub Назад                                                 ' переходим в подпрограмму "Назад"
Wait 1                                                      ' выполняем её в течение 2,5 секунд
Gosub Назад_влево
Wait 1
Gosub Стоп
Goto Выбор_направления                                      ' переходим к началу основного цикла после выполнения команд

L:
Gosub Назад
Wait 1
Gosub Назад_вправо
Wait 1
Gosub Стоп
Goto Выбор_направления

Re: Прога мобильного робота на бейсике

Кирилл » 14 авг 2008, 18:48

ты пробовал ретурн добавлять в том варианте проги?
у тебя кстати один цикл абсолютно лишний есть.

Re: Прога мобильного робота на бейсике

space » 14 авг 2008, 20:54

Кирилл писал(а):ты пробовал ретурн добавлять в том варианте проги?
у тебя кстати один цикл абсолютно лишний есть.

1. Конечно пробовал. Не помогло.
2. Ты вероятно про этот цикл:
Код: Выделить всёРазвернуть
Do                                                          'Основной цикл программы
Основная_программа:
If Кнопка_старт = 0 Then : Gosub Выбор_направления : End If
Loop

Если да, то я его потом уберу

Re: Прога мобильного робота на бейсике

Кирилл » 14 авг 2008, 22:55

не я про этот:
Код: Выделить всёРазвернуть
Do
Выбор_направления:
Rand = Rnd(50)
If Rand = 48 Then : Gosub Стоп : Waitus 10 : End If
...
Debounce Bumper_l , 0 , R                                   'сработал левый датчик, переходим на выполнение команды Br
Loop

на строчку Do программа никогда не попадает.


Rambler\'s Top100 Mail.ru counter