Author Topic: Multiple rotary encoders  (Read 7527 times)

0 Members and 1 Guest are viewing this topic.

Offline Greg Robinson

  • Regular Contributor
  • *
  • Posts: 85
  • Country: au
Multiple rotary encoders
« on: December 29, 2013, 05:29:38 am »
Hi everyone,

I recently asked a question about driving a large number of relays (operating as 8bit digital pots) from a microcontroller, and I received some great help, settling on using shift registers.

Now my lack of experience with digital hardware is showing again.
I would like to use 12 rotary encoders to control 12 digital pots (relay banks). I would also like two digit 7 segment displays to show the value each is set to. I'm hoping to use an Arduino Mega 2560 for the mcu.

How would you recommend I accomplish something like this?

Thanks again for any assistance, and the help I've received so far.
 

Offline Greg Robinson

  • Regular Contributor
  • *
  • Posts: 85
  • Country: au
Re: Multiple rotary encoders
« Reply #1 on: December 29, 2013, 08:03:06 am »
Ok, so I think I've answered my own question about the 7 segment LED displays, I can use serial LED drivers (like the MAX7221) and only use 3 pins on the micro-controller.

Still not sure how I can multiplex the rotary encoders though.
 

Online Rerouter

  • Super Contributor
  • ***
  • Posts: 4290
  • Country: au
  • Question Everything... Except This Statement
Re: Multiple rotary encoders
« Reply #2 on: December 29, 2013, 08:03:56 am »
I really sounds like your not doing much processing wise, as you would only need to update the 7 seg each time the encoder changes,

the relays and 7 segment can be be handled by some 74HC595's, below is a bit of code off an older project of mine the tri-stating bit can probably be cleared up, the idea was to write out to 2 of those chips in series using a hex value (memory card tester) but you can use it to write out your value directly.
DO_SO = Serial Input to chip
DO_OE = Output Enable Pin
SCLK = Shift In Clock
LCLK = Latch Clock

 
Code: [Select]
  void DataOut(unsigned long DATA) {                                // Shift out data
     digitalWrite(DO_OE, LOW);                                       // Enable Shift Register Outputs
     for(int D=0; D<16; D++) {                                       // One by one clock out 16 bits
       if(bitRead(DATA,(15-D)) == 0) { digitalWrite(DO_SO,LOW); }   
       else                          { digitalWrite(DO_SO,HIGH);  }
       Clock(DO_SCLK);                                               // Clock the shift Register
     }
     Clock(DO_LCLK);                                                 // Clock The latch
     digitalWrite(DO_OE, HIGH);                                      // Tristate shift register outputs   
   }

void Clock(int Pin) {                                              // Rising Edge Clock Function
    digitalWrite(Pin, LOW);
    digitalWrite(Pin, HIGH);
  } 


as for the 12 rotaries, each port (not pin) on the At mega has a pin change interrupt, so you can either burn 24 pins and do it very quickly by bit-reading all 24 pins on any change, or offload the second pin of every encoder to a 74hc165 shift register, taking note of a change on only 1 encoder pin.

below i have attached my current encoder interrupt code (I'm only using a single encoder Model: ECW1J-B28-AC0024L) this is the software side of the denouncing, i also have a 10K resistor in series and a 1nF cap to ground (micro side of resistor) on each pin, with the pin lift up turned on, while i could likely improve the de-bouncing routine or hardware, like you I'm not really doing anything else when I'm changing a value.

Code: [Select]
void encoder() {
  if(millis() - LastMillis > 20) {                          // If less than 20ms has elapsed, ignore
    if(bitRead(PINB,0) == 0 /*bitRead( PIND,3)*/) {     // If encoder pin A and B read the same
      Pos++;                                                     // spinning clockwise so increment,
    }
    else {
      Pos--;                                                       // otherwise spinning counter clockwise so decrement,
    }
    LastMillis = millis();                                     // Record last time to compare
  }
}

edit: a side thought, with 12 pins for encoders, 3 for your output shift registers, and 3 for your input shift registers you could manage it on a 328 with no free pins :D
« Last Edit: December 29, 2013, 09:38:58 am by Rerouter »
 

Offline Greg Robinson

  • Regular Contributor
  • *
  • Posts: 85
  • Country: au
Re: Multiple rotary encoders
« Reply #3 on: December 29, 2013, 09:27:05 am »
Thanks for the suggestions and code examples Rerouter!

The parallel in serial out shift register for the rotary encoders is a great idea, seems so simple and intuitive once you've been told about it!

Maybe I should give some more info on my project?

The idea is a vacuum tube musical instrument amplifier, with 12 control parameters, using the digital pots to be able to select pre-set values using midi or other control input (also with the ability to save those pre-sets to EEPROM).
Being a bit of an analog/linear purist led me to the 8 bit relay potentiometer concept - keep the audio signal path out of the digital domain, and away from potential distortion artefacts from fet based digital pots (not to mention the voltage limitations).
There will also be a few other relay signal switching things to handle (I can just tack them on a shift register), so I'm trying to use as few pins as possible, ultimately hopefully allowing me to use a smaller micro-controller (a 328 would be perfect as it's available in a DIP package).

So I'll need to reserve Rx and Tx for midi, 7 inputs for the 12 rotary encoders, 3 outputs for the digital pots, 3 outputs for the LED displays (maybe I should combine the pots and LED displays on the same shift register?), I guess I really want about 20 button inputs as well (guess I could use an analog in with an R-2R ladder, or another parallel in serial out shift register). I think a master LCD display is something I'm going to have to consider too. So, quickly running out of pins, but at least I'm not doing a whole lot of processing. Guess I should consider I/O expanders too, especially if I want to try and stick to through hole packages.

Thanks again everyone!
 

Online Rerouter

  • Super Contributor
  • ***
  • Posts: 4290
  • Country: au
  • Question Everything... Except This Statement
Re: Multiple rotary encoders
« Reply #4 on: December 29, 2013, 10:03:27 am »
So I'll need to reserve Rx and Tx for midi, 7 inputs for the 12 rotary encoders, 3 outputs for the digital pots, 3 outputs for the LED displays (maybe I should combine the pots and LED displays on the same shift register?), I guess I really want about 20 button inputs as well (guess I could use an analog in with an R-2R ladder, or another parallel in serial out shift register). I think a master LCD display is something I'm going to have to consider too. So, quickly running out of pins, but at least I'm not doing a whole lot of processing. Guess I should consider I/O expanders too, especially if I want to try and stick to through hole packages.

to do it right you need 12 inputs for the encoders, + the tie in for second group of 12 pins over the shift register, (3 pins min, Parallel load, clock and serial in) however you can string this input string as long as you like, by using bitread and bitset/bitclear commands for fixed pins, loading in this way can happen stupidly fast, so tie on any buttons you want, just do it after the encoders so that you only need to shift in 12 bits on an interrupt (be tidy)

For your outputs do the same make the string as long as you like, you can clock things out very quickly, but equally take up at minimum 3 pins, (at 18 now, 2-13 + A0-A5, and you may want to share clocks as otherwise tying the output latch pin to clock will have your relays rattling along as the new setting gets shifted in.)

so now how to get around the button dilemma, now you realistically could just read endlessly and add a small debounce loop like the encoder, or create a latch on the input, with my device as it can be very busy crunching other things for a few hundred milliseconds at a time i came up with the little 2 transistor latch in the image below, the switch on the left is your button, and the switch on the top is an output turning on or off a 20K pullup to 5V, with the result of the latch being the point called L, when the switch pulls the transistor low, it latches its output low, until its reset by removing the lift-up and re-applying it.

as long as all your dealing with is logic inputs and outputs shift registers can be used, if you want to measure analog values, i2c port expanders might be the go, just know that i2c is much much slower than direct bit reads and writes.
 

Offline Greg Robinson

  • Regular Contributor
  • *
  • Posts: 85
  • Country: au
Re: Multiple rotary encoders
« Reply #5 on: December 29, 2013, 10:21:28 am »
to do it right you need 12 inputs for the encoders, + the tie in for second group of 12 pins over the shift register, (3 pins min, Parallel load, clock and serial in)

Whoops! Yep, typo there.

Thanks again for the assistance Rerouter, you've been a big help!
« Last Edit: December 29, 2013, 10:23:22 am by Greg Robinson »
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Multiple rotary encoders
« Reply #6 on: December 30, 2013, 02:46:53 pm »
Quote
I would like to use 12 rotary encoders to control 12 digital pots (relay banks).

I would step back and think how insane that approach is. Not sure what you are trying to do but using 12 individual encoders to control 12 pots is just crazy, and difficult to implement on one mcu.

Two options (out of many possible options):
1) Use 1 encoder + 1 mcu to control 12 digital pots: fairly standard and easy to implement;
2) Use 1 encoder + 1 mcu to control 1 digital pot: modular and easy to do;
================================
https://dannyelectronics.wordpress.com/
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf