Example of interrupt driven Rotary Encoder interface using ISC3806-003G-1024BZ1-5L Rotary Encoder

Dependencies:   BufferedSerial mbed

Files at this revision

API Documentation at this revision

Comitter:
JonFreeman
Date:
Tue Mar 22 16:17:12 2016 +0000
Commit message:
Simple example showing how to interface a rotary encoder using interrupt driven code

Changed in this revision

BufferedSerial.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 545775417e0d BufferedSerial.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial.lib	Tue Mar 22 16:17:12 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/sam_grove/code/BufferedSerial/#a0d37088b405
diff -r 000000000000 -r 545775417e0d main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Mar 22 16:17:12 2016 +0000
@@ -0,0 +1,93 @@
+#include "mbed.h"
+#include "BufferedSerial.h"
+
+//  Interface to Rotary Encoder type IOSC3806-003G-1024BZ1-5L
+InterruptIn rcA     (PB_6);     //  Coder provides A and B quadrature outputs and a once-per-rev index position pulse (signal Z)
+InterruptIn rcB     (PA_6);     //  These three signals wired to inputs configured to cause CPU interrupt on every level transition
+InterruptIn rcZ     (PA_7);
+DigitalOut  led_grn     (LED1); //  green led on ST Nucleo board set to flash to prove system alive
+BufferedSerial pc(USBTX, USBRX);    //  serial port via usb used to display output on pc using TTY terminal e.g. PuTTY
+                    
+volatile    bool    trigger_200ms = false;
+
+Ticker  toggleTick;         //  turns led on / off @ 1Hz, provides visual check of cpu running
+
+int     seconds = 0;
+
+void ledToggler(void) { //  Interrupt handler - led on half sec, off half sec, repeat
+    led_grn = !led_grn;
+    if  (led_grn)
+        seconds++;  //  counts up once per second
+}
+
+void    twohundredms_handler    ()  {
+    trigger_200ms = true;
+}
+
+signed long angle = 0, turns = 0;
+
+void    rcArise_handler ()  {   //  Handler of 'A' rising edge interrupts
+    if  (rcB)   angle++;
+    else        angle--;
+}
+
+void    rcAfall_handler ()  {   //  Handler of 'A' falling edge interrupts
+    if  (rcB)   angle--;
+    else        angle++;
+}
+
+void    rcBrise_handler ()  {   //  Handler of 'B' rising edge interrupts   
+    if  (rcA)   angle--;
+    else        angle++;
+}
+
+void    rcBfall_handler ()  {   //  Handler of 'B' falling edge interrupts
+    if  (rcA)   angle++;
+    else        angle--;
+}
+
+void    rcZrise_handler ()  {   //  Index pulse interrupt handler,
+    if   (rcA)   {              //  keeps count of whole turns of the shaft
+        turns--;
+    }
+    else    {
+        turns++;
+    }
+    angle = 0;
+}
+void    rcZfall_handler ()  {   }
+
+
+int main()
+{
+    int     c_5 = 0;
+    toggleTick.attach(&ledToggler, 0.5f);   //  set interrupt handler to toggle led
+    Ticker  tick200ms;
+    tick200ms.attach_us(&twohundredms_handler, 200000); //  cause timer interrupts at 5Hz
+
+    rcA.mode  (PullUp);     //  Attach pullup resistors to the 3 coder outputs
+    rcB.mode  (PullUp);
+    rcZ.mode  (PullUp);
+    rcA.rise  (&rcArise_handler);   //  Identify interrupt handlers for each of rise and fall
+    rcA.fall  (&rcAfall_handler);   //  events on all three input lines
+    rcB.rise  (&rcBrise_handler);
+    rcB.fall  (&rcBfall_handler);
+    rcZ.rise  (&rcZrise_handler);
+    rcZ.fall  (&rcZfall_handler);
+
+    pc.baud (115200);
+    pc.printf   ("Jon's rotary encoder test sytem starting up\r\n");
+
+    //  Main loop
+    while(1) {  //  loop forever
+        pc.printf   ("Turns %+d\t%+.1f degree\r\n", turns, (double)angle * 360.0 / 2048.0);
+
+        c_5++;
+        if(c_5 > 4)
+        {               //  Can do stuff once per second here
+            c_5 = 0;
+        }
+        while   (!trigger_200ms)    ;//  NEARLY ALL CPU TIME WASTED HERE waiting for interrupt handler to set trigger_200 true
+        trigger_200ms = false;      //  Hence main loop is cycled every 200ms
+    }
+}
diff -r 000000000000 -r 545775417e0d mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Mar 22 16:17:12 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/87f2f5183dfb
\ No newline at end of file