Help with Leonardo & Rotary Optical Encoder

I have a manual pulse generator (quadrature encoder) I loaded the example code in Leonardo and got it working: /* Read Quadrature Encoder * Connect Encoder to Pins encoder0PinA, encoder0PinB, and +5V. * * Sketch by max wolf / www.meso.net * v. 0.1 - very basic functions - mw 20061220 * */

int val; int encoder0PinA = 3; int encoder0PinB = 4; int encoder0Pos = 0; int encoder0PinALast = LOW; int n = LOW;

void setup() { pinMode (encoder0PinA,INPUT); pinMode (encoder0PinB,INPUT); Serial.begin (9600); }

void loop() { n = digitalRead(encoder0PinA); if ((encoder0PinALast == LOW) && (n == HIGH)) { if (digitalRead(encoder0PinB) == LOW) { encoder0Pos--; } else { encoder0Pos++; } Serial.print (encoder0Pos); Serial.print ("/"); } encoder0PinALast = n; }

I have the code working with my Rotary Optical Encoder. Now what I need help and guidance with: I want to use a 4 position rotary switch to select an input in Leonardo. I want Leonardo to emulate a PC Keyboard that: When in position 1, every time I rotate the optical encoder in one direction, Leonardo will out put the PC Keyboard character RIGHT arrow when turned in the opposite direction, LEFT arrow for each pulse of the encoder When in position 2, every time I rotate the optical encoder in one direction, Leonardo will out put the PC Keyboard character UP arrow when turned in the opposite direction, DOWN arrow for each pulse of the encoder When in position 3, every time I rotate the optical encoder in one direction, Leonardo will out put the PC Keyboard character PAGE UP when turned in the opposite direction, PAGE DOWN for each pulse of the encoder When in position 4, every time I rotate the optical encoder in one direction, Leonardo will out put the PC Keyboard character + when turned in the opposite direction, - for each pulse of the encoder

I'd really appreciate some help and direction! I'm a newbie, and have impressed myself that I got this far. (I also understand to make Leonardo emulate a keyboard, I need to ground an input that will put Leonardo into keyboard emulation mode.

Thanks in advance! I hope this challenges someone. :-)

Marty

I made some progress. I have my rotary encoder now outputting the right arrow key press when turned to the right and left arrow key press when turned to the left.

int val; int encoder0PinA = 3; int encoder0PinB = 4; int encoder0Pos = 0; int encoder0PinALast = LOW; int n = LOW;

void setup() { pinMode (encoder0PinA,INPUT); pinMode (encoder0PinB,INPUT); pinMode (10, INPUT); //X Axis// pinMode (11, INPUT); //Y Axis// pinMode (12, INPUT); //Z Axis// pinMode (13, INPUT); //A Axis// Serial.begin (115200); }

void loop() { n = digitalRead(encoder0PinA); if ((encoder0PinALast == LOW) && (n == HIGH)) { if (digitalRead(encoder0PinB) == LOW) { encoder0Pos--; //if (digitalRead(10, HIGH)); Keyboard.write(215); } else { encoder0Pos++; Keyboard.write(216); } /** Serial.print (encoder0Pos); ** Serial.print ("/"); */ } encoder0PinALast = n; }


I added the 4 inputs to monitor at the top, 10, 11, 12 & 13 So depending one which is grounded, I need to change the keyboard press output. Can someone suggest how to do this? I thought IF digitalWrite (10,HIGH) then Keyboard.write(215); Would work but it doesn't I figured I would need 4 "statements" and depending on which input was low, then it would Keyboard.write(XXX)

Thanks again in advance Marty

I would suggest moving the encoder to pins 2 and 3 and using the pin-change interrupts to detect all transitions. Your current code will fail if the encoder moves faster than your main loop, which means you can never use delay ().

As for the rotary switch, I'm assuming it's a 1-pole, 4-throw? I would put a different value of resistor on each leg so that it forms a variable voltage divider. You can then measure the voltage at the common pin, which will tell you where the switch is. For example: - 10k from common to VCC - common connects to any analog pin, eg A1 - 0R from A to ground - 3k3 from B to ground - 10k from C to ground - 30k from D to ground.

That should give you readings of about 0, 250, 500 and 750 for switch positions A, B, C and D respectively; over 1000 when the knob is between settings.

Personally, I think using 2 digital pins would be more appropriate:

For example D3 and D4, D3 = 0, D4 = 0 case 1 D3 = 1, D4 = 0 case 2 D3 = 0, D4 = 1 case 3 D3 = 1, D4 = 1 case 4

Now just put switch case in loop() and add your specific coded between the cases and common code before/after the case.

Thanks for the suggestions. I tested my manual pulse generator (which is just a handwheel) I spun it pretty quickly and there did't seem to be any problem.

I'd like to keep it simple. My issue is I need suggestions/examples for the code. Something like IF input 1 is low then I use the same encoder inputs but then Keyboard.write(215) when the MPG is turned to the right and then Keyboard.write(216) if its turned to the left.

If input 2 or 3 or 4 is low then the two keyboard.write statements output different characters depending on which input is put low from the rotary switch.

I hope I am making some sense. Basically the operation of the Manual Pulse generator does not change but depending on which input is low will determine which pair of characters gets sent to the PC.

My problem is I can't find examples of the code syntax that does something similar to what I want to do.

Keep the ideas coming!

mrburnette: Personally, I think using 2 digital pins would be more appropriate:

For example D3 and D4, D3 = 0, D4 = 0 case 1 D3 = 1, D4 = 0 case 2 D3 = 0, D4 = 1 case 3 D3 = 1, D4 = 1 case 4

Now just put switch case in loop() and add your specific coded between the cases and common code before/after the case.

I would rather use the 4 individual inputs and just ground them. I have plenty of I/O and it simplifies the type of rotary switch I need to get. Can you give me examples of the code? This is my hangup right now. If all I needed to do was output the left and right arrow keyboard presses I would be done, but I need to use the same manual pulse generator/Leonardo to output 3 more pair of characters depending on which of the inputs are asserted to ground. I've spent hours on this project today and am happy to have gotten were I am, but now frustrated I can't find sample code similar to what I need to finish up. So close.... :)

Thanks! Marty