Hi all,

it's nice to use 3x4 matrix keyboard to enter all variables via keyboard. But sometimes it's more convenient to use rotary encoder for that purpose.

PEC11

In this blog I will write something about rotary encoder, how to use it and how to make a system with main menu and submenus. All will be displayed on the LCD of course. Read more if interested...

 

For those of you, who do not know what a rotary encoder is see the image above.

Incremental rotary encoder is similar to potentiometer that can be found on some older equipment but note that potentiometer has a turning angle of some 270 degrees, while rotarty encoder can rotate more than 360 degrees. It can be turned indefinetly if you like. Most of rotary encoders also have a button in the shaft means if you press the shaft, it makes a contact. That contact is very handy to function as an "Enter" command.

Rotary encoder has two outputs, A and B. The electrical signal on these output terminals is seen on the image below:

CW = clockwise; CCW = counter clock wise

If you connect a resistor (1kOhm) from +5V to each terminal (A and B) and start turning the shaft you will see that signal on each terminal will change as seen on the image above. How do we read rotary encoder signals with our AVR? With a help of Bascom-AVR it's quite simple.

 

Bascom AVR has got a nice command called Encoder (see Help file for more info on it). But this command does not solve all problems. Namely there are many different encoders on the market. Encoder that I own makes more pulses on one "click" than other enkoders and therefore the Encoder command needs some help of additional programming, which will be explained later.

Firstly we have to define input pins:

Enk1 Alias Pind.2                                           'Encoder pin A
Enk2 Alias Pind.3                                           'Encoder pin B
Enk3 Alias Pind.5                                           'Encoder mid switch
Config Enk1 = Input
Config Enk2 = Input
Config Enk3 = Input
Portd = 255

Instead of connecting resistors from +5V to A/B terminals we have turned internal pull-up resistors on PortD.

To have a reliable encoder reading I suggest to connect A/B terminals to interrupt pins on an AVR. We have used INT0 and INT1, and this corresponds also in the program:

Enable Interrupts
Mcucr = &B00000101
Enable Int1
Enable Int0
On Int0 Enkoder_sub
On Int1 Enkoder_sub

The Encoder_sub subroutine is very simple:

Enkoder_sub:
   B = Encoder(pind.2 , Pind.3 , Dol , Gor , 0)
Return

The program jumps to subroutines "Dol" and "Gor", which corresponds to "Down" and "Up". The main loop is also very simple:

Do
  Locate 1 , 1                                              'test of encoder if performs OK
  Lcd "C1  " ; C1 ; "  " ; "B= " ; B ; "  "                 'if OK, then C1 wil be incr/decr in 1
  Debounce Enk3 , 0 , Pojdi_sub , Sub                       'switch to enter submenus
Loop

In the main loop we just test if the switch was pressed. When pressing the switch we enter into submenus. When in the submenu we choose a setting and press switch which leads to another submenu, where we choose next items and so forth. I think that the program that you can download from this link is quite self explanatory. If not, send me an email through the web page.

Enjoy using incremental rotary encoder in your next projects!