init

Dependencies:   PinDetect mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "PinDetect.h"
00003 //Lab 3 Part 1
00004 //See http://makeatronics.blogspot.com/2013/02/efficiently-reading-quadrature-with.html
00005 //for a detailed explanation of the RPG encoder counting algorithm
00006 //uses Sparkfun RPG with RGB led on breakout board (#15141,11722,10597)
00007 //place RPG PCB across a breadboard power bus strip for easier pin hookup!
00008 InterruptIn RPG_A(p14,PullUp);//encoder A and B pins/bits use interrupts
00009 InterruptIn RPG_B(p15,PullUp);
00010 PinDetect RPG_PB(p16); //encode pushbutton switch "SW" on PCB
00011 //PWM setup for RGB LED in enocder
00012 PwmOut red(p21);//"R" pin
00013 PwmOut blue(p23);//"G" pin
00014 PwmOut green(p22);//"B" pin
00015 //Note: also tie RPG PCB "C" pin to ground, "+" pin to 3.3
00016 //mbed status leds
00017 DigitalOut ledPB(LED1);
00018 DigitalOut red_adjust_mode(LED2);
00019 DigitalOut green_adjust_mode(LED3);
00020 DigitalOut blue_adjust_mode(LED4);
00021 //Serial pc(USBTX,USBRX);
00022 volatile int old_enc = 0;
00023 volatile int new_enc = 0;
00024 volatile int enc_count = 0;
00025 int current_state = 0;
00026 //Instead of a slow 16 case statement use a faster table lookup of truth table
00027 //index table with (previous encoder AB value<<2 | current current encoder AB value) 
00028 //to find -1(CCW),0,or 1(CW) change in count each time a bit changes state
00029 //Always want Interrupt routines to run fast!
00030 //const puts data in read only Flash instead of RAM
00031 const int lookup_table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
00032 //Encoder bit change interrupt service routine
00033 //called whenever one of the two A,B encoder bits change state
00034 void Enc_change_ISR(void)
00035 {
00036     new_enc = RPG_A<<1 | RPG_B;//current encoder bits
00037     //check truth table for -1,0 or +1 added to count
00038     enc_count = enc_count + lookup_table[old_enc<<2 | new_enc];
00039     old_enc = new_enc;
00040 }
00041 //debounced RPG pushbutton switch callback
00042 int state_change(void){
00043     return (current_state + 1) % 3;
00044 }
00045 void PB_callback(void)
00046 {
00047     if (!ledPB.read()) {
00048         current_state = state_change();
00049     }
00050     //ledPB= !ledPB;
00051 }
00052 int main()
00053 {
00054 //turn off built-in RPG encoder RGB led
00055     red = 1.0;//PWM value 1.0 is "off", 0.0 is full "on"
00056     green = 1.0;
00057     blue = 1.0;
00058 //current color adjust set to red
00059     red_adjust_mode = 1;
00060 //debounce RPG center pushbutton
00061     RPG_PB.mode(PullDown);
00062     RPG_PB.attach_deasserted(&PB_callback);
00063     RPG_PB.setSampleFrequency();
00064 // generate an interrupt on any change in either encoder bit (A or B)
00065     RPG_A.rise(&Enc_change_ISR);
00066     RPG_A.fall(&Enc_change_ISR);
00067     RPG_B.rise(&Enc_change_ISR);
00068     RPG_B.fall(&Enc_change_ISR);
00069     while (true) {
00070         // Scale/limit count to 0..100
00071         if (enc_count>100) enc_count = 100;
00072         if (enc_count<0) enc_count = 0;
00073         if (current_state == 0) {
00074             red = 1.0 - enc_count / 100.0;
00075         } else if (current_state == 1) {
00076             green = 1.0 - enc_count / 100.0;
00077         } else {
00078             blue = 1.0 - enc_count / 100;
00079         }
00080         //green = 1.0 - enc_count/100.0;
00081 //        pc.printf("%D\n\r",enc_count);
00082     }
00083 }
00084