<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=23&amp;t=18468&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2017-05-23T20:28:25+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=23&amp;t=18468&amp;mode</id>
<entry>
<author><name><![CDATA[micky]]></name></author>
<updated>2017-05-23T20:28:25+01:00</updated>
<published>2017-05-23T20:28:25+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189728#p189728</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189728#p189728"/>
<title type="html"><![CDATA[Re: Czujnik kolor(ów) TCS3200]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189728#p189728"><![CDATA[
Fajny kodzik i podejście! Gratulacje. <br /><br />Sent from my Mi-4c using Tapatalk<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1546">micky</a> — 23 maja 2017, o 20:28</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[WoodPaker]]></name></author>
<updated>2017-05-23T18:35:26+01:00</updated>
<published>2017-05-23T18:35:26+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189726#p189726</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189726#p189726"/>
<title type="html"><![CDATA[Re: Czujnik kolor(ów) TCS3200]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189726#p189726"><![CDATA[
Dziękuję, chciałbym dodać, że pisałem podobny soft wcześniej w C i ten w C++ napisany jest:<br />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. <br />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ś.<br />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 &quot;prywatny&quot;? Ale już to ogarnąłem (przynajmniej teoretycznie) więc teraz zostają mi testy i klasa zostanie poprawiona. <br />4) Wykorzystanie RAMu też jest jakieś takie mniejsze.<br />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ę!<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1425">WoodPaker</a> — 23 maja 2017, o 18:35</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2017-05-23T18:20:28+01:00</updated>
<published>2017-05-23T18:20:28+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189724#p189724</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189724#p189724"/>
<title type="html"><![CDATA[Re: Czujnik kolor(ów) TCS3200]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189724#p189724"><![CDATA[
Bardzo fajny przykład dla tych którzy chcą skierować swoje kroki na próby pisania softu w C++ na AVR'ki<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 23 maja 2017, o 18:20</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[WoodPaker]]></name></author>
<updated>2017-05-23T16:54:33+01:00</updated>
<published>2017-05-23T16:54:33+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189722#p189722</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189722#p189722"/>
<title type="html"><![CDATA[Re: Czujnik kolor(ów) TCS3200]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189722#p189722"><![CDATA[
Dziękuję za komplement.<br />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.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1425">WoodPaker</a> — 23 maja 2017, o 16:54</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Jarecki]]></name></author>
<updated>2017-05-23T07:06:21+01:00</updated>
<published>2017-05-23T07:06:21+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189705#p189705</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189705#p189705"/>
<title type="html"><![CDATA[Re: Czujnik kolor(ów) TCS3200]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189705#p189705"><![CDATA[
Kawał dobrej roboty <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> <br />pod AVR-a jest ten kod? <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br />jakiego kompilatora używasz?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=2511">Jarecki</a> — 23 maja 2017, o 07:06</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[WoodPaker]]></name></author>
<updated>2017-05-22T21:04:51+01:00</updated>
<published>2017-05-22T21:04:51+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189702#p189702</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189702#p189702"/>
<title type="html"><![CDATA[Czujnik kolor(ów) TCS3200]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=18468&amp;p=189702#p189702"><![CDATA[
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 &quot;zamienia&quot; kolor jaki &quot;widzi&quot; 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. <br />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.<br /> <br /><a href="https://obrazkiforum.atnel.pl/1425/8170ba8d4701b22920584a6c23522980.jpg"  class="postlink"><img src="https://obrazkiforum.atnel.pl/thumb/1425/8170ba8d4701b22920584a6c23522980.jpg" alt="Obrazek" /></a><br />czujnik TCS3200<br /><br />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 &quot;odczytaniu&quot; koloru.<br />W tabeli poniżej pokazane jest jak należy sterować urządzeniem.<br /><br /><a href="https://obrazkiforum.atnel.pl/1425/656c1cd997a570b3efe738967b1fc587.png"  class="postlink"><img src="https://obrazkiforum.atnel.pl/thumb/1425/656c1cd997a570b3efe738967b1fc587.png" alt="Obrazek" /></a><br />Tabela ustawień czujnika TCS3200<br /><br />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ć)<br /><strong><em>int.hpp</em></strong><br />[syntax=cpp]//int.hpp - autor - WoodPaker<br />#include &lt;avr/interrupt.h&gt;<br />#pragma once<br /> <br />enum _EICRA {_LOW,_ANY,_FALING,_RASING};<br /> <br /> <br />class class_INT0<br />{<br />    public:<br />        /** Default constructor */<br />        class_INT0();<br />        class_INT0(uint8_t _EICRA, void(*callback_int)(void));<br />        /** Default destructor */<br /> <br />         void on(void);<br />         void off(void);<br />         ~class_INT0();<br /> <br /> <br />    protected:<br /> <br />    private:<br />};[/syntax]<br /><br /><strong><em>int.cpp</em></strong><br />[syntax=cpp]//int.cpp - autor - WoodPaker<br />#include &quot;_INT.h&quot;<br /> <br /> <br />void (*callback_i)();<br /> <br />class_INT0::class_INT0()<br />{<br />    EICRA=0x03;<br />    EIMSK |= (1 &lt;&lt; INT0);;<br />    callback_i=nullptr;<br />}<br /> <br />class_INT0::class_INT0(uint8_t _EICRA, void(*callback_int)(void))<br />{<br />    EICRA=_EICRA;<br />    callback_i = callback_int;<br /> <br />}<br /> <br />void class_INT0::on(void)<br />{<br />    EIMSK |= (1 &lt;&lt; INT0);<br />}<br /> <br /> <br />void class_INT0::off(void)<br />{<br />    EIMSK &amp;= ~(1 &lt;&lt; INT0);<br />}<br /> <br />class_INT0::~class_INT0()<br />{<br />    //dtor<br />}<br /> <br />ISR (INT0_vect)<br />{<br />    (*callback_i)();<br />}[/syntax]<br /><br /><strong><em>main.cpp</em></strong><br /><br />[syntax=cpp]#include &lt;stdint.h&gt;<br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &quot;usart.hpp&quot;<br />#include &lt;stdlib.h&gt;<br />#include &quot;_INT.h&quot;<br /> <br />#define S0 PC5<br />#define S1 PC4<br />#define S2 PC3<br />#define S3 PC2<br />#define OUT PD2<br />#define OE PD5<br /> <br />#define S0_high PORTC |= (1&lt;&lt;S0);<br />#define S0_low PORTC &amp;= ~(1&lt;&lt;S0);<br /> <br />#define S1_high PORTC |= (1&lt;&lt;S1);<br />#define S1_low PORTC &amp;= ~(1&lt;&lt;S1);<br /> <br />#define S2_high PORTC |= (1&lt;&lt;S2);<br />#define S2_low PORTC &amp;= ~(1&lt;&lt;S2);<br /> <br />#define S3_high PORTC |= (1&lt;&lt;S3);<br />#define S3_low PORTC &amp;= ~(1&lt;&lt;S3);<br /> <br /> <br />volatile uint32_t time;<br />volatile uint32_t R;<br />volatile uint32_t G;<br />volatile uint32_t B;<br />volatile uint32_t C;<br />#define R_max 14478<br />#define G_max 14478<br />#define B_max 14478<br />#define C_max 14480<br />#define R_min 172<br />#define G_min 176<br />#define B_min 236<br />#define C_min 835<br />CircularBuffer rxBuffer, txBuffer;<br /> <br />void sendStr(char *buf);<br /> <br /> <br />Usart myUsart(0, 115200, &amp;rxBuffer, &amp;txBuffer);<br />char textR&#91;6&#93;;<br />char textG&#91;6&#93;;<br />char textB&#91;6&#93;;<br />char textC&#91;6&#93;;<br />enum Colours {RED,GREEN,BLUE,CLEAR}; //Unumerate Colours RED,GREEN,BLUE and ClEAR<br />uint32_t ReadColour(uint8_t Colour)<br />{<br />  switch(Colour)<br />  {<br />    case RED:<br />        S2_low;<br />        S3_low;<br />    break;<br /> <br />    case GREEN:<br />        S2_high;<br />        S3_high;<br />      break;<br /> <br />    case BLUE:<br />        S2_low;<br />        S3_high;<br />      break;<br /> <br />    case CLEAR:<br />        S2_high;<br />        S3_low;<br />      break;<br />  }<br />  _delay_ms(10);<br />  return time;<br />}<br /> <br />void INT_0()<br />{<br />    time++;<br />}<br />int main()<br />{<br />    class_INT0 Przerwanie(_RASING,INT_0);<br />    DDRC |= (1&lt;&lt;S0) | (1&lt;&lt;S1) | (1&lt;&lt;S2) | (1&lt;&lt;S3); //Ustawjako wyjœcia<br />    DDRD |= (1&lt;&lt;OE);<br />    DDRD &amp;= ~(1&lt;&lt;OUT);//Ustaw jako wejœcie<br />    sei();<br />    myUsart &lt;&lt; &quot;\n\rSTART - freq 100 procent\n\r&quot;;<br />    S0_high;<br />    S1_high;<br />    PORTD |= (1&lt;&lt;OE);<br />    while(1)<br />    {<br />//RED<br />    Przerwanie.on();<br />    time=0;<br />    R=ReadColour(RED);<br />    Przerwanie.off();<br /> <br />//GREEN<br />    Przerwanie.on();<br />    time=0;<br />    G=ReadColour(GREEN);<br />    Przerwanie.off();<br />//BLUE<br />    Przerwanie.on();<br />    time=0;<br />    B=ReadColour(BLUE);<br />    Przerwanie.off();<br />//CLEAR<br />    Przerwanie.on();<br />    time=0;<br />    C=ReadColour(CLEAR);<br />    Przerwanie.off();<br />    itoa(R,textR,10);<br />    itoa(G,textG,10);<br />    itoa(B,textB,10);<br />    itoa(C,textC,10);<br />    myUsart &lt;&lt; &quot;R=&quot;&lt;&lt;textR&lt;&lt;&quot;   G=&quot;&lt;&lt;textG&lt;&lt;&quot;   B=&quot;&lt;&lt;textB&lt;&lt;&quot;   C=&quot;&lt;&lt;textC;<br />    myUsart &lt;&lt; &quot;\n\rKOLEJNY POMIAR\n\r&quot;;<br />    _delay_ms(2000);<br />    }<br />}[/syntax]<br /><br /><strong>Jak działa program?</strong><br />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:<br /><em>Usart myUsart(0, 115200, &amp;rxBuffer, &amp;txBuffer);<br />class_INT0 Przerwanie(_RASING,INT_0);</em><br />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 <em>uint32_t ReadColour(uint8_t Colour)</em> 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. <br /><br /><strong>Jak odczytać kolor w postaci RGB? </strong><br />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}.<br /><br />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 <img src="https://forum.atnel.pl/images/smilies/icon_razz.gif" alt=":P" title="Pokazuje język" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1425">WoodPaker</a> — 22 maja 2017, o 21:04</p><hr />
]]></content>
</entry>
</feed>