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:
The trimmer potentiometer is used to vary the current through the IRED LEDs, in order to balance out the two output signals.
main.cpp
- Committer:
- elijahorr
- Date:
- 2016-09-05
- Revision:
- 0:c71cc517659b
- Child:
- 1:83e238178956
File content as of revision 0:c71cc517659b:
#include "mbed.h" #include "SevenSegmentDisplay.h" // 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. #define SIGNAL_LOW 0.56 #define SIGNAL_HIGH 0.60 class Encoder{ public: /**************************************************************************************************************** * Encoder - class constructor, used to declare an instant of the Encoder class. * * * * Parameters: PinA - analog channel A, PinB - analog channel B, OutputA - digital output for channel A, * * OutputB - digital output for channel B, InputA - input for the feedback of digital channel A, * * InputB - input for the feedback of digital channel B * * * * Returns: none * ****************************************************************************************************************/ Encoder(PinName pinA, PinName pinB, PinName OutputA, PinName OutputB, PinName InputA, PinName InputB) : SignalA(pinA), SignalB(pinB), SquaredA(OutputA), SquaredB(OutputB), SquaredA_in(InputA), SquaredB_in(InputB){ //attach ADC function to ticker, will be called every 75 microseconds (pretty much as often as possible) ProcessCycle.attach_us(this, &Encoder::ConvertSignals, 75); //attach rising_A function to rising edge interrupt on the feedback signal for digital channel A SquaredA_in.rise(this, &Encoder::rising_A); //attach falling_A function to falling edge interrupt on the feedback signal for digital channel B SquaredA_in.fall(this, &Encoder::falling_A); } /******************************************************************************* * get_count - returns the current encoder counter value * * Parameters: none * * Returns: int - current counter value *******************************************************************************/ int get_count(void){ return count; } private: AnalogIn SignalA; //analog input for signal A AnalogIn SignalB; //analog input for signal B DigitalOut SquaredA; //digital output for the digital translation of channel A DigitalOut SquaredB; //digital output for the digital translation of channel B InterruptIn SquaredA_in; //interrupt for the feedback of digital channel A signal InterruptIn SquaredB_in; //interrupt for the feedback of digital channel B signal Ticker ProcessCycle; //ticker to attach signal converter function to int count; //variable to store counter value /******************************************************************************* * ConvertSignals - converts the analog signals from the encoder into digital * quadrature signals. * * Parameters: none * * Returns: none *******************************************************************************/ void ConvertSignals(void){ //take readings from the ADC float A_reading = SignalA; float B_reading = SignalB; //decision algorithm to decide when to set the digital signals high/low, //SIGNAL_LOW and SIGNAL_HIGH are user defined high and low for the analog signals if(A_reading < SIGNAL_LOW){ SquaredA = 0; } else if(A_reading > SIGNAL_HIGH){ SquaredA = 1; } if(B_reading < SIGNAL_LOW){ SquaredB = 0; } else if(B_reading > SIGNAL_HIGH){ SquaredB = 1; } } /******************************************************************************* * rising_A - interrupt function for rising edges on channel A, decides when * the count should be decremented. * * Parameters: none * * Returns: none *******************************************************************************/ void rising_A(void){ if(SquaredB.read() == 0){ count--; } } /******************************************************************************* * falling_A - interrupt function for rising edges on channel A, decides when * the count should be incremented. * * Parameters: none * * Returns: none *******************************************************************************/ void falling_A(void){ if(SquaredB.read() == 0){ count++; } } }; /* Create an instance of the class Encoder, which will be called lollipop (because of the lolly stick height control). * Pins must be given in the order specified in the constructor, and analog inputs must be ADC pins */ Encoder lollipop(P0_15, P0_22, P0_17, P0_7, P1_14, P0_1); SevenSegmentDisplay display(INSTANT); //create instance of SevenSegmentDisplay to drive the 7 segs /******************************************************************************* * main - this is the main program routine. The encoder class is working in the * background, as the constructor was called above. * * Parameters: none * * Returns: none *******************************************************************************/ int main(){ //a while loop with the parameter 1 will always execute, and repeat forever while(1){ int counter = lollipop.get_count(); //get the current encoder count value // if the counter value is positive, seperate into individual digits and drive displays if(counter >= 0){ display.FadeMode(INSTANT); int first_digit = counter/10; int second_digit = counter%10; display.DisplayDigits(first_digit, second_digit); } //if the counter value is negative, make the display flash while displaying value else if(counter < 0){ display.FadeMode(FLASH); display.FlashRate(500); counter = counter*-1; int first_digit = counter/10; int second_digit = counter%10; display.DisplayDigits(first_digit, second_digit); } wait(0.2); } }