Example of interrupt driven Rotary Encoder interface using ISC3806-003G-1024BZ1-5L Rotary Encoder
Dependencies: BufferedSerial mbed
main.cpp@0:545775417e0d, 2016-03-22 (annotated)
- Committer:
- JonFreeman
- Date:
- Tue Mar 22 16:17:12 2016 +0000
- Revision:
- 0:545775417e0d
Simple example showing how to interface a rotary encoder using interrupt driven code
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JonFreeman | 0:545775417e0d | 1 | #include "mbed.h" |
JonFreeman | 0:545775417e0d | 2 | #include "BufferedSerial.h" |
JonFreeman | 0:545775417e0d | 3 | |
JonFreeman | 0:545775417e0d | 4 | // Interface to Rotary Encoder type IOSC3806-003G-1024BZ1-5L |
JonFreeman | 0:545775417e0d | 5 | InterruptIn rcA (PB_6); // Coder provides A and B quadrature outputs and a once-per-rev index position pulse (signal Z) |
JonFreeman | 0:545775417e0d | 6 | InterruptIn rcB (PA_6); // These three signals wired to inputs configured to cause CPU interrupt on every level transition |
JonFreeman | 0:545775417e0d | 7 | InterruptIn rcZ (PA_7); |
JonFreeman | 0:545775417e0d | 8 | DigitalOut led_grn (LED1); // green led on ST Nucleo board set to flash to prove system alive |
JonFreeman | 0:545775417e0d | 9 | BufferedSerial pc(USBTX, USBRX); // serial port via usb used to display output on pc using TTY terminal e.g. PuTTY |
JonFreeman | 0:545775417e0d | 10 | |
JonFreeman | 0:545775417e0d | 11 | volatile bool trigger_200ms = false; |
JonFreeman | 0:545775417e0d | 12 | |
JonFreeman | 0:545775417e0d | 13 | Ticker toggleTick; // turns led on / off @ 1Hz, provides visual check of cpu running |
JonFreeman | 0:545775417e0d | 14 | |
JonFreeman | 0:545775417e0d | 15 | int seconds = 0; |
JonFreeman | 0:545775417e0d | 16 | |
JonFreeman | 0:545775417e0d | 17 | void ledToggler(void) { // Interrupt handler - led on half sec, off half sec, repeat |
JonFreeman | 0:545775417e0d | 18 | led_grn = !led_grn; |
JonFreeman | 0:545775417e0d | 19 | if (led_grn) |
JonFreeman | 0:545775417e0d | 20 | seconds++; // counts up once per second |
JonFreeman | 0:545775417e0d | 21 | } |
JonFreeman | 0:545775417e0d | 22 | |
JonFreeman | 0:545775417e0d | 23 | void twohundredms_handler () { |
JonFreeman | 0:545775417e0d | 24 | trigger_200ms = true; |
JonFreeman | 0:545775417e0d | 25 | } |
JonFreeman | 0:545775417e0d | 26 | |
JonFreeman | 0:545775417e0d | 27 | signed long angle = 0, turns = 0; |
JonFreeman | 0:545775417e0d | 28 | |
JonFreeman | 0:545775417e0d | 29 | void rcArise_handler () { // Handler of 'A' rising edge interrupts |
JonFreeman | 0:545775417e0d | 30 | if (rcB) angle++; |
JonFreeman | 0:545775417e0d | 31 | else angle--; |
JonFreeman | 0:545775417e0d | 32 | } |
JonFreeman | 0:545775417e0d | 33 | |
JonFreeman | 0:545775417e0d | 34 | void rcAfall_handler () { // Handler of 'A' falling edge interrupts |
JonFreeman | 0:545775417e0d | 35 | if (rcB) angle--; |
JonFreeman | 0:545775417e0d | 36 | else angle++; |
JonFreeman | 0:545775417e0d | 37 | } |
JonFreeman | 0:545775417e0d | 38 | |
JonFreeman | 0:545775417e0d | 39 | void rcBrise_handler () { // Handler of 'B' rising edge interrupts |
JonFreeman | 0:545775417e0d | 40 | if (rcA) angle--; |
JonFreeman | 0:545775417e0d | 41 | else angle++; |
JonFreeman | 0:545775417e0d | 42 | } |
JonFreeman | 0:545775417e0d | 43 | |
JonFreeman | 0:545775417e0d | 44 | void rcBfall_handler () { // Handler of 'B' falling edge interrupts |
JonFreeman | 0:545775417e0d | 45 | if (rcA) angle++; |
JonFreeman | 0:545775417e0d | 46 | else angle--; |
JonFreeman | 0:545775417e0d | 47 | } |
JonFreeman | 0:545775417e0d | 48 | |
JonFreeman | 0:545775417e0d | 49 | void rcZrise_handler () { // Index pulse interrupt handler, |
JonFreeman | 0:545775417e0d | 50 | if (rcA) { // keeps count of whole turns of the shaft |
JonFreeman | 0:545775417e0d | 51 | turns--; |
JonFreeman | 0:545775417e0d | 52 | } |
JonFreeman | 0:545775417e0d | 53 | else { |
JonFreeman | 0:545775417e0d | 54 | turns++; |
JonFreeman | 0:545775417e0d | 55 | } |
JonFreeman | 0:545775417e0d | 56 | angle = 0; |
JonFreeman | 0:545775417e0d | 57 | } |
JonFreeman | 0:545775417e0d | 58 | void rcZfall_handler () { } |
JonFreeman | 0:545775417e0d | 59 | |
JonFreeman | 0:545775417e0d | 60 | |
JonFreeman | 0:545775417e0d | 61 | int main() |
JonFreeman | 0:545775417e0d | 62 | { |
JonFreeman | 0:545775417e0d | 63 | int c_5 = 0; |
JonFreeman | 0:545775417e0d | 64 | toggleTick.attach(&ledToggler, 0.5f); // set interrupt handler to toggle led |
JonFreeman | 0:545775417e0d | 65 | Ticker tick200ms; |
JonFreeman | 0:545775417e0d | 66 | tick200ms.attach_us(&twohundredms_handler, 200000); // cause timer interrupts at 5Hz |
JonFreeman | 0:545775417e0d | 67 | |
JonFreeman | 0:545775417e0d | 68 | rcA.mode (PullUp); // Attach pullup resistors to the 3 coder outputs |
JonFreeman | 0:545775417e0d | 69 | rcB.mode (PullUp); |
JonFreeman | 0:545775417e0d | 70 | rcZ.mode (PullUp); |
JonFreeman | 0:545775417e0d | 71 | rcA.rise (&rcArise_handler); // Identify interrupt handlers for each of rise and fall |
JonFreeman | 0:545775417e0d | 72 | rcA.fall (&rcAfall_handler); // events on all three input lines |
JonFreeman | 0:545775417e0d | 73 | rcB.rise (&rcBrise_handler); |
JonFreeman | 0:545775417e0d | 74 | rcB.fall (&rcBfall_handler); |
JonFreeman | 0:545775417e0d | 75 | rcZ.rise (&rcZrise_handler); |
JonFreeman | 0:545775417e0d | 76 | rcZ.fall (&rcZfall_handler); |
JonFreeman | 0:545775417e0d | 77 | |
JonFreeman | 0:545775417e0d | 78 | pc.baud (115200); |
JonFreeman | 0:545775417e0d | 79 | pc.printf ("Jon's rotary encoder test sytem starting up\r\n"); |
JonFreeman | 0:545775417e0d | 80 | |
JonFreeman | 0:545775417e0d | 81 | // Main loop |
JonFreeman | 0:545775417e0d | 82 | while(1) { // loop forever |
JonFreeman | 0:545775417e0d | 83 | pc.printf ("Turns %+d\t%+.1f degree\r\n", turns, (double)angle * 360.0 / 2048.0); |
JonFreeman | 0:545775417e0d | 84 | |
JonFreeman | 0:545775417e0d | 85 | c_5++; |
JonFreeman | 0:545775417e0d | 86 | if(c_5 > 4) |
JonFreeman | 0:545775417e0d | 87 | { // Can do stuff once per second here |
JonFreeman | 0:545775417e0d | 88 | c_5 = 0; |
JonFreeman | 0:545775417e0d | 89 | } |
JonFreeman | 0:545775417e0d | 90 | while (!trigger_200ms) ;// NEARLY ALL CPU TIME WASTED HERE waiting for interrupt handler to set trigger_200 true |
JonFreeman | 0:545775417e0d | 91 | trigger_200ms = false; // Hence main loop is cycled every 200ms |
JonFreeman | 0:545775417e0d | 92 | } |
JonFreeman | 0:545775417e0d | 93 | } |