Interface the RenBed with a simple optical linear encoder, using X1 encoding.

Dependencies:   SevenSegmentDisplay mbed

This is an example of a copper strip-board design for an optical linear encoder (IRED), and how it is wired up to the Renbed on a breadboard:

/media/uploads/elijahorr/encoderwiring.png

The trimmer potentiometer is used to vary the current through the IRED LEDs, in order to balance out the two output signals.

Committer:
elijahorr
Date:
Mon Sep 05 13:17:15 2016 +0000
Revision:
0:c71cc517659b
Child:
1:83e238178956
rev 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elijahorr 0:c71cc517659b 1 #include "mbed.h"
elijahorr 0:c71cc517659b 2 #include "SevenSegmentDisplay.h"
elijahorr 0:c71cc517659b 3
elijahorr 0:c71cc517659b 4 // define values for high and low analog signals, used to compare to ADC values. 0.56 indicates that the low level is set to 56% of 3.3V.
elijahorr 0:c71cc517659b 5 #define SIGNAL_LOW 0.56
elijahorr 0:c71cc517659b 6 #define SIGNAL_HIGH 0.60
elijahorr 0:c71cc517659b 7
elijahorr 0:c71cc517659b 8 class Encoder{
elijahorr 0:c71cc517659b 9 public:
elijahorr 0:c71cc517659b 10
elijahorr 0:c71cc517659b 11 /****************************************************************************************************************
elijahorr 0:c71cc517659b 12 * Encoder - class constructor, used to declare an instant of the Encoder class. *
elijahorr 0:c71cc517659b 13 * *
elijahorr 0:c71cc517659b 14 * Parameters: PinA - analog channel A, PinB - analog channel B, OutputA - digital output for channel A, *
elijahorr 0:c71cc517659b 15 * OutputB - digital output for channel B, InputA - input for the feedback of digital channel A, *
elijahorr 0:c71cc517659b 16 * InputB - input for the feedback of digital channel B *
elijahorr 0:c71cc517659b 17 * *
elijahorr 0:c71cc517659b 18 * Returns: none *
elijahorr 0:c71cc517659b 19 ****************************************************************************************************************/
elijahorr 0:c71cc517659b 20 Encoder(PinName pinA, PinName pinB, PinName OutputA, PinName OutputB, PinName InputA, PinName InputB) :
elijahorr 0:c71cc517659b 21 SignalA(pinA), SignalB(pinB), SquaredA(OutputA), SquaredB(OutputB), SquaredA_in(InputA), SquaredB_in(InputB){
elijahorr 0:c71cc517659b 22
elijahorr 0:c71cc517659b 23 //attach ADC function to ticker, will be called every 75 microseconds (pretty much as often as possible)
elijahorr 0:c71cc517659b 24 ProcessCycle.attach_us(this, &Encoder::ConvertSignals, 75);
elijahorr 0:c71cc517659b 25 //attach rising_A function to rising edge interrupt on the feedback signal for digital channel A
elijahorr 0:c71cc517659b 26 SquaredA_in.rise(this, &Encoder::rising_A);
elijahorr 0:c71cc517659b 27 //attach falling_A function to falling edge interrupt on the feedback signal for digital channel B
elijahorr 0:c71cc517659b 28 SquaredA_in.fall(this, &Encoder::falling_A);
elijahorr 0:c71cc517659b 29 }
elijahorr 0:c71cc517659b 30
elijahorr 0:c71cc517659b 31 /*******************************************************************************
elijahorr 0:c71cc517659b 32 * get_count - returns the current encoder counter value
elijahorr 0:c71cc517659b 33 *
elijahorr 0:c71cc517659b 34 * Parameters: none
elijahorr 0:c71cc517659b 35 *
elijahorr 0:c71cc517659b 36 * Returns: int - current counter value
elijahorr 0:c71cc517659b 37 *******************************************************************************/
elijahorr 0:c71cc517659b 38 int get_count(void){
elijahorr 0:c71cc517659b 39 return count;
elijahorr 0:c71cc517659b 40 }
elijahorr 0:c71cc517659b 41
elijahorr 0:c71cc517659b 42 private:
elijahorr 0:c71cc517659b 43 AnalogIn SignalA; //analog input for signal A
elijahorr 0:c71cc517659b 44 AnalogIn SignalB; //analog input for signal B
elijahorr 0:c71cc517659b 45 DigitalOut SquaredA; //digital output for the digital translation of channel A
elijahorr 0:c71cc517659b 46 DigitalOut SquaredB; //digital output for the digital translation of channel B
elijahorr 0:c71cc517659b 47 InterruptIn SquaredA_in; //interrupt for the feedback of digital channel A signal
elijahorr 0:c71cc517659b 48 InterruptIn SquaredB_in; //interrupt for the feedback of digital channel B signal
elijahorr 0:c71cc517659b 49 Ticker ProcessCycle; //ticker to attach signal converter function to
elijahorr 0:c71cc517659b 50
elijahorr 0:c71cc517659b 51 int count; //variable to store counter value
elijahorr 0:c71cc517659b 52
elijahorr 0:c71cc517659b 53 /*******************************************************************************
elijahorr 0:c71cc517659b 54 * ConvertSignals - converts the analog signals from the encoder into digital
elijahorr 0:c71cc517659b 55 * quadrature signals.
elijahorr 0:c71cc517659b 56 *
elijahorr 0:c71cc517659b 57 * Parameters: none
elijahorr 0:c71cc517659b 58 *
elijahorr 0:c71cc517659b 59 * Returns: none
elijahorr 0:c71cc517659b 60 *******************************************************************************/
elijahorr 0:c71cc517659b 61 void ConvertSignals(void){
elijahorr 0:c71cc517659b 62
elijahorr 0:c71cc517659b 63 //take readings from the ADC
elijahorr 0:c71cc517659b 64 float A_reading = SignalA;
elijahorr 0:c71cc517659b 65 float B_reading = SignalB;
elijahorr 0:c71cc517659b 66
elijahorr 0:c71cc517659b 67 //decision algorithm to decide when to set the digital signals high/low,
elijahorr 0:c71cc517659b 68 //SIGNAL_LOW and SIGNAL_HIGH are user defined high and low for the analog signals
elijahorr 0:c71cc517659b 69 if(A_reading < SIGNAL_LOW){
elijahorr 0:c71cc517659b 70 SquaredA = 0;
elijahorr 0:c71cc517659b 71 }
elijahorr 0:c71cc517659b 72 else if(A_reading > SIGNAL_HIGH){
elijahorr 0:c71cc517659b 73 SquaredA = 1;
elijahorr 0:c71cc517659b 74 }
elijahorr 0:c71cc517659b 75
elijahorr 0:c71cc517659b 76 if(B_reading < SIGNAL_LOW){
elijahorr 0:c71cc517659b 77 SquaredB = 0;
elijahorr 0:c71cc517659b 78 }
elijahorr 0:c71cc517659b 79 else if(B_reading > SIGNAL_HIGH){
elijahorr 0:c71cc517659b 80 SquaredB = 1;
elijahorr 0:c71cc517659b 81 }
elijahorr 0:c71cc517659b 82 }
elijahorr 0:c71cc517659b 83
elijahorr 0:c71cc517659b 84 /*******************************************************************************
elijahorr 0:c71cc517659b 85 * rising_A - interrupt function for rising edges on channel A, decides when
elijahorr 0:c71cc517659b 86 * the count should be decremented.
elijahorr 0:c71cc517659b 87 *
elijahorr 0:c71cc517659b 88 * Parameters: none
elijahorr 0:c71cc517659b 89 *
elijahorr 0:c71cc517659b 90 * Returns: none
elijahorr 0:c71cc517659b 91 *******************************************************************************/
elijahorr 0:c71cc517659b 92
elijahorr 0:c71cc517659b 93 void rising_A(void){
elijahorr 0:c71cc517659b 94 if(SquaredB.read() == 0){
elijahorr 0:c71cc517659b 95 count--;
elijahorr 0:c71cc517659b 96 }
elijahorr 0:c71cc517659b 97 }
elijahorr 0:c71cc517659b 98
elijahorr 0:c71cc517659b 99 /*******************************************************************************
elijahorr 0:c71cc517659b 100 * falling_A - interrupt function for rising edges on channel A, decides when
elijahorr 0:c71cc517659b 101 * the count should be incremented.
elijahorr 0:c71cc517659b 102 *
elijahorr 0:c71cc517659b 103 * Parameters: none
elijahorr 0:c71cc517659b 104 *
elijahorr 0:c71cc517659b 105 * Returns: none
elijahorr 0:c71cc517659b 106 *******************************************************************************/
elijahorr 0:c71cc517659b 107
elijahorr 0:c71cc517659b 108 void falling_A(void){
elijahorr 0:c71cc517659b 109 if(SquaredB.read() == 0){
elijahorr 0:c71cc517659b 110 count++;
elijahorr 0:c71cc517659b 111 }
elijahorr 0:c71cc517659b 112 }
elijahorr 0:c71cc517659b 113
elijahorr 0:c71cc517659b 114 };
elijahorr 0:c71cc517659b 115
elijahorr 0:c71cc517659b 116 /* Create an instance of the class Encoder, which will be called lollipop (because of the lolly stick height control).
elijahorr 0:c71cc517659b 117 * Pins must be given in the order specified in the constructor, and analog inputs must be ADC pins */
elijahorr 0:c71cc517659b 118 Encoder lollipop(P0_15, P0_22, P0_17, P0_7, P1_14, P0_1);
elijahorr 0:c71cc517659b 119 SevenSegmentDisplay display(INSTANT); //create instance of SevenSegmentDisplay to drive the 7 segs
elijahorr 0:c71cc517659b 120
elijahorr 0:c71cc517659b 121 /*******************************************************************************
elijahorr 0:c71cc517659b 122 * main - this is the main program routine. The encoder class is working in the
elijahorr 0:c71cc517659b 123 * background, as the constructor was called above.
elijahorr 0:c71cc517659b 124 *
elijahorr 0:c71cc517659b 125 * Parameters: none
elijahorr 0:c71cc517659b 126 *
elijahorr 0:c71cc517659b 127 * Returns: none
elijahorr 0:c71cc517659b 128 *******************************************************************************/
elijahorr 0:c71cc517659b 129 int main(){
elijahorr 0:c71cc517659b 130 //a while loop with the parameter 1 will always execute, and repeat forever
elijahorr 0:c71cc517659b 131 while(1){
elijahorr 0:c71cc517659b 132 int counter = lollipop.get_count(); //get the current encoder count value
elijahorr 0:c71cc517659b 133
elijahorr 0:c71cc517659b 134 // if the counter value is positive, seperate into individual digits and drive displays
elijahorr 0:c71cc517659b 135 if(counter >= 0){
elijahorr 0:c71cc517659b 136 display.FadeMode(INSTANT);
elijahorr 0:c71cc517659b 137 int first_digit = counter/10;
elijahorr 0:c71cc517659b 138 int second_digit = counter%10;
elijahorr 0:c71cc517659b 139 display.DisplayDigits(first_digit, second_digit);
elijahorr 0:c71cc517659b 140 }
elijahorr 0:c71cc517659b 141 //if the counter value is negative, make the display flash while displaying value
elijahorr 0:c71cc517659b 142 else if(counter < 0){
elijahorr 0:c71cc517659b 143 display.FadeMode(FLASH);
elijahorr 0:c71cc517659b 144 display.FlashRate(500);
elijahorr 0:c71cc517659b 145 counter = counter*-1;
elijahorr 0:c71cc517659b 146 int first_digit = counter/10;
elijahorr 0:c71cc517659b 147 int second_digit = counter%10;
elijahorr 0:c71cc517659b 148 display.DisplayDigits(first_digit, second_digit);
elijahorr 0:c71cc517659b 149 }
elijahorr 0:c71cc517659b 150 wait(0.2);
elijahorr 0:c71cc517659b 151 }
elijahorr 0:c71cc517659b 152 }
elijahorr 0:c71cc517659b 153