Example of interrupt driven Rotary Encoder interface using ISC3806-003G-1024BZ1-5L Rotary Encoder
Dependencies: BufferedSerial mbed
Diff: main.cpp
- Revision:
- 0:545775417e0d
--- /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
+ }
+}