Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 29 mar 2024, o 16:45


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 
Autor Wiadomość
PostNapisane: 22 maja 2017, o 21:04 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 cze 2013
Posty: 988
Lokalizacja: Byram, MS 39272
Pomógł: 55

Dzień Dobry wszystkim czytającym. Z braku czasu dawno nic nie robiłem na żadnym układzie. Czasem wszedłem na czata pogadać. Ot i tyle. Ale trafił w moje ręce czujnik TCS3200. Jest to o czujnik, który "zamienia" kolor jaki "widzi" na częstotliwość, którą możemy odczytać, a następnie przekształcić na RGB. Jako, że zostało mi postawione pewne zadania, a w ramach powolnego przerzucania się z C na C++ postanowiłem napisać program do obsługi tegoż urządzenia w oparciu o klasy.
Na początku garść informacji o samym czujniku. Czujnik posiada diody światłoczułe, macierz 4x4 z filtrem R, 4x4 z filtrem G, 4x4 z filtrem B oraz 4x4 całkowicie bez filtra. Poprzez piny możemy wybrać, z których diod odczytujemy wartość. Czujnik ma 8 wyprowadzeń, 2 od zasilania (GND, VCC) oraz 8 I/O (S0, S1,S2,S3,OE,OUT), które służą do sterowania czujnikiem.

Obrazek
czujnik TCS3200

Wejścia S0 do S3 służą do ustawienia filtra oraz częstotliwości, OE (Output Enabled - 0=aktywne) służy do włączania, wyłączania pomiaru koloru. Na OUT zaś możemy odczytać częstotliwość jaką zwraca nam czujnik po "odczytaniu" koloru.
W tabeli poniżej pokazane jest jak należy sterować urządzeniem.

Obrazek
Tabela ustawień czujnika TCS3200

Aby odczytać częstotliwość na pinie OUT możemy wykorzystać kilka podejść. Najprostszym dla mnie było użycie przerwania sprzętowego INT i zliczanie wystąpień przerwania w ustalonym czasie, dla każdego filtra z osobna. W tym celu przygotowałem sobie klasę, która obsługuje sprzętowy INT oraz wykorzystałem gotową klasę do obsługi UART. Poniżej przedstawiam pliki deklaracji klasy oraz główny program do odczytu kolorów. Oczywiście jest to tylko podstawa, którą można rozbudować wedle własnego uznania. Natomiast sposób przekazywania do USART można zrobić samemu lub skorzystać jak ja z gotowej klasy (niestety nie jest ona moja więc nie mogę jej udostępnić)
int.hpp
Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


int.cpp
Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


main.cpp

Składnia: [ Pobierz ] [ Ukryj ]
język cpp
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Jak działa program?
Otóż na początku trzeba stworzyć obiekty obsługujące przerwanie zewnętrzne INT0 oraz obiekt obsługujący UART. Zrobione jest to poprzez te dwie definicje:
Usart myUsart(0, 115200, &rxBuffer, &txBuffer);
class_INT0 Przerwanie(_RASING,INT_0);

W konstruktorze obiektu przerwania podajemy funkcję (a raczej jej adres) do obsługi przerwania, w tym przypadku jest to zwiększenie licznika, oraz przy jakiej zmianie na PINie przerwanie ma się pojawiać. Ja wybrałem sygnał wzrastający. Funkcja uint32_t ReadColour(uint8_t Colour) służy do odczytu ilości wystąpień przerwania w czasie 10ms. Następnie wartość ta składowana jest w zmiennej globalnej. Wiem, wiem, program główny jest lekko przerośnięty ale to dlatego, że robiłem testy, chcę jeszcze wprowadzić do niego funkcje przeliczającą odczytaną częstotliwość na RGB i stąd kompletny brak optymalizacji.

Jak odczytać kolor w postaci RGB?
Po pierwsze trzeba skalibrować czujnik. Czyli odczytujemy wartości częstotliwości dla kanałów RGB dla białego koloru i składujemy je jako zmienne (lub stałe) Rb,Gb,Bb. To samo robimy dla koloru czarnego i składujemy je jako Rc, Gc, Bc. A następnie trzeba przeskalować otrzymaną wartość dla danego koloru według następującego wzoru( (X-Xc)/(Xb-Xc))*255. Gdzie X to odczytana wartość danego kanału dla wybranego koloru, (RGB), Xc to wartość dla wybranego kanału dla koloru czarnego, a Xb to wartości dla koloru białego. Jednym matematycznym zdaniem X={R,G,B}.

I to tyle w temacie. Zapraszam do korzystania. I nie czepiać sie programu głównego bo służy on tylko do testów i jest całkowicie niezoptymalizowany. Można się czepiać wyłącznie procedur i ewentualnie klas :P

_________________
Pomysły na podpis - wyślij SMSa +1 769 243 0011



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 maja 2017, o 07:06 
Offline
Użytkownik

Dołączył(a): 23 sty 2014
Posty: 1079
Pomógł: 73

Kawał dobrej roboty :)
pod AVR-a jest ten kod? :)
jakiego kompilatora używasz?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 maja 2017, o 16:54 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 cze 2013
Posty: 988
Lokalizacja: Byram, MS 39272
Pomógł: 55

Dziękuję za komplement.
Tak, zapomniałem wspomnieć, że całość została napisana i skompilowana pod Atmega328 ale nic nie stoi na przeszkodzie by używać kodu z innymi prockami. Kod, który zaprezentowałem zajmuje 4% po kompilacji na wspomnianej Atmedze. Do skompilowania użyłem najnowszego toolchaina przy współpracy ze środowiskiem CodeBlock. Aczkolwiek środowisko nie ma nic do kompilatora więc tak jak napisałem - najnowszy toolchain.

_________________
Pomysły na podpis - wyślij SMSa +1 769 243 0011



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 maja 2017, o 18:20 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27212
Lokalizacja: Szczecin
Pomógł: 1041

Bardzo fajny przykład dla tych którzy chcą skierować swoje kroki na próby pisania softu w C++ na AVR'ki

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 maja 2017, o 18:35 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 cze 2013
Posty: 988
Lokalizacja: Byram, MS 39272
Pomógł: 55

Dziękuję, chciałbym dodać, że pisałem podobny soft wcześniej w C i ten w C++ napisany jest:
1) Czytelniejszy - praca na obiektach jest łatwiejsza. C to taka nauka tańca poprzez słuchanie wykładu, a C++ to nauka tańca poprzez tańczenie.
2) Mniejszy - ten kod w C robiący to samo zajmował 7%, a ten tutaj tylko 4%. Niby nic, a jednak czuje gdzieś tam, że to coś.
3) Łatwiejszy - naprawdę praca na obiektach jest łatwiejsza choć jest wiele rzeczy, które wydają się ciężkie - na przykład jak umieścić wskaźnik do procedury w ciele klasy jako "prywatny"? Ale już to ogarnąłem (przynajmniej teoretycznie) więc teraz zostają mi testy i klasa zostanie poprawiona.
4) Wykorzystanie RAMu też jest jakieś takie mniejsze.
Ogólnie rzecz biorąc na początku miałem złe zdanie o C++, bałem się, że obiekty będą dużo ważyć, że kod będzie mało optymalny i przede wszystkim mało przejrzysty - jak widać myliłem się!

_________________
Pomysły na podpis - wyślij SMSa +1 769 243 0011



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 23 maja 2017, o 20:28 
Offline
Użytkownik

Dołączył(a): 25 lip 2013
Posty: 2561
Pomógł: 126

Fajny kodzik i podejście! Gratulacje.

Sent from my Mi-4c using Tapatalk



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 6 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO