Example of interrupt driven Rotary Encoder interface using ISC3806-003G-1024BZ1-5L Rotary Encoder
Dependencies: BufferedSerial mbed
main.cpp
- Committer:
- JonFreeman
- Date:
- 2016-03-22
- Revision:
- 0:545775417e0d
File content as of revision 0:545775417e0d:
#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 } }