startrek1p2p Napisano Listopad 16, 2019 Udostępnij Napisano Listopad 16, 2019 (edytowany) Hej, napotkałem na problem przy czujniku koloru. Ten czujnik został podłączony jak w różnych poradnikach, ale dalej pokazywał dziwne wartości. Chciałem aby odczytywał kolory RGB w skali 0-255 i następnie żeby ten wynik wyświetlał na diodzie WS2812. Niestety ten czujnik wyświetla dziwne wyniki " R= -1350 G= -1615 B= -1887 " Gdzie tutaj leży błąd ? Kod już próbowałem zmieniać kilkukrotnie i nigdy nie otrzymywałem prawdziwego wyniku. Może czujnik jest zepsuty? Czy może jeszcze coś innego? Włączałem i wyłączałem podświetlenie, też to nic nie daje. Obecny kod został praktycznie skopiowany i wklejony z tej strony i dodana tylko linijka WS2812 abym na bieżąco widział, jaki jest kolor. #define S0 4 #define S1 5 #define S2 6 #define S3 7 #define sensorOut 8 #include <Adafruit_NeoPixel.h> int frequency = 0; int R = 0; int G = 0; int B = 0; Adafruit_NeoPixel linijka = Adafruit_NeoPixel(8, A0, NEO_GRB + NEO_KHZ800); void setup() { pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); pinMode(2, OUTPUT); pinMode(sensorOut, INPUT); // Setting frequency-scaling to 20% digitalWrite(S0,HIGH); digitalWrite(S1,LOW); digitalWrite(2, HIGH); Serial.begin(9600); linijka.begin(); //Inicjalizacja linijka.show(); } void loop() { // Setting red filtered photodiodes to be read digitalWrite(S2,LOW); digitalWrite(S3,LOW); // Reading the output frequency frequency = pulseIn(sensorOut, LOW); //Remaping the value of the frequency to the RGB Model of 0 to 255 frequency = map(frequency, 25,72,255,0); // Printing the value on the serial monitor Serial.print("R= ");//printing name Serial.print(frequency);//printing RED color frequency Serial.print(" "); R = frequency; delay(100); // Setting Green filtered photodiodes to be read digitalWrite(S2,HIGH); digitalWrite(S3,HIGH); // Reading the output frequency frequency = pulseIn(sensorOut, LOW); //Remaping the value of the frequency to the RGB Model of 0 to 255 frequency = map(frequency, 30,90,255,0); // Printing the value on the serial monitor Serial.print("G= ");//printing name Serial.print(frequency);//printing RED color frequency Serial.print(" "); G = frequency; delay(100); // Setting Blue filtered photodiodes to be read digitalWrite(S2,LOW); digitalWrite(S3,HIGH); // Reading the output frequency frequency = pulseIn(sensorOut, LOW); //Remaping the value of the frequency to the RGB Model of 0 to 255 frequency = map(frequency, 25,70,255,0); // Printing the value on the serial monitor Serial.print("B= ");//printing name Serial.print(frequency);//printing RED color frequency Serial.println(" "); B = frequency; delay(100); linijka.setPixelColor(5, linijka.Color(R, G, B)); linijka.show(); delay(500); Serial.print(" "); Serial.print(R); Serial.print(" "); Serial.print(G); Serial.print(" "); Serial.println(B); } Edytowano Listopad 16, 2019 przez startrek1p2p
RFM Listopad 16, 2019 Udostępnij Listopad 16, 2019 Co to za czujnik? Umieść jego notę katalogowa na forum. Aktualizacja: Note znalazłem https://pdf1.alldatasheet.com/datasheet-pdf/view/560507/AMSCO/TCS3200.html Aktualizacja: Deklarujesz int frequency a spodziewana wartość frequency to 0..255. Dlaczego deklarujesz int (+/-32kB)? To powód otrzymywania wartości ujemnych. Wyświelt co otrzymujesz z pulseIn(sensorOut, LOW); Aktualizacja: Z tego co widzę to pulseIn zwraca unsigned long. Programista spodziewa się wartości 25..72. Łatwo wywnioskować, że przekroczony jest zakres. Obstawiam, że na wejściu sensorOut nie ma sygnału. Sprawdź oscyloskopem czy i jaki sygnał tam jest. 1
Elvis Listopad 17, 2019 Udostępnij Listopad 17, 2019 @startrek1p2p wyłącz na chwilę wywołania funkcji map(), będzie można wtedy zobaczyć jak wyglądają same odczyty z czujnika. Wygląda na to że, twój czujnik zwraca wartości z innego przedziału niż zakładasz - zacznij więc od sprawdzenia, jakie są to wartości i czy zmieniają się zgodnie z oczekiwaniami. 1 1
startrek1p2p Listopad 17, 2019 Autor tematu Udostępnij Listopad 17, 2019 (edytowany) @RFM niestety nie mam oscyloskopy i żadnego znajomego który by go posiadał. Zamieniłem z int na byte wiec tutaj już powinno byc lepiej, int frequency = 0; byte R = 0; byte G = 0; byte B = 0; na razie wartość frequency zostawiłem aby zobaczyć co dalej będzie wychodzić Wartości pulseIn : @Elvis zmieniłem ale nie do końca wiem czego mam sie spodziewać w sensie jakich wartości. To, że sie zmieniają to widać. Oznaczyłem kolorami przedmioty o tych samych kolorach do czujnikach. posprawdzałem wszytko i widzę, że tutaj odległość 3/5 mm wpływa diametralnie na cały odczyt. wiec nawet jak ustawie pod kątem to wynik jest zafałszowany. i już mniej więcej mogę utalic ale tylko pod konkretny kolor ( czerwony, zielony, niebieski) ale juz ma problem przy innych kolorach oraz innych odcieniach Edytowano Listopad 17, 2019 przez startrek1p2p
RFM Listopad 17, 2019 Udostępnij Listopad 17, 2019 22 minuty temu, startrek1p2p napisał: niestety nie mam oscyloskopy i żadnego znajomego który by go posiadał. Na to nic nie poradzę. Nie zabieram się do budowy domu jak nie mam betoniarki. 23 minuty temu, startrek1p2p napisał: na razie wartość frequency zostawiłem aby zobaczyć co dalej będzie wychodzić Wyniki stabilne ale niezgodne z tym czego spodziewał się autor programu. 24 minuty temu, startrek1p2p napisał: @Elvis zmieniłem ale nie do końca wiem czego mam sie spodziewać w sensie jakich wartości. Pisałem jakich wartości spodziewa się autor programu.
Popularny post Elvis Listopad 17, 2019 Popularny post Udostępnij Listopad 17, 2019 @startrek1p2p Ja też nie wiem jakie wartości będziesz odczytywał - dlatego napisałem żebyś na razie zrezygnował z funkcji map() i przetestował jaki jest zakres wartości. Bo map() przelicza zakresy, czyli jak miałeś: frequency = map(frequency, 25,72,255,0); to zakres 25-72 był przeliczany na 255-0. Jeśli dostałeś wartość spoza zakresu 25-72, to i wyniki wyszły poza 0-255. Stąd takie dziwne wartości. Moim zdaniem powinieneś zacząć od ustalenia jakie wartości dostajesz dla R, G i B - zaczynając od całkiem zasłoniętego czujnika, a kończąc na oświetlonym białym światłem. Co więcej warto sprawdzić, czy czujnik odpowiednio reaguje na kolory - tak żeby się upewnić że wszystko działa. Nie musisz mieć do tego oscyloskopu, wystarczy trochę się pobawić i poobserwować wyniki. Jeśli umieścisz czerwony obiekt - wartości dla czerwonego powinny maleć itd. Dopiero wiedząc jakie otrzymujesz "gołe" wyniki możesz dodać funkcję map() i przeskalować odczytane wartości na oczekiwany zakres. Musisz jednak pamiętać, że map może zwracać też wartości spoza oczekiwanego przedziału. I jeszcze jedno - zmień typ zmiennych R,G,B z powrotem na int. Teraz jest dużo gorzej niż było. 2 1
startrek1p2p Listopad 17, 2019 Autor tematu Udostępnij Listopad 17, 2019 No to na razie sie pobawię z samymi karteczkami i kolorami, zobaczymy co sie uda to jednak trochę zajmie. Początkowy projekt jest jednak trochę po za moimi granicami, przynajmniej na razie
Elvis Listopad 17, 2019 Udostępnij Listopad 17, 2019 (edytowany) Nie musisz testować wszystkich możliwych kolorów - potrzebujesz tak naprawdę 6 liczb, czyli minimalnej i maksymalnej wartości, która jest zwracana przez pulseIn() dla trzech kolorów w używanym przez Ciebie otoczeniu. Później możesz te wartości wstawić do map(). Musisz tylko doczytać jak działa ta funkcja: https://www.arduino.cc/reference/en/language/functions/math/map/ Wykonuje ona proste skalowanie, czyli: long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } Więc jeśli wartość x, czyli wejście jest poza zakresem in_min - in_max, to i wynik jest poza zakresem out_min i out_max. Będziesz musiał więc odczytany wynik ograniczyć jeśli wyszedł poza zakres, albo jeszcze lepiej - ograniczyć wartość danej wejściowej, czyli x. Edytowano Listopad 17, 2019 przez Elvis 1 1
startrek1p2p Listopad 17, 2019 Autor tematu Udostępnij Listopad 17, 2019 Coś pokombinuje i zobaczę co z tego wyjdzie. Najgorsze jest to, że ta odległość zawsze musi być taka sama, więc jeszcze do tego muszę zrobić obudowę która będzie dotykała bezpośrednio przedmiot i dopiero mogę coś robić z kolorem. Czyli z tymi kolorami to mam szukać maksymalnej i minimalnej wartości Która ogólnie mi się pojawi w otoczeniu(np biały kolor na szafce) ? Czy tylko na konkretnym głównym kolorze (kartki R G B z oświetleniem i bez) ?
Elvis Listopad 17, 2019 Udostępnij Listopad 17, 2019 Moim zdaniem warto przetestować jak zachowa się program i czujnik przy maksymalnych wartościach - ale nie musisz się nimi szczególnie przejmować. Jak będziesz znał zakres, który Cię interesuje wystarczy wpisać go do funkcji map(), ale przed jej użyciem wywołać funkcję constrain() https://www.arduino.cc/reference/en/language/functions/math/constrain/ Wtedy wszystko powinno działać jak należy 1
startrek1p2p Listopad 17, 2019 Autor tematu Udostępnij Listopad 17, 2019 @Elvis dzięki. Dam później znać co wyszło
marek1707 Listopad 17, 2019 Udostępnij Listopad 17, 2019 Ten czujnik zawsze na początku sprawia problemy, bo zapominamy, że: Nie ma żadnej optyki i widzi dokładnie całą przednią półsferę. Ch-ka kierunkowa pokazuje, że spadek czułości do 50% następuje dopiero powyżej 70° odchylenia od osi a i przy 90° wciąż jeszcze jest 10%. Gdyby chcieć zrozumieć jak ten czujnik widzi otoczenie trzeba wyobrazić sobie okulary z mleczną szybą. Czy zakłądając je na nos możemy określić kolor czerwonej kartki A4 w odległości 50cm od oczu? Nie ma szans, bo jej pole powierzchni stanowi jedynie niewielki fragment wszytskiego co widzimy. Do naszych oczu dociera średnia z całego pola widzenia i zwykle będzie to mniej lub bardziej średnio szare. Natomiast gdy przyłożymy tę kartkę sobie do nosa, wtedy nasze okulary wyraźnie poczerwienieją. Jeżeli chcesz by ten czujnik określał kolor czegoś co mu pokazujesz musisz sprawić, by widział tylko to. Albo robisz czarną puszkę z okienkiem odsłaniającym dobrze oświetlony przedmiot badany albo wstawiasz czujnik w czarną (matową, tekturową?) rurkę kończącą się przy powierzchni badanej. Im dalejbędzie przedmiot i im mniejszy jest musisz go jaśniej oświetlić, to chyba oczywiste. Dziłające rozwiązania spokojni eodrózniające kolory to a) zbliżenie tego czegoś na 2-3mm od czoła, b) rurka, c) puszka z okienkiem, d) najtańszy obiektyw od kamerki z filtrem IR. Wszystkie trzy diody RGB bardzo dobrze widzą podczerwień. Filtry kolorów mają "dziurę" w paśmie od 800nm do 1um więc w otoczeniu czujnika (nawet "z tyłu") nie może być żadnych żarówek, świetlówek, ekranów LCD itp rzeczy. "Światło" podczerwone z tego typu źródeł jednakowo intensywnie oddziaływuje na każdą fotodiodę i wtedy kolor przedmiotu który chcemy analizować zwyczajnie znika w śmieciach. A jeśli weźmiemy pod uwagę, że od żarówek/świetlówek zwykle są to sygnały 100Hz to zaczyna wyglądać, że dostajemy zupełnie losowy sygnał kolorów. Popróbowałbym ze zmniejszeniem częstotliwości sygnałów. W programie widzę, że czujnik jest ustawiony na średni zakres częstotliwości wyjściowych (S0=1, S1=0) co oznacza, że może wygenerować sygnał nawet ponad 100kHz. Ponieważ pulseIn() mierzy długość "jedynki" to polegnie już powyżej 50kHz, bo z opisu tej funkcji wiemy, że mierzy od 10us. Swoją drogą pomiar długości stanu wysokiego nie daje "frequency" jak nazywa się zmienna w kodzie a wręcz przeciwnie: im więcej światła tym częstotliwość z czujnika będzie wyższa czyli okres krótszy, więc liczba oddana przez pulseIn() będzie mniejsza. Po zrobieniu dobrego układu mechaniczno-optycznego (to podstawa, bez tego w żadne pomiary nie mają sensu) spróbuj jakie liczby się mierzą dla S0=0 i S1=1, tylko zmień typ zmiennych frequency, R, G i B na taki który te pomiary pomieści, np. uint32_t. 1
startrek1p2p Listopad 17, 2019 Autor tematu Udostępnij Listopad 17, 2019 @RFM Sory, że dopiero teraz, ale jakoś twój komentarz mi umkną. 3 godziny temu, RFM napisał: Na to nic nie poradzę. Nie zabieram się do budowy domu jak nie mam betoniarki. nie od razu Kraków zbudowano. Zabawę z Arduino nie zaczyna się od przygotowania całego laboratorium, bo główną zaletą tej całej platformy jest niewielkie potrzebne zaplecze do startu, i na tym bazuje. 3 godziny temu, RFM napisał: Wyniki stabilne ale niezgodne z tym czego spodziewał się autor programu. wtedy jeszcze myślałem, że wartość RGB będzie zawsze taki sam dla każdego koloru i czujnika tego typu. @marek1707 Dzięki, Twoja odpowiedz idealnie uzmysłowiła mi co mam teraz zrobić i tutaj posprawdzam co sie stanie, już mam pomysł jak to zrobić. Za kilka dni dam znać
RFM Listopad 17, 2019 Udostępnij Listopad 17, 2019 (edytowany) 1 godzinę temu, startrek1p2p napisał: wtedy jeszcze myślałem, że wartość RGB będzie zawsze taki sam dla każdego koloru Nie będzie. Zarówno oko, jak i czujnik, ma różną charkterystykę dla każdej podstawowej barwy. Kolor biały nie da równych wartości wszystkich składowych RGB np 250, 250, 250. Edytowano Listopad 17, 2019 przez Gieneq
Pomocna odpowiedź
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ę »