Hacked a stereo to use face plate

Full Demo
This code reads all 24 buttons on the main panel (1-24), the power and mute buttons (35,34), the three buttons around the volume knob (31,32,33) and the button in the center of the rotary encoder labeled set (30). Also the small rotary encoder is re1 and the larger volume knob is re2. This demo simply displays the button pressed or new value of a knob turn via the serial port.

This uses timer2 to allow for background reading of the values to not effect the loop. You can move this to any timer / fast read iteration.

*** Include - code from class AnalogButtonController here
*** Include - code from class RotaryEncoderRangeController here

//====================================

#include <MsTimer2.h>

//----------------------------
// Rotary Encoder Setup
//----------------------------

//--- create callback functions for Rotary encoder
void valueChangedForRE1(int theNewValue){
  Serial.print("RE1 ");
  Serial.println(theNewValue, DEC);
}
void valueChangedForRE2(int theNewValue){
  Serial.print("RE2 ");
  Serial.println(theNewValue, DEC);
}

//--- create a new Rotary encoder controller for RE1 using digital pins
RotaryEncoderRangeController re1 = RotaryEncoderRangeController(&valueChangedForRE2, 8, 9);
RotaryEncoderRangeController re2 = RotaryEncoderRangeController(&valueChangedForRE1, 6, 7);

//----------------------------
// Button Set Setup
//----------------------------
//--- create callback functions for button group
boolean tmpStatus = true;
void buttonPressed(int theButton){
  Serial.print("Button ");
  Serial.println(theButton, DEC);
}

int getButtonFromValueSet1(int theVal){
if( theVal > 1010 ) return 0;

if( theVal <= 930 && theVal >= 920 ) return 5;
if( theVal <= 950 && theVal >= 942 ) return 6;
if( theVal <= 970 && theVal >= 964 ) return 7;
if( theVal <= 976 && theVal >= 972 ) return 8;
if( theVal <= 200 && theVal >= 2 ) return 13;
if( theVal <= 877 && theVal >= 870 ) return 14;
if( theVal <= 965 && theVal >= 953 ) return 15;
if( theVal <= 1000 && theVal >= 992 ) return 31;
if( theVal <= 992 && theVal >= 984 ) return 32;
if( theVal <= 982 && theVal >= 978 ) return 33;

  return -1;
}

int getButtonFromValueSet2(int theVal){
if( theVal > 1010 ) return 0;


if( theVal <= 980 && theVal >= 974 ) return 1;
if( theVal <= 972 && theVal >= 969 ) return 2;
if( theVal <= 967 && theVal >= 962 ) return 3;
if( theVal <= 960 && theVal >= 951 ) return 4;
if( theVal <= 105 && theVal >= 0 ) return 9;
if( theVal <= 873 && theVal >= 868 ) return 10;
if( theVal <= 926 && theVal >= 919 ) return 11;
if( theVal <= 947 && theVal >= 939 ) return 12;
if( theVal <= 988 && theVal >= 982 ) return 34;
if( theVal <= 996 && theVal >= 990 ) return 35;

  return -1;
}

int getButtonFromValueSet3(int theVal){
if( theVal > 1010 ) return 0;


if( theVal <= 880 && theVal >= 870 ) return 17;
if( theVal <= 928 && theVal >= 920 ) return 18;
if( theVal <= 964 && theVal >= 960 ) return 19;
if( theVal <= 974 && theVal >= 968 ) return 20;
if( theVal <= 200 && theVal >= 0 ) return 21;
if( theVal <= 949 && theVal >= 941 ) return 22;
if( theVal <= 961 && theVal >= 954 ) return 23;
if( theVal <= 982 && theVal >= 977 ) return 24;
if( theVal <= 997 && theVal >= 989 ) return 16;
if( theVal <= 991 && theVal >= 984 ) return 30;

  return -1;
}


//--- Create three sets of button controlles that all read different values but call the same callback function
//-- Example: The first one ..
//      calls buttonPressed when button pressed, 
//      gets button from analog value from getButtonFromValueSet1 function 
//      reads analog pin 3 
AnalogButtonController set1 = AnalogButtonController(&buttonPressed, &getButtonFromValueSet1, 3);
AnalogButtonController set2 = AnalogButtonController(&buttonPressed, &getButtonFromValueSet2, 4);
AnalogButtonController set3 = AnalogButtonController(&buttonPressed, &getButtonFromValueSet3, 5);

//----------------------------


void processTimer2(){
  re1.check(); 
  re2.check(); 
  set1.checkButton(); 
  set2.checkButton(); 
  set3.checkButton(); 
}

void setup(){
  Serial.begin(19200);

  //--- Range from 1 to 256 with tick of 1 and step of 5
  re1.begin(1,256,1,5);
  //--- Same as above but goes backwards
  re2.begin(1,256,1,5,false);
  //Note: or setup range on the fly (for different usages of same encoder)
  //Example:  re1.setRange(10,10000,currentValueVar,50);

  MsTimer2::set(5, processTimer2);
  MsTimer2::start();
}


void loop(){
 //--- take action in loop to not blow out interrupt time
 set1.runButtonPress();
 set2.runButtonPress();
 set3.runButtonPress();
 delay(100);
}

Notes about the code:

I wanted the code to be "load and go" for someone making use of it. Also this is Alpha version one, not quite ready to move into library form. For these reasons the classes are just placed in line at the top of the code.

The buttons on the stereo are not connected to outputs in the same logical orientation I want to use them in. For example, the top eight buttons on the stereo go to 2 different outputs. I opted to create a logical breakdown of button numbers from left to right. So the top 8 are 1-8 the next row is 9-16 and so on. That is why the return numbers in the callbacks that map analog readings jump around. Your usage of this library may be simply numbered in order.

The action resulting from the callback should not happen in a timer or your code will lock up trying to do too much in the cycle. For this reason the runButtonPress routine is called inside the standard loop so the callback will run there as well.

// this is in loop
  set1.runButtonPress();
 set2.runButtonPress();
 set3.runButtonPress();