<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>Lothar Miller - Encoder</title>
    <link>http://www.lothar-miller.de/s9y/</link>
    <description>Elektronik und Musik</description>
    <dc:language>de</dc:language>
    <generator>Serendipity 1.3.1 - http://www.s9y.org/</generator>
    <pubDate>Wed, 20 Apr 2011 06:44:02 GMT</pubDate>

    <image>
        <url>http://www.lothar-miller.de/s9y/templates/bulletproof/img/s9y_banner_small.png</url>
        <title>RSS: Lothar Miller - Encoder - Elektronik und Musik</title>
        <link>http://www.lothar-miller.de/s9y/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Drehgeberauswertung mit Beschleunigung</title>
    <link>http://www.lothar-miller.de/s9y/archives/71-Drehgeberauswertung-mit-Beschleunigung.html</link>
            <category>Encoder</category>
    
    <comments>http://www.lothar-miller.de/s9y/archives/71-Drehgeberauswertung-mit-Beschleunigung.html#comments</comments>
    <wfw:comment>http://www.lothar-miller.de/s9y/wfwcomment.php?cid=71</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.lothar-miller.de/s9y/rss.php?version=2.0&amp;type=comments&amp;cid=71</wfw:commentRss>
    

    <author>nospam@example.com (Lothar Miller)</author>
    <content:encoded>
    
&lt;p&gt;Hier eine &lt;b&gt;Drehgeberauswertung&lt;/b&gt;, die auf der Basis von Peter Danneggers Code (auf &lt;a title=&quot;mikrocontroller.net&quot; target=&quot;_blank&quot; href=&quot;http://www.mikrocontroller.net/topic/112603&quot;&gt;www.mikrocontroller.net&lt;/a&gt;) zusätzlich eine &lt;b&gt;dynamische Beschleunigung&lt;/b&gt; realisiert. Je schneller am Knopf gedreht wird, umso schneller ändert sich der Wert. Das ergibt ein gutes haptisches Gefühl, und man kann größere Bereiche einstellen, ohne dass umgegriffen werden muß.&lt;/p&gt;&lt;hr width=&quot;100%&quot; size=&quot;2&quot; /&gt;&lt;pre&gt;&lt;span style=&quot;color: rgb(0, 136, 136); font-weight: bold;&quot;&gt;volatile&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 119, 68); font-weight: bold;&quot;&gt;int16_t&lt;/span&gt; enc_pos;&lt;br /&gt;&lt;span style=&quot;color: rgb(85, 119, 153);&quot;&gt;#define&lt;/span&gt; PHASE_A  (PINA &amp;amp; &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;1&lt;/span&gt;&amp;lt;&amp;lt;PA1)   &lt;br /&gt;&lt;span style=&quot;color: rgb(85, 119, 153);&quot;&gt;#define&lt;/span&gt; PHASE_B  (PINA &amp;amp; &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;1&lt;/span&gt;&amp;lt;&amp;lt;PA2)&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// ISR wird z.B. &lt;b&gt;jede ms&lt;/b&gt; aufgerufen&lt;/span&gt;&lt;br /&gt;ISR(SIG_OUTPUT_COMPARE1A)&lt;br /&gt;{&lt;br /&gt;&lt;span style=&quot;color: rgb(85, 119, 153);&quot;&gt;    #define&lt;/span&gt; DYNAMIK &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;40&lt;/span&gt;  &lt;br /&gt;    &lt;span style=&quot;color: rgb(0, 136, 136); font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 119, 68); font-weight: bold;&quot;&gt;uint8_t&lt;/span&gt; enc_ab = &lt;span style=&quot;color: rgb(0, 85, 136); font-weight: bold;&quot;&gt;0x01&lt;/span&gt;; &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;  // Encoderzustand 0..3 &lt;/span&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0, 136, 136); font-weight: bold;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0, 119, 68); font-weight: bold;&quot;&gt;uint8_t&lt;/span&gt; enc_accel = &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;0&lt;/span&gt;;   &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// speichert die aktuelle Beschleunigung&lt;/span&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0, 119, 68); font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 119, 68); font-weight: bold;&quot;&gt;int16_t&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 119, 68); font-weight: bold;&quot;&gt;&lt;/span&gt;   p;                    &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// (position) lokale Variable für Positionsberechnung&lt;/span&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0, 119, 68); font-weight: bold;&quot;&gt;int8_t&lt;/span&gt;    m = &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;0&lt;/span&gt;;                &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// (moved) lokale Variable für Bewegungsberechnung&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0, 136, 0); font-weight: bold;&quot;&gt;if&lt;/span&gt;( enc_accel&lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;&lt;/span&gt; ) enc_accel--;    &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// solange &amp;gt;0: pro ms um 1 &amp;quot;entschleunigen&amp;quot; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0, 136, 0); font-weight: bold;&quot;&gt;if&lt;/span&gt;( PHASE_A ) m = &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;1&lt;/span&gt;;            &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// Gray nach binär wandeln&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;&lt;/span&gt;    &lt;span style=&quot;color: rgb(0, 136, 0); font-weight: bold;&quot;&gt;if&lt;/span&gt;( PHASE_B ) m ^= &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;3&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    m -= enc_ab;                     &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// berechnen, ob sich der Encoder bewegt hat&lt;/span&gt;&lt;br /&gt;                                     &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// gültige Werte für Differenz (m): -1, 0, +1 &lt;/span&gt;&lt;br /&gt;                                     &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// sonst ist die Abtastfrequenz zu niedrig!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0, 136, 0); font-weight: bold;&quot;&gt;if&lt;/span&gt;( moved ) {                    &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// Positionsänderung am Encoder?&lt;/span&gt;&lt;br /&gt;        enc_ab += m;                &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt; // Encoderzustand speichern&lt;/span&gt;&lt;br /&gt;        p = enc_pos;                 &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// nicht auf globaler Variable (enc_pos) herumrechnen&lt;/span&gt;        &lt;br /&gt;        &lt;span style=&quot;color: rgb(0, 136, 0); font-weight: bold;&quot;&gt;if&lt;/span&gt; (enc_accel&amp;lt;&lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;255&lt;/span&gt;-DYNAMIK)   &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// neuen Beschleunigungswert berechnen:&lt;/span&gt;            &lt;br /&gt;            enc_accel += DYNAMIK;    &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// solange &amp;lt;255 Beschleunigungswert aufaddieren&lt;/span&gt;&lt;br /&gt;        &lt;span style=&quot;color: rgb(0, 136, 0); font-weight: bold;&quot;&gt;else&lt;/span&gt;                         &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// sonst&lt;/span&gt;&lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt; &lt;/span&gt;            &lt;br /&gt;            enc_accel = &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;255&lt;/span&gt;;         &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// auf 255 begrenzen&lt;/span&gt;  &lt;br /&gt;        &lt;span style=&quot;color: rgb(0, 136, 0); font-weight: bold;&quot;&gt;if&lt;/span&gt; (i&amp;amp;&lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;2&lt;/span&gt;)                     &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// Bit 1 = Vorzeichen = Richtung (+/-)&lt;/span&gt;            &lt;br /&gt;            p += &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;1&lt;/span&gt;+(enc_accel&amp;gt;&amp;gt;&lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;6&lt;/span&gt;); &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;&lt;/span&gt;  &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// Erst Beschleunigungswerte &amp;gt;64 (wegen &amp;gt;&amp;gt;6)  &lt;/span&gt;        &lt;br /&gt;        &lt;span style=&quot;color: rgb(0, 136, 0); font-weight: bold;&quot;&gt;else&lt;/span&gt;                         &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// &lt;/span&gt;&lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;werden &lt;/span&gt;&lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;berücksichtigt. &lt;/span&gt;            &lt;br /&gt;            p -= &lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;1&lt;/span&gt;+(enc_accel&amp;gt;&amp;gt;&lt;span style=&quot;color: rgb(0, 0, 221); font-weight: bold;&quot;&gt;6&lt;/span&gt;); &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;  // Diese Division (Shift 6) evtl. anpassen...&lt;/span&gt;        &lt;br /&gt;        enc_pos = p;                 &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// lokale Variable auf globale Variable zurückkopieren&lt;br /&gt; &lt;/span&gt;    }&lt;br /&gt;    :&lt;br /&gt;    &lt;span style=&quot;color: rgb(136, 136, 136);&quot;&gt;// ab hier kommt sonstiger Code im Timerinterrupt&lt;/span&gt;   &lt;br /&gt;}&lt;/pre&gt;&lt;hr width=&quot;100%&quot; size=&quot;2&quot; /&gt;&lt;p&gt; Im Beispiel sind die beiden Spuren an den Portpins 1 und 2 vom Port A angeschlossen. Mit dem &lt;b&gt;&lt;i&gt;#define DYNAMIK&lt;/i&gt;&lt;/b&gt; lässt sich der &amp;quot;Biss&amp;quot;, also die Beschleunigung einstellen. Leider funktioniert das z.B. mit den billigen Pollin-Encodern nur eingeschränkt, weil die pro Raste zwei Schritte machen. Also ist da etwas Spielen und Ausprobieren mit dem Wert angesagt. Ich habe noch jedesmal einen brauchbaren Wert gefunden. Mit einem &lt;b&gt;&lt;i&gt;uint16_t&lt;/i&gt;&lt;/b&gt; für &lt;b&gt;&lt;i&gt;enc_accel&lt;/i&gt;&lt;/b&gt; kann der Dynamikbereich wesentlich ausgeweitet werden.&lt;br /&gt;&lt;br /&gt;Die Umwandlung vom Gray- in den Binärcode erfolgt mit dem XOR Verfahren wie auf &lt;a title=&quot;Umwandlung Graycode&quot; href=&quot;http://www.lothar-miller.de/s9y/categories/53-Graycode&quot;&gt;Software/Graycode&lt;/a&gt; im letzten Beispiel beschrieben.&lt;/p&gt;


 
    </content:encoded>

    <pubDate>Fri, 12 Mar 2010 12:56:02 +0100</pubDate>
    <guid isPermaLink="false">http://www.lothar-miller.de/s9y/archives/71-guid.html</guid>
    
</item>

</channel>
</rss>
