rotary encoder as a enviromental controller

I'm trying to build a multi media controller for vol and custom buttons functions and menu navigations open apps or jump from an app to another app with a rotary encoder with an Arduino micro with ATmega32u4

already got the vol work and 4 custom buttons works too im trying find the code sketch or somebody can guide on the right direction how to make the rotary encoder move from one app to another app

I'm really new programing i apologize if i bother somebody with my newbie question i attach the code that i used in the best of my knowledge thanks

I edited my post to make it right

[code]

#include <ClickEncoder.h>
#include <TimerOne.h>
#include <HID-Project.h>
#define ROTARY_D 14 
#define ROTARY_E 10
#define ROTARY_F 7
int buttonPina = 5;
int buttonPinb = 6;
int buttonPinc = 3;
int buttonPind = 2;

ClickEncoder *encoder; // variable representing the rotary encoder
int16_t last, value; // variables for current and last rotation value

void timerIsr() {
  encoder->service();
}

void setup() {
  Serial.begin(9600); // Opens the serial connection used for communication with the PC.
  Consumer.begin(); // Initializes the media keyboard
  Keyboard.begin();
  //Serial.write("Starting...\n")
  encoder = new ClickEncoder(ROTARY_D, ROTARY_E, ROTARY_F ); // Initializes the rotary encoder with the mentioned pins

  Timer1.initialize(1000); // Initializes the timer, which the rotary encoder uses to detect rotation
  Timer1.attachInterrupt(timerIsr);
  last = -1;
  pinMode(ROTARY_D,   INPUT_PULLUP);
  pinMode(ROTARY_E,   INPUT_PULLUP);
  pinMode(ROTARY_F,   INPUT_PULLUP);
  pinMode(buttonPina, INPUT_PULLUP);
  pinMode(buttonPinb, INPUT_PULLUP);
  pinMode(buttonPinc, INPUT_PULLUP);
  pinMode(buttonPind, INPUT_PULLUP);


}

void loop() {
  value += encoder->getValue();

  // This part of the code is responsible for the actions when you rotate the encoder
  if (value != last) { // New value is different than the last one, that means to encoder was rotated
    if (last < value) // Detecting the direction of rotation
      Keyboard.press(KEY_MINUS); // Replace this line to have a different function when rotating counter-clockwise
    Keyboard.releaseAll();
    delay(500);
  }
  else {
    Keyboard.press(KEY_LEFT_SHIFT); // Replace this line to have a different function when rotating clockwise
    Keyboard.press('+');
    Keyboard.releaseAll();
    delay(1000);
    last = value; // Refreshing the "last" varible for the next loop with the current value
    Serial.print("Encoder Value: "); // Text output of the rotation value used manily for debugging (open Tools - Serial Monitor to see it)
    Serial.println(value);
  }

  // This next part handles the rotary encoder BUTTON
  ClickEncoder::Button b = encoder->getButton(); // Asking the button for it's current state
  if (b != ClickEncoder::Open) { // If the button is unpressed, we'll skip to the end of this if block
    //Serial.print("Button: ");
    //#define VERBOSECASE(label) case label: Serial.println(#label); break;
    switch (b) {
      case ClickEncoder::Clicked: // Button was clicked once
        Consumer.write(MEDIA_PLAY_PAUSE); // Replace this line to have a different function when clicking button once
        break;

      case ClickEncoder::DoubleClicked: // Button was double clicked
        Consumer.write(MEDIA_NEXT); // Replace this line to have a different function when double-clicking
        break; {


        }

        delay(10); // Wait 10 milliseconds, we definitely don't need to detect the rotary encoder any faster than that
        // The end of the loop() function, it will start again from the beggining (the begginging of the loop function, not the whole document)

    }
    if (digitalRead(buttonPina))
    {
      Keyboard.write(KEY_F7);
    } else {
      Serial.println("A");
      delay(500);
    }
  }
  if (digitalRead(buttonPinb))
  {
    Keyboard.write(KEY_F7);
  } else {
    Serial.println("B");
    delay(500);
  }

  if (digitalRead(buttonPinc))
  {
    Keyboard.write(KEY_F7);
  } else {
    Serial.println("C");
    delay(500);
  }


  if (digitalRead(buttonPind))
  {
    Keyboard.write(KEY_F7);
  } else {
    Serial.println("D");
    delay(500);
  }
}

[/code]

You should post code by using code-tags
There is an automatic function for doing this inthe Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy to forum"
  3. paste clipboard into write-window of a posting

I have never done something with the USB-libraries.
There has to be some kind of documentation about the available key-constants

you have some if-conditions

 if (millis() + 5 > t)

millis() is a millisecond-counter that starts counting up at 0 and counts up to 4 billions
you initialise t = 0
this means
millis() + 5 will be always greater than zero
the condition is always and immetiately true

if it works this way you could just delete the if-condition

you increment / decrement variable n but make not use of the variable

For adding more keys:
So if I were you I would search for this list of keys-constants

the only thing that might bother other users is to refuse making progress in understanding programming.

Take a look into this tutorial:

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

best regards Stefan

thaks for reply i will get in this tutorial and see if this can help me how you see have no experience on programing

Just a thought.. Using a pot (Analog dial) is WAY WAY easier than a rotary encoder code wise. And to the user it'll feel like pretty much the same thing.

-jim lee

thanks for the suggestion Jim

already have 2 ring encoder of my previous car stereo and i design my pcb to work with those too

I make this post trying to find a little help to accomplished my project have more than 6+ months trying to make the second encoder works the way I wanted how you can see have no a lot experience on this type of coding first time trying to make something like this

The probability of getting an answer increases the more specific your questions are.

And it addition: If you describe in normal words what kind of functionality you want to have
the users don't have to analyse your existing code to guess what you might mean.

best regards Stefan

if you can se on this picture the orange square it moves left / right when you rotate the encoder and open when you clicked but when its reach the end or edge of the screen not moving down on the next row of objects thats what im looking for to do

Hi Edgar,

this is still not enough information to help you. Your Arduino shall work as a HID-USB-device sending keystrokes.

There seems to be a "original user-input-device" for using "the screen". So please answer the following questions:

  • what is the functionality of the device on the picture?
  • is this a navigationsystem? is this a mediaplayer?
  • Is the keyboard seen on the picture a part of this device?
  • what is the original "thing" for using this device?

describe how this original user-input-"thing" must be used to control this device.
and please write details!.
It would be very insufficient to describe it as "I press a key and the device reacts"

describe it with:

  • a high-resolution picture of the original input-"thing"
  • descibe all functions you want the arduino to re-produce as the second or new user-input-device

If you want to play a a ping-pong game of always posting too short answers that just erode the patience of your potential helpers go on like this.

If you really want to finish this project take the time to write a really detailed description

best regards Stefan

thanks jim I'm going to do the most accurate description possible from me

the device you see on the picture its an car stereo from a gmc acadia 2020
the keyboard you see on the picture its my computer its not a part of the device

I'm trying to build my own 10.1 lcd screen car stereo based on odroid c2 with android as OS + kodi leia 18 as a multimedia + Arduino Nano to used it for the functions with the 2 ring encoders + 4 pushbuttons
switches

what i have

10.1 LCD screen with HDMI -------------------- (1920x800 Resolution)

usb capacitive touchscreen digitizer

odroid c2 with android + kodi leia 18
X300 shield for audio WIFI, storage, audiodigital,

Arduino Nano ATmega32u4

1 ring encoder
(EC35AH part number from alps alpine)
on clockwise -------------------------------(VOL +)
on counter clockwise---------------------- (VOL -)
on click -------------------------------------(MUTE)

1 ring encoder
(EC35AH part number from alps alpine)

on clockwise--------------------------------(MOVE RIGHT)
on counter clockwise-----------------------(MOVE LEFT )
on click--------------------------------------(ENTER OR OPEN APP OR MENU)

this is the encoder for the movements on screen i know that i have a touchscreen but some of the screen objects (apps or menus) are too small to be touched.
making the encoder works as i wanted its easy to use or navigate though the screen or menus

this is the encoder that I'm trying to used for the movements on screen using the arrow keys LEFT/RIGHT those keys not moving automatically to the lower or upper row on screen

4 pushbuttons switch for shortcuts

1 digital read -----------(KEY F7)---------------------(open app)
2 digital read -----------(KEY F8)---------------------(open app)
3 digital read -----------(KEY F9)---------------------(open app)
4 digital read -----------(KEY F6)---------------------(open app)

I attached an image trying to make an example what I'm trying to do with the rotary encoder as (movements)

the blue arrow means movements right on screen cw
going from number 1 object on screen to number 4 when it reach the number 4 goes automatically to number 5 or the next row of objects (apps) and keep scrolling to the right to number 9 keep moving right goes automatically jumping from number 9 to 10 on the next row to reach the number 15 when it goes to the las row on screen goes automatically to number 1

and the red arrow been the ccw moving on screen from anywhere from 15 to 11 goes automatically to the upper row

Hi Edgar,

very good description well done. Now I understand what you want to do.
Turning the encoder shall scroll through the three lines.
The encoder-pulses must be translated to key-presses. Next step is to describe what keyboard-keypressed do what?

On clockwise rotation your code does send a shift +

Keyboard.press(KEY_LEFT_SHIFT); 
Keyboard.press('+');
Keyboard.releaseAll();

case A:
is this enough? If you just send "shift +" again and again and again does this scroll from 1 to 16?

or

case B:
do you have to press a different key (or multiple different keys to jump from row 1 position most right (App 4 )
into
row 2 position most left (App5)

So next step is to give a full list of all keypresses that are nescsessary to navigate through the menu up and down.

How shall somebody help you if you don't give sufficient information?
The code looks different in case A compared to case B
best regards Stefan

When yours is scrolling across the menu part and come to the end, does it automatically jump to the "orange square" part? Or does it stick at the end of the menu?

-jim lee

StefanL38:
Hi Edgar,

very good description well done. Now I understand what you want to do.
Turning the encoder shall scroll through the three lines.
The encoder-pulses must be translated to key-presses. Next step is to describe what keyboard-keypressed do what?

On clockwise rotation your code does send a shift +

Keyboard.press(KEY_LEFT_SHIFT); 

Keyboard.press('+');
Keyboard.releaseAll();




case A:
is this enough? If you just send "shift +" again and again and again does this scroll from 1 to 16?

or 

case B:
do you have to press a different key (or multiple different keys to jump from row 1 position most right (App 4 )
into
row 2 position most left (App5)

So next step is to give a full list of all keypresses that are nescsessary to navigate through the menu up and down.

How shall somebody help you if you don't give sufficient information?
The code looks different in case A compared to case B
best regards Stefan

this part of the code its the one i used for for volumen on kodi (kodi shortcut) pressing key shift + not for movements

Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.press('+');
Keyboard.releaseAll();
I use this for movements going only left on ccw and right cw on encoder rotation

value += encoder->getValue();
  // This part of the code is responsible for the actions when you rotate the encoder
  if (value  != last) { 
    if (last = value)      
      Keyboard.write(KEY_LEFT_ARROW);

    else

      Keyboard.write(KEY_RIGHT_ARROW); 
    last = value; 
    Serial.print("Encoder Value: "); 
    Serial.println(value);
    delay(1000);


    // This next part handles the rotary encoder BUTTON
    ClickEncoder::Button b = encoder->getButton(); 
    if (b != ClickEncoder::Open) { 
      //Serial.print("Button: ");
      //#define VERBOSECASE(label) case label: Serial.println(#label); break;
      switch (b) {
        case ClickEncoder::Clicked: 
          Keyboard.write(KEY_DOWN_ARROW);

with this section the encoder goes only from left to right not down or up when its been rotated i used the keyboard arrows to for moves (navigation on screen ) in other words when i rotate the encoder only goes left to right on the same row like i mentioned before i need to find the way (on code ) to make it goes down automatically when its reach the last object on screen going clockwise (RIGHT KEY ARROW) and up and when it reach the first object on screen going counter clockwise (LEFT KEY ARROW)
how you can see on click it send the (KEY UP ARROW) making a try im not going to used for that function on click

jimLee:
When yours is scrolling across the menu part and come to the end, does it automatically jump to the "orange square" part? Or does it stick at the end of the menu?

-jim lee

hello jim
not it keeps on the same row not going automatically down or up

I'm still fuzzy on what your doing. But, are you assuming that a right click at the end should take it down a level, and that's not happening? Is there a possibility that there is a "go down" command that you are missing?

-jim lee

What the program has to look like DEPENDS on the KEY-STROKE-Sequence
please write a posting with the KEY-STROKE-Sequence

I can hardly understand what you are trying to describe. If english is not your native language then I suggest that you write down the hole explanation in your native laguage and let google-translate do the translation.

So once again: what is the KEY-stroke-sequence that you would have to press to make the selection move from

  • 1 to 4
  • then to 5
  • then to 8
  • then to 9 etc.
    Do you understand the KEY-STROKE-Sequence!

What the program has to look like DEPENDS on the KEY-STROKE-Sequence

Man! I'm willing to help but you should answer the questions I was asking.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.