Skocz do zawartości

ADC Atmega8 wall follower


Pomocna odpowiedź

Ja w Bascomie nie piszę, ale z tego co pamiętam co mi kolega mówił, to nie możesz w Bascomie przeprowadzać kilku operacji w jednej linijce w taki sposób

Zamiast tego

Pwm1a = 127 + Roznica * 0.8

Spróbuj tak:

Roznica = Roznica * 0.8
Pwm1a = 127 - Roznica
  • Pomogłeś! 1

Dzięki, gdzieś dawno temu czytałem, że w Bascom'ie nie można robić kilku rzeczy na raz, ale to było dawno i wystarczająco nie zapamiętałem :/

Tu obecny kod:

$regfile = "m8def.dat"
$crystal = 1000000

'Konfiguracja przetwornika analog-cyfra (ADC)
Config Adc = Single , Prescaler = 64 , Reference = Avcc

'Konfiguracja sterowania sprzętowym PWM
Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down

Config Portb = Output
Config Portd = Output
Dioda Alias Portd.7
Dioda2 Alias Portd.6

Silnik_lewy_a Alias Portb.4
Silnik_lewy_b Alias Portb.0
Silnik_prawy_a Alias Portb.5
Silnik_prawy_b Alias Portb.3

Const Granica = 200

Dim W As Word
Dim Czujnik_prawy As Word
Dim Roznica As Integer

Set Silnik_lewy_a
Reset Silnik_lewy_b
Set Silnik_prawy_a
Reset Silnik_prawy_b

Do

'założenie - ściana jest po prawej stronie robota
Roznica = Granica - Czujnik_prawy

Gosub Odczyt
'za daleko od  ściany
If Roznica > 0 Then
  Set Dioda
  Reset Dioda2

  Roznica = Roznica * 0.8

  Pwm1a = 127 + Roznica                                    'lewy silnik szybciej
  Pwm1b = 127 - Roznica                                    'prawy silnik wolniej
' za blisko ściany
Elseif Roznica < 0 Then
  Set Dioda2

  Roznica = Roznica * 0.8

  Reset Dioda
  Pwm1a = 127 - Roznica                                    'lewy silnik wolniej
  Pwm1b = 127 + Roznica                                    'prawy silnik szybciej

Else
'na granicy

  Pwm1a = 255                                              'lewy silnik na maksa
  Pwm1b = 255                                              'prawy silnik na maksa
End If

  If Roznica > 128 Then
  Roznica = 128
  Elseif Roznica < -128 Then
  Roznica = -128
End If

Loop
End


Odczyt:
Start Adc
W = Getadc(5)
W = Getadc(5)
Stop Adc
Czujnik_prawy = W
Return

Teraz mam takie pytanie, żeby do tego kodu dodać jeszcze jeden czujnik (np. środkowy - żeby robot reagował na ściankę przed sobą i (jeżeli jest to wall follower na prawą ścianę) skręcał na lewo od ścianki przed nim.

To naprawdę nie jest trudne. Spróbuj sobie wyobrazić, że jesteś robotem i zanotuj sobie jak byś musiał postępować w różnych sytuacjach (jedna ściana za blisko, dwie za blisko, za daleko itp.), najlepiej rozrysuj sobie algorytm i małymi kroczkami dojdziesz do tego, czego szukasz. Jeśli ciągle ktoś będzie Ci podpowiadać, to nie nauczysz się tego specyficznego, programistycznego myślenia, a bez tego niczego wartościowego tak naprawdę nie zaprogramujesz. Skoro nie gonią Cię terminy, szef nie wisi nad Tobą z biczem, to moim zdaniem jest to idealna chwila żeby właśnie teraz zrobić trochę błędów, wyciągnąć trochę wniosków i zdobyć mnóstwo doświadczenia.

Wiesz, na pewno nie jest to trudne, ale trzeba nabrać doświadczenia i jak Ty napisałeś nie nauczyłbym się programistycznego myślenia. Wezmę to pod uwagę i spróbuję sam coś wykombinować. Jak miałbym jakieś gigantyczne problemy to dopiero napiszę.

[ Dodano: 21-07-2013, 22:33 ]

Edit:

Tylko chciałem się zapytać, czy jak się napisze:

Pwm1a = -127
Pwm1b = -127

To silniki będą się kręciły wstecz? Czy trzeba jakoś inaczej?

Tak, to wiem, że jeżeli napiszę to tak:

Set Silnik_lewy_a
Reset Silnik_lewy_b
Set Silnik_prawy_a
Reset Silnik_prawy_b

To jedzie prosto. Jak napiszę to tak:

Set Silnik_lewy_a
Reset Silnik_lewy_b
Reset Silnik_prawy_a
Set Silnik_prawy_b

To będzie kręcił się w miejscu

W kodzie regulatora P nie używam tego: Set Silnik_lewy_a itp tylko PWM1A = 127 + Roznica ( i silnik kręci się w jedną stronę albo stoi)

[ Dodano: 22-07-2013, 20:48 ]

Próbowałem sobie to wszystko rozpisać, sprawdzałem różne kombinacje tego kodu i niestety za bardzo mi to nie wychodzi :/ W kodzie przyjąłem, że będę miał dwie różnice:

Roznica_prawa = Granica - Czujnik_prawy

To jest do czujnika prawego.

Roznica_srodkowa = Granica - Czujnik_srodkowy

A to do czujnika środkowego. Nie jestem pewien, czy robię to dobrze i czy to ma akurat tak wyglądać.

Wyobrażam sobie to tak:

*Jak robot ma tylko po prawej stronie ścianę to jedzie prosto z maksymalną szybkością, gdy jest na granicy. Jeżeli skręci w lewo - to zwalnia prawy silnik, a lewy przyśpiesza. Jak robot jedzie zbyt blisko ściany - to przyśpiesza prawy silnik, a lewy zwalnia. I jeżeli przed robotem nie ma ścianki to jedzie dalej równając do prawej, a jak robot dojeżdża do ścianki to lewy silnik staje, a prawy jedzie z maksymalną szybkością. Jak robot wyminie ściankę skręca w prawo, żeby równać do prawej ścianki.

Pierwszy raz mam z tym styczność, a w Internecie na moje pytania niestety nie znalazłem odpowiedzi.

Możesz skorzystać z zagnieżdżania instrukcji warunkowych, czyli w uproszczeniu:

if [nie ma przeszkody] then
    if [jest za blisko ściany] then
       instrukcje skręcania w jedną stronę
    elseif [jeśli za daleko od ściany] then
       instrukcje skręcania w drugą stronę
    else 'czyli jeśli jest w odpowiedniej odległości
       instrukcje jazdy prosto
    end if
else 'czyli jeśli jest przeszkoda
    instrukcje omijania przeszkody
end if

taki "if w ifie". To jest jeden sposób rozwiązania tego problemu. Czasami bardziej eleganckie jest stosowanie kilku warunków w jednym "if".

Np.

if warunek_1 AND warunek_2 then
   instrukcje czegośtam
else
   ....
end if

albo

if warunek_1 OR warunek_2 then
   instrukcje czegośtam
else
   ...
end if

Dla tych dwóch "przykładów": w pierwszym instrukcje czegośtam wykonają się tylko jeśli warunek_1 i warunek_2 są spełnione, np. roznica>100 i odleglosc>20. "AND" to takie polskie "ORAZ". W drugim przykładzie tylko jeden warunek musi zostać spełniony, czyli np. albo roznica>100, albo odleglosc>20, albo roznica>100 i odleglosc>20. "OR" to polskie "LUB".

Mam wrażenie, że trochę brakuje Ci podstaw w dziedzinie programowania, może pora zaopatrzyć się w jakąś lekturę? Nie musi być książka, w internecie jest mnóstwo tego typu artykułów. Możesz nawet poszukać kursu typowo pod BASCOM-AVR.

Zamiast wymyślać coraz bardziej skomplikowane algorytmy, spróbuj najpierw przetestować podstawowe. Czyli dojdź najpierw do tego, żeby robot w miarę płynnie trzymał się jednej ściany. Potem dodaj mu czujnik z przodu i spróbuj zaprogramować go tak, żeby przed przeszkodą po prostu stawał. Potem spróbuj zaprogramować go tak, żeby np. obracał się w lewo i próbował jechać wzdłuż przeszkody, aż dojdziesz do momentu, gdy robot "objeżdża" przeszkodę i wraca na trasę. Za dużo pomysłów naraz przy minimalnym doświadczeniu i nic dziwnego, że nie możesz sobie poradzić. Moja rada - małymi krokami dalej zajdziesz 🙂

  • Pomogłeś! 1
Mam wrażenie, że trochę brakuje Ci podstaw w dziedzinie programowania, może pora zaopatrzyć się w jakąś lekturę? Nie musi być książka, w internecie jest mnóstwo tego typu artykułów. Możesz nawet poszukać kursu typowo pod BASCOM-AVR.

Mam taką książkę: Programowanie mikrokontrolerów AVR w języku BASCOM Marcin Wiązania.

Niektóre rzeczy jakie napisałeś wiedziałem 🙂 Jeszcze zanim mi odpisałeś to jeszcze próbowałem coś z kodem zrobić i dopisałem nowego If'a i coś powoli wychodziło. Takie coś:

If Czujnik_srodkowy < 500 Then
Pwm1a = 0
Pwm1b = 0
Waitms 1500
Pwm1a = 0
Pwm1b = 255
End If

I jakoś omijał przeszkodę przed sobą.

Zamiast wymyślać coraz bardziej skomplikowane algorytmy, spróbuj najpierw przetestować podstawowe. Czyli dojdź najpierw do tego, żeby robot w miarę płynnie trzymał się jednej ściany. Potem dodaj mu czujnik z przodu i spróbuj zaprogramować go tak, żeby przed przeszkodą po prostu stawał. Potem spróbuj zaprogramować go tak, żeby np. obracał się w lewo i próbował jechać wzdłuż przeszkody, aż dojdziesz do momentu, gdy robot "objeżdża" przeszkodę i wraca na trasę. Za dużo pomysłów naraz przy minimalnym doświadczeniu i nic dziwnego, że nie możesz sobie poradzić. Moja rada - małymi krokami dalej zajdziesz 🙂

Na pewno sobie pokombinuję.

Czyli dojdź najpierw do tego, żeby robot w miarę płynnie trzymał się jednej ściany.

To jest opanowane.

Potem dodaj mu czujnik z przodu i spróbuj zaprogramować go tak, żeby przed przeszkodą po prostu stawał.

Testowałem taki sposób najpierw zanim napisałem ten kawałek kodu. (patrz początek postu)

Za dużo pomysłów naraz przy minimalnym doświadczeniu i nic dziwnego, że nie możesz sobie poradzić.

No pewnie tak. Moje doświadczenie na pewno jest już większe niż kiedyś 😃

Jak myślisz, jakie będzie lepsze ułożenie czujników? Ten linie czarne, czy żółte?

Edit:

Wgrałem Twój kod (z początku postu) i pozmieniałem po swojemu i robot omija przeszkody jeszcze lepiej niż na moim kodzie 😃

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...