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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2015-01-27T14:21:25+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=10317&amp;mode</id>
<entry>
<author><name><![CDATA[grzesiekk]]></name></author>
<updated>2015-01-27T14:21:25+01:00</updated>
<published>2015-01-27T14:21:25+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=116140#p116140</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=116140#p116140"/>
<title type="html"><![CDATA[Re: Problem z enkoderem i dwoma przewraniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=116140#p116140"><![CDATA[
Poprawiłem i zdecydowanie szybciej chodzi i mniej miejsca zajmuje. Nie wiem co mnie przyćmiło bo już kiedyś to robiłem. Niestety jest tylko trochę lepiej  ale to juz najpewniej problem z mechaniką.<br />Dzięki wielkie za pomoc.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=599">grzesiekk</a> — 27 sty 2015, o 14:21</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2015-01-26T17:16:32+01:00</updated>
<published>2015-01-26T17:16:32+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=116001#p116001</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=116001#p116001"/>
<title type="html"><![CDATA[Re: Problem z enkoderem i dwoma przewraniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=116001#p116001"><![CDATA[
<div class="quotetitle">grzesiekk napisał(a):</div><div class="quotecontent"><br />Czyli najlepiej użyć w tym wypadku, w przerwaniu - tam zeruję i wykonuję proste obliczenia, ATOMIC_BLOCK(ATOMIC_RESTORESTATE) i w nim umieścić te operacje? Dobrze rozumiem?<br /></div><br />W przerwaniu ta zmienna nie zostanie zmieniona przez inną funkcję przerwania. Tak jest domyślnie dla mikrokontrolerów AVR i kompilatora avr-gcc. Tutaj nie musisz tego wstawiać. Ten blok ATOMIC_BLOCK to chwilowe wyłączenie przerwań, a domyślnie jak procesor wykonuje operacje w przerwaniu to drugie przerwanie czeka w kolejce.<br /><br />Myślę, że problemem w tym przypadku jest użycie liczb zmiennoprzecinkowych i działania na nich w przerwaniu. Takie obliczenia zajmują dużo czasu. Przerwania powinny trwać możliwie krótko. Jeśli tak nie jest to inne przerwanie (w tym przypadku od zmiany stanu INT1) musi czekać. Jeśli okaże się, że w czasie tych obliczeń przerwanie INT1 wystąpi 2 razy, ale nie może zostać obsłużone to jedna zmiana zostanie zgubiona, bo procesor po zakończeniu obsługi przerwania od timera2 ma informację, że jakaś część sprzętu coś chciała, ale nie wie ile razy. Spróbuj może tak to poprawić:<br /><br />[syntax=c]wysokosc.odczyt = (abs(encoder.position_new) * 17741UL) / 10000;<br />predkosc_obr = (628 / 2) * (abs(encoder.position_new-encoder.position_last));[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 26 sty 2015, o 17:16</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[grzesiekk]]></name></author>
<updated>2015-01-26T15:35:00+01:00</updated>
<published>2015-01-26T15:35:00+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=115979#p115979</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=115979#p115979"/>
<title type="html"><![CDATA[Re: Problem z enkoderem i dwoma przewraniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=115979#p115979"><![CDATA[
Dziękuję za odzew. Czyli najlepiej użyć w tym wypadku, w przerwaniu - tam zeruję i wykonuję proste obliczenia,  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) i w nim umieścić te operacje? Dobrze rozumiem?<br /><br /><br />[syntax=c]ISR(TIMER2_COMP_vect)<br />{<br /><br />if ((++Timer_obl) &gt; 99) {<br /><br />Timer_obl = 0;<br /><br />ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {<br /><br />encoder.position_last =encoder.position_new;<br />encoder.position_new = encoder.position; // encoder.position - zmienna typu long. Z niej, w przerwaniu od enkodera (INT1) odczytuję informację o pozycji)<br /><br /><br />wysokosc.odczyt = abs(encoder.position_new) * 0.17741;<br />predkosc_obr = ((6.28 / 200) * 10000)* (abs(encoder.position_new-encoder.position_last));<br /><br />}<br /><br />}<br /><br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=599">grzesiekk</a> — 26 sty 2015, o 15:35</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Krauser]]></name></author>
<updated>2015-01-24T21:22:55+01:00</updated>
<published>2015-01-24T21:22:55+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=115751#p115751</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=115751#p115751"/>
<title type="html"><![CDATA[Re: Problem z enkoderem i dwoma przewraniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=115751#p115751"><![CDATA[
<div class="quotetitle">grzesiekk napisał(a):</div><div class="quotecontent"><br />Niby proste - w przerwaniu enkodera inkrementujemy zmienną i resetujemy ja co 100ms, ale niestety nie jest tak słodko. <br />W momencie, w którym pojawia się przerwanie od enkodera, wstrzymywane jest przerwanie od Timera1 i wyniki sypia się...<br /></div><br />Ta zmienna powinna mieć specyfikator volatile, a tam, gdzie ją zerujesz, porównujesz w pętli głównej programu to należy ją otoczyć ATOMIC_BLOCK.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=465">Krauser</a> — 24 sty 2015, o 21:22</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[grzesiekk]]></name></author>
<updated>2015-01-20T21:50:36+01:00</updated>
<published>2015-01-20T21:50:36+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=115038#p115038</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=115038#p115038"/>
<title type="html"><![CDATA[Problem z enkoderem i dwoma przewraniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=10317&amp;p=115038#p115038"><![CDATA[
W akcie desperacji zwracam się do Was z problemem, nad którym siedzę już dosyć długo.<br /><br />Muszę zmierzyć prędkości obrotową obracającego się koła. Koło może obracać się w dwóch kierunkach. Jednocześnie muszę zmierzyć drogę, jaką pokonało - coś w stylu &quot;jojo&quot;.<br />Całość zbudowana jest na Atmega32, kwarc 16000000, uart i parę innych bzdetów takich jak LCD 16x2. Do obsługi enkodera (rozdzielczość 1600 imp na obrót) wykorzystuje przerwanie INT0.<br /><br />Obsługa enkodera:<br />[syntax=c]/*<br /> PORTC Pin change interrupt service routine. Decodes the encoder.<br /> For algorithm, see Scott Edwards article from Nuts&amp;Volts V1 Oct. 1995<br /> (righthand bit of old A,B) xor (lefthand bit of new A,B) =&gt; dir.<br /> Increment or decrement encoder position accordingly<br /> */<br /><br />//enkoder<br />#define A (1&lt;&lt;PD2) //wyprowadzenie A enkodera<br />#define B (1&lt;&lt;PD3)  //wyprowadzenie B enkodera<br /><br />unsigned char enc_pos;<br />unsigned char enc_dir;<br /><br /><br /><br /><br />ISR (INT1_vect)<br />{<br /><br />static unsigned char enc_last = 0, enc_now;<br /><br />enc_now = (PIND &amp; (A | B)) &gt;&gt; 2; //odczytanie stanu inˇw i przesuniŕcie wartoťci o dwie pozycje w prawo<br />enc_dir = (enc_last &amp; 1) ^ ((enc_now &amp; 2) &gt;&gt; 1); //wykrycie kierunku obrotˇw<br />if (enc_dir == 0) {<br />enc_pos++;<br />} else {<br />enc_pos--;<br />}<br /><br />enc_last = enc_now; //zapamiŕtanie ostatniego stanu<br /><br />}[/syntax]<br /><br />i to działa bez problemu - nie myli się nawet przy dużej prędkości koła.<br /><br />Do odmierzania czasu wykorzystuję Timer1 (prescaler 64, i ICR1 = 249 tryb CTC). &quot;Próbkuję&quot; co 100ms - do takich założeń muszę się dostosować... (timer programowy z kodów Kolegi Mirka - kurcze jak prawie 90% innych kodów których używam).<br />Problem jest w monecie  pomiaru prędkości obrotowej koła.<br />Niby proste - w przerwaniu enkodera inkrementujemy zmienną i resetujemy ja co 100ms, ale niestety nie jest tak słodko. <br />W momencie, w którym pojawia się przerwanie od enkodera, wstrzymywane jest przerwanie od Timera1 i wyniki sypia się...<br />Próbowałem kodów do obsługi enkodera z Forum i umieszczałem je w jednym przerwaniu &quot;globalnym&quot; (sprawdzałem stan enkodera nawet z częstotliwością ok 50kHz - wtedy uart poszedł w krzaki), ale niestety gubił kroki. Próbowałem też, liczyć czas, między jednym przerwaniem enkodera a drugim i też lipa. W kodzie nie ma ani jednego &quot;delay...&quot;<br /><br />Czy jest jakiś inny sposób na obliczanie prędkości ew. obsługę w jednym przerwaniu?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=599">grzesiekk</a> — 20 sty 2015, o 21:50</p><hr />
]]></content>
</entry>
</feed>