Rotary Encoder confusion

I'm a complete noob, this is my first project ever.

My goal is to emulate the UP & DOWN keys from a standard keyboard (to control a separate device) with a rotary encoder.

I'm using this sketch & hardware from a Youtube video- Midi controller | Premiere Pro | Lightroom | Navigation Dial DIY (NEW) | Video Edit Jog Wheel USB - YouTube

It's a rotary encoder & ATmega32u4 board for manipulating the arrow keys on a keyboard.

The project works perfectly on my PC, but doesn't work to control my device. But, if I plug in a keyboard to my device, it work perfectly....confusing.

I would appreciate any guidance or insight.

Thanks!

Here is the code-

// Youtube : Eunchan Park
// https://www.youtube.com/watch?v=dJJ1wlJPqwE

// left right
// up down
// everytime you clicks button, it changes arrow direction from horizontal to vertical

// Resolution : some encoder is too sensitive. this reduces sensitivity.
#define RESOLUTION 4

// include a Keyboard library
#include "Keyboard.h"

// include a EEPROM library for memorizing last function
#include <EEPROM.h>


// "OUTPUT_A" is going to be replaced with "A0".
#define  OUTPUT_A 2

// "PIN_GND_ENCODER" is going to be replaced with "3".
#define PIN_GND_ENCODER  3

// "OUTPUT_B" is going to be replaced with "15".
#define  OUTPUT_B 4

// "BUTTON" is going to be replaced with "A1".
#define  BUTTON A1

// "PIN_GND_BUTTON" is going to be replaced with "A3".
#define PIN_GND_BUTTON  A3

// Declare variables aState, aLastState for checking the state of OUTPUT_A of the encoder
bool aState;

// We need to save the previous state of OUTPUT_A
bool aLastState;

// this variable for check the state of button.
bool lastButtonState = 0;

// mode selection
#define HORIZONTAL_MODE 0
#define VERTICAL_MODE 1

int mode = HORIZONTAL_MODE;
const int numMode = 2;

// void setup(){} function is for one time setting
void setup() {

  //read the last mode
  mode = EEPROM.read(0);

  // in order to use the Keyboard library, begin() is necessary
  Keyboard.begin();

  // OUTPUT_A is for INPUT. must be pull-up
  pinMode(OUTPUT_A, INPUT_PULLUP);

  // OUTPUT_B is for INPUT, must be pull-up
  pinMode(OUTPUT_B, INPUT_PULLUP);

  // BUTTON is for INPUT
  // Most pin has thier own pull-up resistor.
  // INPUT_PULLUP makes the pin high.
  // a leg of button is connected with this pin and another pin which is grounded.
  // when the button is not pressed, the pin reads HIGH signal because of this PULL-UP
  // when the button is pressed, pin is going to be LOW which means "pressed"
  pinMode(BUTTON, INPUT_PULLUP);

  // PIN_GND_ENCODER is for OUTPUT
  // This pin is used for giving GROUND to the encoder.
  // this is a kind of trick, but it works well.
  pinMode(PIN_GND_ENCODER, OUTPUT);
  digitalWrite(PIN_GND_ENCODER, LOW);

  // PIN_GND_BUTTON is for OUTPUT
  // This pin is used for giving GND to the button.
  // this is a kind of trick, but it works well.
  pinMode(PIN_GND_BUTTON, OUTPUT);
  digitalWrite(PIN_GND_BUTTON, LOW);

  // read a signal from OUTPUT_A
  // this is for initialization
  aLastState = digitalRead(OUTPUT_A);
}

long tempCount = 0;

// this loop() function repeats its code eternally
void loop() {

  //read signal from OUTPUT_A and save its state to aState
  aState = digitalRead(OUTPUT_A);

  // if aLastState is not currentState, it meant there's something changed.
  if (aState != aLastState) {

    // read another pin's state.
    // if you want to know about the theory, watch this video
    // https://www.youtube.com/watch?v=v4BbSzJ-hz4
    if (digitalRead(OUTPUT_B) != aState) {
      rotateLeft();
    } else {
      rotateRight();
    }
    // save current State as last State
    aLastState = aState;
  }

  // read button (short or long)
  if (digitalRead(BUTTON) == LOW) {
    if (lastButtonState == LOW) {
      // LOW -> LOW : nothing to do
    } else {
      // HIGH-> LOW
      delay(300); // ignoring chattering
    }
    lastButtonState = LOW;
  } else {
    if (lastButtonState == LOW) {   // LOW -> HIGH : check whether long press or not
      changeMode();
    }
    else {                          // HIGH -> HIGH : noting to do
    }
    lastButtonState = HIGH;
  }
}

void changeMode() {
  mode = ++mode % numMode;
  EEPROM.write(0, mode);
}

void rotateLeft() {
  if (tempCount++ % RESOLUTION == 0) {
    if (mode == HORIZONTAL_MODE ) {
      Keyboard.press(KEY_LEFT_ARROW);
    } else if (mode == VERTICAL_MODE) {
      Keyboard.press(KEY_UP_ARROW);
    }
    Keyboard.releaseAll();
  }
}

void rotateRight() {
  if (tempCount++ % RESOLUTION == 0) {
    if (mode == HORIZONTAL_MODE) {
      Keyboard.press(KEY_RIGHT_ARROW);
    } else if (mode == VERTICAL_MODE) {
      Keyboard.press(KEY_DOWN_ARROW);
    }
    Keyboard.releaseAll();
  }
{

Please describe the nature and intended use of your "rotary encoder", without reference to a video. I assume that your rotary encoder is different from those used to determine motor speed or position.

When the rotary encoder is turned clockwise, each detent = 1 press of the UP KEY on a keyboard. Anticlockwise = 1 press of the DOWN KEY.

Thanks for helping!

DrDiettrich:
Please describe the nature and intended use of your "rotary encoder", without reference to a video. I assume that your rotary encoder is different from those used to determine motor speed or position.

Nice job with using the code tags on your first post.

The project works perfectly on my PC

What exactly does this mean?

but doesn't work to control my device. But, if I plug in a keyboard to my device, it work perfectly....confusing.
I would appreciate any guidance or insight.

Can you verify that the encoder rotation is calling rotateLeft() and rotateRight() at the detents. Can you see that with some Serial printing for debug.

Given what you have said, I'm more confused about the HID keyboard output from the Arduino than the encoder.

What is the device you are trying to control?

Thanks for replying.

cattledog:
Nice job with using the code tags on your first post.

What exactly does this mean?

The Arduino MicroPro & rotary encoder control the cursor on my computer (in the same way the UP & DOWN arrow keys on my keyboard work) And the UP & DOWN arrows on a keyboard control my device (sound recorder) exactly as needed. but, the encoder doesn't control my device.

Can you verify that the encoder rotation is calling rotateLeft() and rotateRight() at the detents. Can you see that with some Serial printing for debug.

Bear with me, I'm trying to figure out how to use Serial.Print to verify this.

Given what you have said, I'm more confused about the HID keyboard output from the Arduino than the encoder.

What is the device you are trying to control?

A sound recording device (Sound Devices MixPre 6)

The Arduino MicroPro & rotary encoder control the cursor on my computer (in the same way the UP & DOWN arrow keys on my keyboard work) And the UP & DOWN arrows on a keyboard control my device (sound recorder) exactly as needed. but, the encoder doesn't control my device.

This fellow also had troubles getting a MixPre6 to recognize the Arduino keyboard emulation.

Nice find, I'm a member of that group but hadn't seen that project.

I don't want/need to control, the transport of my recorder, I just want to control the headphone volume and mic input gain, which are easily controlled from a regular USB keyboard.

cattledog:
This fellow also had troubles getting a MixPre6 to recognize the Arduino keyboard emulation.

MixPre 6/LANC remote control project - Do It Yourself - JWSOUNDGROUP

1 Like