Skocz do zawartości
piwniczne

[czujnik koloru, follower] Sprawdzenie układu, dodanie zmiany predkosci

Pomocna odpowiedź

Hej,

to mój pierwszy post więc witam was serdecznie.

Tworze (właściwie, to próbuję) robota, którego zadaniem będzie rozpoznawanie koloru linii która jest pod nim i zmiana prędkości w zależności od wykrytego koloru. Linia póki co ma być prosta.

Jako rdzeń użyłem schematu z tutka: https://www.forbot.pl/forum/topics20/dla-poczatkujacych-przepis-na-robota-w-pelni-programowalny-line-follower-vt2356.htm

zmieniłem go nieco, dodałem czujnik który sam potrzebuje użyć. ( TSC3200 )

Jako napędu planuje użyć: http://electropark.pl/napedy-tamiya/563-przekladnia-podwojna-tamiya-70168-5901000563005.html ponieważ już go posiadam.

Pytanie do was, to prośba o wskazanie błędów oraz zbędnych elementów.

Oprócz tego, chciałbym was prosić o doradzenie,

w jaki sposób regulować jego prędkość?

Na tę chwilę myślę o zamieszczeniu PWM przed mostkiem, w celu zmian napięcia w zależności od zadanej wart przez mikroprocesor.

SCHEMAT:

Udostępnij ten post


Link to post
Share on other sites

Nie będę tu powtarzał uwag o używaniu 7805 przy 7V na wejściu, o zmarnowanym UART itd. Chciałem tym razem skupić się na idei i czujniku, bo to nowość 🙂

1. Czy wiesz jak ten czujnik działa? Napisz proszę kilka zdań o nim (funkcje wejść Sn, /OE oraz rodzaj sygnału wyjściowego) i to jak wyobrażasz sobie jego współpracę z procesorem. Co będzie robił program itp.

2. Jak robot będzie znajdował linię? Czy nie jest potrzebny jeszcze co najmniej jeden taki czujnik (lub 2?) lub kilka czarno-białych do kontroli kierunku? Wiem, że (na razie) linia będzie prosta ale utrzymanie prostego kierunku jazdy robota z dwoma sinikami jest praktycznie niemożliwe bez jakiegoś naprowadzania. Jak to chcesz osiągnąć?

Udostępnij ten post


Link to post
Share on other sites

Kondensator C3 zapewne ma filtrować zasilanie podłączone do pinu Vcc mikrokontrolera.

Reset mikrokontrolera następuje, gdy na pin RESET podłączy się logiczne 0. Dlatego podczas normalnej pracy podłącza się go do Vcc (logiczne 1 = brak resetowania), ale gdyby nie było rezystora (powinien mieć ok. 10k) to podczas resetu (np. podczas programowania) następuje zwarcie Vcc do GND i mamy śmierdzący dymek.

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites
1. Czy wiesz jak ten czujnik działa? Napisz proszę kilka zdań o nim (funkcje wejść Sn, /OE oraz rodzaj sygnału wyjściowego) i to jak wyobrażasz sobie jego współpracę z procesorem. Co będzie robił program itp.

Z tego co czytałem w dokumentacji technicznej, czujnik daje na wyjściu sygnał prostokątny którego częstotliwość jest zależna od natężenia barwy którą szczytuje.

Za pomocą S0, S1 regulujemy skalowanie funkcji wyjściowej (2% 20% 100%)

za pomocą S2, S3 ustalamy którą z barw chcemy zbierać ( R, B, G, Clear)

Program będzie zbierał przebiegi i porównywał je z oczekiwanymi (na starcie 3 R, G, B),

Dla trzech kolorów z początku wystarczy, żeby zebrał dane z 3 barw i wybrał tę która ma największą wartość. W późniejszych etapach można to rozbudować do większej palety kolorów oraz dopuszczalnych błędów.

Póki co tak to widzę, kwestia regulowania prędkości.

Myślę o zastosowaniu przed mostkiem PWM, jednak nie robiłem tego nigdy i nie bardzo wiem, czy da się nim sterować cyfrowo - zaraz to będę ogarniał. Gdyby była taka możliwość to byłoby najlepiej, ponieważ na starcie wystarczą 2 piny które daja 4 stany -> 3 dla kolorów i 1 na postój.

2. Jak robot będzie znajdował linię? Czy nie jest potrzebny jeszcze co najmniej jeden taki czujnik (lub 2?) lub kilka czarno-białych do kontroli kierunku? Wiem, że (na razie) linia będzie prosta ale utrzymanie prostego kierunku jazdy robota z dwoma sinikami jest praktycznie niemożliwe bez jakiegoś naprowadzania. Jak to chcesz osiągnąć?

Znajdywanie linii póki co nie jest w jego zakresie- z założenia linia miała być bardzo szeroka, nie brałem pod uwagę tego by korygował swój ruch. Kwestia rozbija się o to, w jakim czasie zgubi linie, ponieważ zależy mi na tym, by podążał za nią powiedzmy póki co przez metr.

Jeżeli chodzi o rozwój w tym kierunku to widze to w postaci czujników odbiciowych, tyle, że wtedy podłoże musiałoby mieć ( z tego co rozumiem ) jednolity kolor odległy od tych które wykrywa robot. (by wykrywały, że któryś z nich najeżdża na linie.)

Udostępnij ten post


Link to post
Share on other sites

"..czujnik daje na wyjściu sygnał prostokątny którego częstotliwość jest zależna od natężenia barwy.."

OK, to teraz powiedz jak chcesz tę częstotliwość/okres mierzyć. Jeżeli wybierzesz pomiar częstotliwości, to program będzie musiał zaliczać setki jeśli nie tysiące zdarzeń na sekundę. Jak się domyślasz nie będzie mógł w tym czasie robić niczego innego. Jeżeli zdecydujesz się na pomiar okresu, to będziesz musiał programowo liczyć czas między zdarzeniami co również zablokuje procesor na kawał czasu. Jestem pewien, że to wiesz, więc moje pytanie jest proste: dlaczego nie wykorzystujesz żadnych możliwości sprzętu za który płacisz? Procesory AVR, nawet ta prosta mega8 ma kilka bloków ułatwiających pomiary okresu/częstotliwości. Timery - bo o nich mowa - mają wyprowadzone wejścia i wyjścia na konkretne piny. Już teraz musisz podjąć decyzje które z nich i w jaki sposób wykorzystasz, jak zrobiłeś to z PWM do mostka. Poczytaj o nich i zdecyduj. Ciekaw jetem Twoich wniosków. Jeśli zrobisz to bez głowy, Twój szybki procesor będzie totalnie zamulony ciągłym robieniem rzeczy podstawowych nie mając czasu na coś ciekawszego.

Mam też nadzieję, że uwagę o UART weźmiesz sobie do serca i przełożysz sygnały które mogą być podłączone do czegokolwiek uwalniając ten cenny zasób na ciekawsze funkcje. Pomyśl - gdy już będzie Ci się wydawało, że napisałeś kawałek kodu mierzący okres/częstotliwość - jak zweryfikujesz pomiary? Jak dowiesz się jakie wielkości są mierzone, czy kalibracja początkowa jest prawidłowa itd? Jakie są liczbowe wartości pomiarów, decyzje podejmowane w bloku sterowania napędami, jakie wysterowania PWM?

Przemyśl też sprawę oświetlenia podłoża. Co to będzie i jak wielki będzie wpływ oświetlenia rozproszonego na barwę. To samo z wpływem samego oświetlacza. Twój czujnik jest odbiciowy - musisz jakoś oświetlać teren.

Myślę, że sam pomiar koloru jakiegoś podłoża możesz zrobić i bez robota. Jeżeli ma to być szerokie pole, to w końcu je zmierzysz i co dalej? Planuj takie konstrukcje na trochę dalej niż jeden eksperyment. Za chwilę okaże się, że jednak masz jeździć po linii (i ją śledzić) bo samo mierzenie szybko się znudzi. Dwa-trzy czujniki koloru będą w stanie odróżnić jej kolor i położenie na tle innego (białego?) podłoża więc idąc za ciosem wstawiłbym trzy czujniki pracujące na jedno wejście procesora i skorzystał z ich wejścia /EN otwierając do pomiaru za każdym razem tylko jeden.

W każdym razie pomysł mi się podoba.

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

marek1707, na wstępie wielkie dzięki za odpowiedź!

To pierwszy projekt jaki robię, nie wiem dlaczego zakładasz, że to wszystko wiem (chyba, ze prowokujesz mnie do szukania, to dobrze Ci to wychodzi 😃 ). Nie, nie wiem większości z tych rzeczy.

Dobra z tego co ogarniam PC5 (ADC5/SCL) PC4 (ADC4/SDA) zmienię, żeby zostawić miejsce choćby na I2C, które może się przydać do późniejszego rozbudowywania urządzenia. Podobnie piny do UART czyli (RXD) PD0 (TXD) PD1.

obecnie: Muszę ogarnąć jak wykorzystać timery do mierzenia wartości z czujnika.

Jeżeli miałeś coś konkretnego na myśli, fajnie jakbyś powiedział jak to zrobić, albo dał jakiś poradnik/tut 😉

Udostępnij ten post


Link to post
Share on other sites

Niestety nie znam żadnych poradników, choć stron o AVR jest mnóstwo. Na pewno ktoś już popełnił artykuł o wykorzystaniu timerów.

Jeżeli choć pobieżnie przejrzałeś dane katalogowe różnych "atmeg" to już się pewnie zorientowałeś, że w zakresie wejść nie ma wielkiego wyboru. Właściwie masz dwie możliwości:

1. Timer z wejściem zegarowym (np. T0 czy T1)

2. Timer z wejściem zatrzaskującym stan (np. IC1, IC3).

Pierwsza opcja będzie z definicji polegać na pomiarze częstotliwości:

1a. Zerujesz timer, ustawiasz go na zliczanie impulsów z zewnętrznego wejścia T robiąc z niego zwykły licznik.

1b. Odmierzasz stały czas np. za pomocą innego timera żeby mieć szansę robienia czegoś innego. Czas powinien być tak dobrany aby licznik na pewno się nie przepełnił a jednocześnie by miał szansę zliczyć ich odpowiednio dużo zapewniając sensowną rozdzielczość pomiaru.

1c. Po upłynięciu czasu (przerwanie?) blokujesz pracę licznika przez wyłączenie mu zegara i odczytujesz wynik.

1d. Teraz możesz np. przełączyć kolor przez modyfikację sygnałów Sn czujnika lub nawet zmienić czujnik poprzez manipulację sygnałami /OE kilku czujników podłączonych do tego samego wejścia T timera/licznika.

Druga jest dużo fajniejsza, ale takich timerów jest mało (1 i 3) i chyba dopiero ATmega128 ma ten drugi (czyli 3 🙂 ). Z tego powodu, gdybyś chciał wykorzystać tę metodę warto użyć procesora mającego więcej wyjść PWM z innych timerów. Np. bardzo podobna ATmega88 ma już wyjścia PWM z każdego timera i to do któregoś z nich możesz podłączyć mostek, uwalniając timer 1 do pomiaru za pomocą wejścia IC1.

Metoda wygląda mniej więcej tak:

2a. Ustawiasz timer 1 na pracę z odpowiednio wysokim zegarem tak, by w czasie jednego okresu mierzonego przebiegu był w stanie zliczyć odpowiednio dużo "tyknięć". Puszczasz go by pracował kółko w najprostszym trybie (0000) i zapominasz o nim.

2b. Programujesz wejście IC1 na złapanie np. narastającego zbocza i czekasz na przerwanie od tego zdarzenia (robiąc w tym czasie coś ciekawego).

2c. Po przyjściu przerwania odczytujesz rejestr ICR1A i zapamiętujesz tę wartość w jakiejś zmiennej statycznej.

2d. Czekasz na kolejne takie samo zdarzenie/przerwanie.

2e. Po przyjściu przerwania znów odczytujesz rejestr ICR1A i liczysz różnicę między wartością zapamiętaną a te obecną. To jest długość okresu mierzonego przebiegu wyrażona w długościach okresu zegara timera 1. Nie ma znaczenia jakie te wartości były a timer 1 mógł się w tym czasie przekręcić przez 0 - wynik odejmowania i tak będzie OK.

Oczywiście w powyższych opisach jest kilka miejsc krytycznych, gdzie trzeba przemyśleć sprawę np. już wiszących bo zgłoszonych wcześniej przerwań (trzeba je kasować) itp, ale ogólnie obie wydają się proste. Niestety ATmegi - o ile pamiętam - w odróżnieniu od rodziny Xmega czy procesorów STM32 nie mają naprawdę dobrze zrobionych wejść do timerów automatycznie mierzących okres czy np. wypełnienie. Szkoda, trzeba lubić co się ma.

W swoim układzie możesz wykorzystać obie metody właśnie dzięki temu, że czujnik ma przełączane podzielniki wyjściowe. W trybie z małym podziałem dostajesz dużą częstotliwość wyjściową i możesz ją mierzyć metodą 1, a w trybie z dużym podzielnikiem dostajesz wolne przebiegi którym łatwiej mierzyć okres.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Dzięki wielkie za opis.

Przechodzę do napisania założeń projektowych,

jeżeli interesuje Cię projekt to mogę napisać w późniejszym czasie o postępach/problemach 😉 !

Udostępnij ten post


Link to post
Share on other sites

Założenia to najweselsza część projektu, bo można puszczać wodze fantazji, robić w głowie niesamowite urządzenia których funkcje będą daleko wykraczały poza rzeczywiste potrzeby, planować oprogramowanie którego nikt nie będzie w stanie napisać a to wciąż nic nie kosztuje.

Oczywiście, wrzucaj wszystko co Ci przyjdzie na myśl. My i tak wszystko bezlitośnie skrytykujemy, przeżujemy i skierujemy w jedynie słusznym kierunku 😉

EDIT: Darmowa porada: nie skupiaj się na tym czego obecnie nie wiesz, w szczególności na małych problemach. Jeżeli nie wymyślisz czegoś zupełnie głupiego, to najprawdopodobniej to się da zrobić. Potrzebujesz pomiaru jakiejś wielkości? - załóż, że to się da zrobić. Musisz zrobić nietypowy układ wczytywania kodów paskowych z podłogi lub ze ściany? OK, to też. W trakcie trwania projektu bardzo dużo i szybko się uczysz. To co dziś wydaje się rocket science, jutro może działać u Ciebie na biurku.

Udostępnij ten post


Link to post
Share on other sites

Mam problem, pewnie dla was banalny, a dla mnie dziwny.

Robiłem PWM i działa normalnie, tyle, ze gdy daje proponowane ustawienia:

    TCCR1A |= (1 << WGM10);                      // Fast PWM 8bit
 	TCCR1B |= (1 << WGM12);
 	TCCR1A |= (1 << COM1A1) | (1 << COM1B1);        //Clear OC1A/OC1B on Compare Match, set OC1A/OC1B at BOTTOM
 	TCCR1B |= (1 << CS10) | (1 << CS11);             // Preksaler = 64  fpwm = 976,5Hz

 	//sterowanie prędkością silników
 	OCR1A = 0xff;         //kanał A = 0
 	OCR1B = 0x00;         //kanał B = 0

ktore pochodza z jednego z waszych tutków.

Sam natomiast chciałem rejestry wyznaczyć w ten sposób:

	TCCR1A = 0b10100000;
CCR1B = 0b00000011;

I nie wiem dlaczego przy pierwszej metodzie działa, przy drugiej nie.

Cały czas myślałem, że wystarczy, że dam gdzieś 0 i 1nki.

Natomiast zapisu |= szczerze mówiąc nie kumam 😋

Udostępnij ten post


Link to post
Share on other sites

Operator |= (podobnie jak +=, &=, %= czy ^= i jeszcze kilka innych) wykonuje trzy czynności:

1. Policz wartość wyrażenia po prawej stronie,
2. Wykonaj dwuargumentową operację wskazaną przez operator (czyli np logiczne OR w przypadku |=) na zmiennej stojącej po lewej stronie i na wartości policzonego przed chwilą wyrażenia,
3. Podstaw wynik pkt.2 do zmiennej po lewej stronie.

To znaczy, że |= dostawia jedynki do wskazanego rejestru bez kasowania poprzednio tam się znajdujących. To wygodne, jeśli chcesz pokazać w kodzie, że ustawiasz np. jeden bit a innych nie ruszasz. Sekwencja:

TCCR1A |= (1 << WGM10);
TCCR1A |= (1 << COM1A1) | (1 << COM1B1);

jest więc równoważna:

TCCR1A |= (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1);

a to - zakładając, że na początku rejestr był wyzerowany - jest równoważne temu:

TCCR1A = 0b10100001;

Twój kod robi co innego bo zapominasz, że wcześniej zostały ustawione bity WGM.

  • Pomogłeś! 1

Udostępnij ten post


Link to post
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ę »

×