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

Dependencies:   BufferedSerial mbed

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?

UserRevisionLine numberNew 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 }