Skocz do zawartości

[Bascom] Obsługa ADC z użyciem megi16 i CNY70


MaRo88PL

Pomocna odpowiedź

Witam.

Piszę program dla swojego LF'a i utknąłem na pewnym problemie.

Mam transoptory CNY70 podpięte do ADC Atmegi16 bez żadnego wzmacniacza. Oczywiście mam podciągnięte je przez rezystory.

Układ teoretycznie działa poprawnie - przy zmianie koloru podłoża zmienia się napięcie przy wejściu na ADC w zakresie 1,5 - 3,5 V.

Nie mogę jednak za cholerę ustawić odpowiedniej granicy reagowania na zmianę koloru.

Próbowałem ustawić to przy pomocy dodatkowej diody włączonej w jedno z wyjść uC, która miała gasnąć, gdy pod transoptorem pojawi się czarna linia. Zmieniałem wartości granicy, aż w pewnym momencie doszedłem do chwili gdy przy wartości X dioda świeci niezależnie od tego czy pod czujnikiem jest białe pole czy czarna linia, a przy wartości X+1 zawsze jest zgaszona (niezależnie od tego czy pod czujnikiem jest białe czy czarne).

Mój kod wygląda następująco:

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

'Konfiguracja przetwornika analog-cyfra (ADC)
Config Adc = Single , Prescaler = Auto

'Konfiguracja portu z dioda
Config Portb = Output

'Granica reagowania na linię - dobrać doświadczalnie
Const Granica = 1000

'Deklaracje zmiennych
Dim Czujnik_lewy As Single
Dim Czujnik_srodkowy As Single
Dim Czujnik_prawy As Single
Dim Czujnik_skrajny_lewy As Single
Dim Czujnik_skrajny_prawy As Single
Dim W As Word

Do
     Gosub Wczytaj_stany_przetwornikow
  If Czujnik_srodkowy > Granica Then                       
     Reset Dioda
  Elseif Czujnik_lewy > Granica Then                      
     Reset Dioda
  Elseif Czujnik_prawy > Granica Then                      
     Reset Dioda
  Elseif Czujnik_skrajny_lewy > Granica Then               
     Reset Dioda
  Elseif Czujnik_skrajny_prawy > Granica Then                      
     Reset Dioda
  Else
     Set Dioda
  End If
Loop
End

Wczytaj_stany_przetwornikow:
Start Adc
W = Getadc(4)
W = Getadc(4)
Stop Adc
Czujnik_skrajny_lewy = W
Start Adc
W = Getadc(2)
W = Getadc(2)
Stop Adc
Czujnik_lewy = W
Start Adc
W = Getadc(0)
W = Getadc(0)
Stop Adc
Czujnik_srodkowy = W
Start Adc
W = Getadc(1)
W = Getadc(1)
Stop Adc
Czujnik_prawy = W
Start Adc
W = Getadc(3)
W = Getadc(3)
Stop Adc
Czujnik_skrajny_prawy = W
Return

Może ktoś pomóc w tej kwestii ponieważ za cholerę nie wiem co może być źle.

Link do komentarza
Share on other sites

Dim W As Word

Zdecydowanie wystarczy As Byte, masz w tedy w zakresie 0 - 255 wartość wynikową.

Config Adc = Single , Prescaler = Auto , Reference = Avcc

Przykład z mojego programu gdzie poskramiałem ADC, brakuje Ci odniesienia do REFERENCE, niby wartość opcjonalna do ustawienia, ale ... bez tego miałem też problemy z wynikami i odczytywaniem wartości.

  • Lubię! 1
Link do komentarza
Share on other sites

Wywal start adc i stop adc, albo spróbuj dac opóżnienia:

Wczytaj_stany_przetwornikow:

Start Adc

Delay

W = Getadc(4)
W = Getadc(4)

Stop Adc

Delay

Czujnik_skrajny_lewy = W

... 
Link do komentarza
Share on other sites

Dim W As Word

Zdecydowanie wystarczy As Byte, masz w tedy w zakresie 0 - 255 wartość wynikową.

Config Adc = Single , Prescaler = Auto , Reference = Avcc

Przykład z mojego programu gdzie poskramiałem ADC, brakuje Ci odniesienia do REFERENCE, niby wartość opcjonalna do ustawienia, ale ... bez tego miałem też problemy z wynikami i odczytywaniem wartości.

Częściowo pomogło ale wyłapuje tylko brzegi linii. Gdy linia jest centralnie pod czujnikiem zachowuje się tak jak by jej tam nie było. Ale myślę, że jest to już tylko kwestia odpowiedniego doboru wartości.

Później sprawdzę jeszcze sugestię KD93

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dim W As Word

Zdecydowanie wystarczy As Byte, masz w tedy w zakresie 0 - 255 wartość wynikową.

Nie wiesz - nie pisz. Jeśli tak zrobisz, otrzymasz wartość od 0 do 255, a reszta będzie ucięta. Trzeba odczytywać ADC do worda bo otrzymuje się wartość z przedziału 0 - 1023.

Zdefiniuj wszystkie wartości dotyczące ADC jako word i granicę ustal na np. 300, wywal te start i stop adc, daj tylko jedno start adc na początku i powinno być dobrze.

Edit: spróbuj tak:

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

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

'Konfiguracja portu z dioda
Config Portb = Output

'Granica reagowania na linię - dobrać doświadczalnie
Const Granica = 300

'Deklaracje zmiennych
Dim Czujnik_lewy As Word
Dim Czujnik_srodkowy As Word
Dim Czujnik_prawy As Word
Dim Czujnik_skrajny_lewy As Word
Dim Czujnik_skrajny_prawy As Word

Start Adc

Do
Czujnik_skrajny_lewy = Getadc(4)
Czujnik_lewy = Getadc(2)
Czujnik_srodkowy = Getadc(0)
Czujnik_prawy = Getadc(1)
Czujnik_skrajny_prawy = Getadc(3)

  If Czujnik_srodkowy > Granica Then                       
     Reset Dioda
  Elseif Czujnik_lewy > Granica Then                     
     Reset Dioda
  Elseif Czujnik_prawy > Granica Then                     
     Reset Dioda
  Elseif Czujnik_skrajny_lewy > Granica Then               
     Reset Dioda
  Elseif Czujnik_skrajny_prawy > Granica Then                     
     Reset Dioda
  Else
     Set Dioda
  End If
Loop
End

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Przy użyciu takiego kodu jak zaproponowałeś działa już niemal perfekcyjnie, poza jedną kwestią. Zdarza się, że czujniki po zjechani z linii zawieszają się i pomimo iż robot przejedzie już całkowicie poza linię diody wszystkie (5 diod, po 1 na czujnik) są wygaszone tak jak by pod każdą była linia.

Dzięki wielkie za wszelką pomoc dla wszystkich.

Link do komentarza
Share on other sites

Nie wiesz - nie pisz.

Wiem, więc piszę ... testowałem na Byte i mi działało, a to że obcinało wartości, cóż trudno jakoś w niczym mi to nie przeszkadzało. Nikt nie jest doskonały i tak cudownie oświecony, dzięki .... super. Na przyszłość nie wiesz, to nie pisz głupot, sam się stosuj do swojej magicznej zasady 😃

Tak żeby nie było doczytałem przetwornik jest 10 bitowy, a nie 8 bitowy, stąd ta strata, co nie znaczy że na BYTE działać nie będzie, działa i to też całkiem dobrze, choć to zależy co chcesz osiągnąć!

Link do komentarza
Share on other sites

Działać będzie tylko jeśli próg jest poniżej 255. Inaczej nie ma prawa (zakres skończy się przed progiem). Niestety nie jest to takie cudowne, że od razu 'ściska' nam zmienną coby się zmieściła (liniowo) tylko ucina nadmiar (2 ostatnie bity).

Link do komentarza
Share on other sites

To, że Tobie działało nie znaczy, że tak jest poprawnie. Owszem - będzie działać, jednak i tak otrzymasz wartość od 0 do 1023, jednak w bajcie zmieści się tylko wartość z przedziału 0 - 255, a od 256 do 1023 nie będzie widoczne. Aby otrzymać wartość od 0 do 255 wystarczy podzielić zwróconą wartość ADC przez 4 😉

Wybacz, jeśli zachowałem się trochę niekulturalnie.

Link do komentarza
Share on other sites

Tak trochę offtop, ale zobaczyłem u siebie jedną ciekawą rzecz. Jak w medze8 nie napisałem START ADC to mi nie działało, a w medze16 zapomniałem napisać i działa 😃 Nie mam po prostu start ADC a i tak odczytuje wartości.

Link do komentarza
Share on other sites

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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.