<?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=8&amp;t=13854&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2015-12-15T21:28:12+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=8&amp;t=13854&amp;mode</id>
<entry>
<author><name><![CDATA[SylwekK]]></name></author>
<updated>2015-12-15T21:28:12+01:00</updated>
<published>2015-12-15T21:28:12+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=148162#p148162</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=148162#p148162"/>
<title type="html"><![CDATA[Re: [atmega8L] Enkoder, obliczanie szerokości impulsu, silni]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=148162#p148162"><![CDATA[
Spróbuj w ten sposób:<br /><br />[syntax=c]ISR(INT0_vect)                                                  // przerwanie mierzące ilość impulsów z enkodera silnika 0<br />{<br />        licznik_impulsow++;<br />}<br />ISR(TIMER0_OVF_vect)<br /><br />{<br />        if (licznik_impulsow &lt; ILOSC_IMPULSOW)<br />        {<br />        if(OCR1B &lt; 500) OCR1B++;<br />        } <br />        <br />        if(licznik_impulsow &gt; ILOSC_IMPULSOW)<br />        {<br />            if(!OCR1B) OCR1B--;<br />        }<br /><br />        licznik_impulsow = 0;                           // zeruje licznik impulsów<br />        TCNT0 = TIMER_START;<br /><br />}[/syntax]<br /><br />Jeśli przerwania masz ustawione prawidłowo to powinno działać.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1922">SylwekK</a> — 15 gru 2015, o 21:28</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawid75_75]]></name></author>
<updated>2015-12-13T18:47:51+01:00</updated>
<published>2015-12-13T18:47:51+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147866#p147866</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147866#p147866"/>
<title type="html"><![CDATA[Re: [atmega8L] Enkoder, obliczanie szerokości impulsu, silni]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147866#p147866"><![CDATA[
Oto jak próbuję policzyć ilość impulsów w czasie:<br />[syntax=c]ISR(INT0_vect)// przerwanie mierzące ilość impulsów z enkodera silnika 0<br />{<br />licznik_impulsow++;<br />}<br /><br />ISR(TIMER0_OVF_vect)<br />{<br /><br />if (licznik_impulsow &lt; ILOSC_IMPULSOW &amp;&amp; OCR1B &lt; 500)<br />{<br />OCR1B++;<br />} <br />else if(licznik_impulsow &gt; ILOSC_IMPULSOW || OCR1B &gt; 500)<br />{<br />OCR1B--;<br />}<br />else if(licznik_impulsow == ILOSC_IMPULSOW);<br /><br />licznik_impulsow = 0;// zeruje licznik impulsów<br />TCNT0 = TIMER_START;<br />}[/syntax]<br /><br />Mam dwa przerwania - jedno do rejestracji i zliczania impulsów z enkodera, a drugie w momencie przepełnienia timera. Czyli regulacja odbywa się co przepełnienie. W okresie jednego przepełnienia powinny pojawić się 4 zmiany stanu z enkodera. Jednak ten kod działa tak, że ILOSC_IMPULSOW w ogóle zdaje się nie mieć znaczenia i OCR1B ustala się na poziomie 400, a to daje 8 zmian stanu z enkodera w jednostce czasu jakim jest jedno przekręcenie się licznika timer/counter0. Jakim cudem ILOSC_IMPULSOW w ogóle nie ma znaczenia w tym kodzie?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=11277">dawid75_75</a> — 13 gru 2015, o 18:47</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawid75_75]]></name></author>
<updated>2015-12-13T00:50:22+01:00</updated>
<published>2015-12-13T00:50:22+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147829#p147829</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147829#p147829"/>
<title type="html"><![CDATA[Re: [atmega8L] Enkoder, obliczanie szerokości impulsu, silni]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147829#p147829"><![CDATA[
Te warunki to na wypadek gdyby jakimś cudem OCR1B zrobiłoby się ujemne.<br /><br />Już nie mam pomysłu na tę regulację. Próbowałem zliczać impulsy w czasie (u mnie powinno być 5 zmian stanu na 256ms, czyli na jeden cały zakres timera 8-bitowego z preskalerem 1024 i zegarem 1MHz), próbowałem podziałać z regulatorem PI (który mi zbytnio nie wyszedł) i nic mi nie wychodzi, jakbym w ogóle nic nie robił tylko od razu strzelił OCR1B na maksa czyli 500.<br />Proszę o jakieś dalsze wskazówki jak to poprawnie wykonać, bo już ręce i nogi opadają.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=11277">dawid75_75</a> — 13 gru 2015, o 00:50</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[SylwekK]]></name></author>
<updated>2015-12-12T22:40:03+01:00</updated>
<published>2015-12-12T22:40:03+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147815#p147815</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147815#p147815"/>
<title type="html"><![CDATA[Re: [atmega8L] Enkoder, obliczanie szerokości impulsu, silni]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147815#p147815"><![CDATA[
<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />Mam 8 impulsów na obrót (magnes neodymowy 8-polowy).<br /></div><br />No to spokojnie 16 tyknięć masz jak na talerzu <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />Jeśli będę reagował na zmianę stanu to sytuacja będzie taka, że raz zmierzę odległość między zboczem opadającym a narastającym albo na odwrót<br /></div><br /><br />...i co w tym złego? Tak między nami to ostatnio moja ulubiona metoda mierzenia obrotów, a przede wszystkim bardzo łatwa do zrealizowania. Mam nawet wrażenie, że łatwiejsza niż liczenie konkretnego zbocza <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> Do jego kontroli wystarczy jedna prosta linia programu(!) i jeden nikomu niepotrzebny bit <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />żeby obliczyć częstotliwość to muszę wiedzieć między jakimi zboczami liczę odległość, czy tak?<br /></div><br />Wystarczy, że zmierzysz w jednostce czasu ilość impulsów lub policzysz np. 10 czy 20 impulsów i zmierzysz czas w jakim tego dokonałeś.<br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />Jednak moją największą bolączką w tym momencie jest to, że OCR1B ciągle leci do 500, nieważne co zrobię. Jak sobie z tym poradzić?<br /></div><br /><br />Nie chce mi się dogłębnej analizy prowadzić, ale to badanie jest trochę dziwne dla mnie:<br />if ((n_0r &lt; n_0) &amp;&amp; (<strong><span style="color: #BF0000">OCR1B &gt;= 0</span></strong> &amp;&amp; OCR1B &lt; 500))<br />i po nim zwiększanie rejestru.<br />Spodziewasz się w tym rej czegoś mniejszego od zera lub większego od 500, bo tak jak jest teraz to mam wrażenie, że zawsze będzie zwiększać jego wartość.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1922">SylwekK</a> — 12 gru 2015, o 22:40</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawid75_75]]></name></author>
<updated>2015-12-12T21:27:07+01:00</updated>
<published>2015-12-12T21:27:07+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147803#p147803</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147803#p147803"/>
<title type="html"><![CDATA[Re: [atmega8L] Enkoder, obliczanie szerokości impulsu, silni]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147803#p147803"><![CDATA[
Mam 8 impulsów na obrót (magnes neodymowy 8-polowy).<br />Odnośnie przerwań - jeśli nie INT to gdzie? <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br />Jeśli będę reagował na zmianę stanu to sytuacja będzie taka, że raz zmierzę odległość między zboczem opadającym a narastającym albo na odwrót, a żeby obliczyć częstotliwość to muszę wiedzieć między jakimi zboczami liczę odległość, czy tak?<br /><br />Jednak moją największą bolączką w tym momencie jest to, że OCR1B ciągle leci do 500, nieważne co zrobię. Jak sobie z tym poradzić?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=11277">dawid75_75</a> — 12 gru 2015, o 21:27</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[SylwekK]]></name></author>
<updated>2015-12-12T21:04:13+01:00</updated>
<published>2015-12-12T21:04:13+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147800#p147800</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147800#p147800"/>
<title type="html"><![CDATA[Re: [atmega8L] Enkoder, obliczanie szerokości impulsu, silni]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147800#p147800"><![CDATA[
Ile impulsów na obrót daje ci silnik? pomiar tylko jednego impulsu i wg niego regulowanie PWM raczej nie da dobrych efektów, bo odstępy chyba nie będą idealne. Jeśli masz trzy śmigiełka w enkoderze to czytaj zmianę stanu dzięki czemu podwoisz ilość impulsów, a to już pozwoli wiarygodnie zmierzyć częstotliwość i to od niej uzależniaj obroty. Jeśli zajdzie taka potrzeba można użyć zmiennej doganiającej z niewielkim opóźnieniem (czyli po prostu opcja bardzo delikatnej rampy) dzięki, której zmiany prędkości będą bardziej płynne. Aha, sam pomiar częstotliwości nie musi być wykonywany w przerwaniach INT. Możesz spokojnie ustawić zwykłe przerwania, czytać dowolne porty (sądząc po czasie nadchodzenia kolejnych impulsów wystarczyć powinno nawet 1kHz) i tam mierzyć częstotliwość.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1922">SylwekK</a> — 12 gru 2015, o 21:04</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawid75_75]]></name></author>
<updated>2015-12-12T20:16:06+01:00</updated>
<published>2015-12-12T20:16:06+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147796#p147796</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147796#p147796"/>
<title type="html"><![CDATA[[atmega8L] Enkoder, obliczanie szerokości impulsu, silnik DC]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=13854&amp;p=147796#p147796"><![CDATA[
Szanowni Forumowicze.<br />Od pewnego czasu pracuję nad robotem mobilnym sterowanym za pomocą atmegi8L. Mój problem w tym momencie to regulacja prędkości silnika DC. Jak chcę to zrobić? Mam enkoder, który generuje sygnał prostokątny w zależności od prędkości obrotowej silnika. Doświadczalnie sprawdziłem - przy pomocy oscyloskopu - że silnik pracuje optymalnie gdy enkoder pokazuje 40ms pomiędzy zboczem narastającym i opadającym. Tę wartość przyjąłem jako wzorcową dla regulatora. Sygnał z tego enkodera chcę podawać na pin INT0 i liczyć odległość pomiędzy zboczami za pomocą przerwania zewnętrznego oraz timera 8-bitowego. Silnikiem steruję przez mostek L293DNE i na prędkość silnika wpływam sygnałem PWM i chcę regulować ten PWM programowo/automatycznie w zależności od prędkości zadanej w zmiennej n_0. Poniżej przedstawiam fragment kodu z mojego programu:<br />[syntax=c]#defineDC_PRZOD_B PORTD|=  (1&lt;&lt;WE_B_A); PORTD &amp;= ~(1&lt;&lt;WE_B_B)<br /><br />volatile uint8_t n_0 = 40;// prędkość zadana dla silnika 0 jako odstęp między sygnałami enkodera w ms<br />volatile uint8_t n_0r = 0;// prędkość rzeczywista silnika 0<br />...<br />TCCR0 |= (1&lt;&lt;CS02) | (1&lt;&lt;CS00);// konfiguracja timer/counter0: źródłem CLK, preskaler 1024<br />  DDRD &amp;= ~(1&lt;&lt;ENKODER_0);// konfiguracja pinu PD2 portu D jako wejście<br /><br />GICR  |= (1&lt;&lt;INT0);// przerwanie zewnętrzne od INT0<br />MCUCR |= (1&lt;&lt;ISC00) | (1&lt;&lt;ISC01);// przerwanie wywoła zbocze narastające<br /><br />...<br />        OCR1B = 0;// wartość początkowa porównania B (Wyjście OC1B - PB2), zmiana duty cycle<br />ICR1  = 500;// wartość maksymalna dla trybu 14, więc częstotliwość CLK/ICR1 = 1kHz; ICR1 - TOP<br /><br />...<br />sei();<br />...<br />                ADCSRA |= (1&lt;&lt;ADSC);//ADSC: uruchomienie pojedynczej konwersji  <br /> while(ADCSRA &amp; (1&lt;&lt;ADSC));//czeka na zakończenie konwersji  <br /><br />if (ADC &gt;= 100 &amp;&amp; ADC &lt; 190)// akcja przycisku C - pojazd jedzie do przodu<br />{<br />DC_PRZOD_B;<br /> if ((n_0r &lt; n_0) &amp;&amp; (OCR1B &gt;= 0 &amp;&amp; OCR1B &lt; 500))<br /> {<br /> OCR1B++;<br />    } <br />   else<br />{<br />OCR1B--;<br />if (OCR1B &lt; 0)<br />{<br />OCR1B = 0;<br /> }<br />}<br />}<br />...<br />ISR(INT0_vect)// przerwanie mierzące prędkość rzeczywistą chwilową silnika 0<br />{<br />if ((MCUCR &amp; (1&lt;&lt;ISC00)))<br />{<br />TCNT0 = 0;<br /> }<br />else<br />{<br />n_0r = TCNT0;<br />}<br />MCUCR ^= (1&lt;&lt;ISC00);// zmiana zbocza wywołującego przerwanie<br />}[/syntax]<br /><br />Zegar taktuje 1MHz więc preskaler dałem 1024 żeby impulsy wychodziły co ok. 1ms. Zrobiłem to po to aby wartość liczbowa odpowiadała zadanemu czasowi w zmiennej n_0.<br />Wg mnie powinno wszystko działać, ale nie działa. Jak uruchomię program i pojazd to zawsze wartość OCR1B leci do 500. Już nie wiem czego się chwycić. Bardzo proszę o wskazówki, świeżym okiem pewnie lepiej się coś zauważy <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> Jeśli potrzeba jeszcze jakichś informacji odnośnie układu to dopiszę.<br />Pozdrawiam.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=11277">dawid75_75</a> — 12 gru 2015, o 20:16</p><hr />
]]></content>
</entry>
</feed>