Example of interrupt driven Rotary Encoder interface using ISC3806-003G-1024BZ1-5L Rotary Encoder
Dependencies: BufferedSerial mbed
Revision 0:545775417e0d, committed 2016-03-22
- 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
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