Preamp Control - Volume, input, mute, remote

Member
Joined 2014
Paid Member
The selector board is also now completed and is working correctly except it only changes selections when rotated clockwise, it does nothing in the opposite direction. I checked both digital input pins on the Nano and it gets pulses both directions. I checked everything else and not seeing any issues. I'm posting a picture of it, maybe someone else will notice something. It's acting like a software issue.

20231003_195137.jpg
 
Finally found a few minutes to look at the code and found the bug. In the Loop() code the line if(inputDown){ should be if(inputDownInt){
I need to look the code over more closely, it is not the cleanest code, I through it together without the hardware to test it. If I can clean it up then I will repost soon.
 
Ok updated the code. Made it simplier and doesn't roll over the input from 4 to 1 on up or 1 to 4 on down. Now it goes up to 4 and stops so you have to turn it the other direction to turn it back to 1. I will just post it as text, it will lose all the formatting indents like good code so not as readable:
/**********************************************************************************
  • This program controls the functions of relays on a PCBs to set Input Selection,
  • The controller is a Arduino Nano and the pins relate to the processor named pins
  • not the pin numbers of a 30 pin DIP device.
***********************************************************************************/

// Global variables
// Input Relay control output pin variables
const int Relay1=6, Relay2=7, Relay3=8, Relay4=9;
// LED control output pins variables
const int LED1=2, LED2=3, LED3=4, LED4=5;
// Volume Encoder D14/A0 and D15/A1
const int EncoderAPin=A0, EncoderBPin=A1;
// variables have to be volatile for use in the Interrupt Service Routine and in the Main Loop
volatile byte seqA = 0;
volatile byte seqB = 0;
volatile boolean InputUpInt = false;
volatile boolean InputDownInt = false;
int input=1;


// the setup function runs once when you press reset or power the board
void setup() {
//set input and LED pins to outputs to control relays
pinMode(LED1, OUTPUT); //pin D3 (see variable names above)
pinMode(LED2, OUTPUT); //pin D4
pinMode(LED3, OUTPUT); //pin D5
pinMode(LED4, OUTPUT); //pin D6
pinMode(Relay1, OUTPUT); //pin D7
pinMode(Relay2, OUTPUT); //pin D8
pinMode(Relay3, OUTPUT); //pin D9
pinMode(Relay4, OUTPUT); //pin D10

//set volume Encoder, input, and mute button pins to input
pinMode(EncoderAPin, INPUT); //pin D14
pinMode(EncoderBPin, INPUT); //pin D15

//set output pins for volume and mute to off, and input select relay to input 1
//Volume is in binary converted from Decimal, The input relay control is BCD
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(Relay1, HIGH);
digitalWrite(Relay2, LOW);
digitalWrite(Relay4, LOW);
digitalWrite(Relay4, LOW);

PCICR = 0b00000010; //PCIE1: pin Change interrupt Enable 1
PCMSK1 = 0b00000011; //Enable PIN Change Interrupt for A0 and A1

} //End of Setup

// Interrupt Service Routine
// Every detent in the rotary encoder generates 4 pin changes, 2 on Pin A and 2 on Pin B
ISR (PCINT1_vect){
//When Interrupt triggered read encoder pins
boolean A_val = digitalRead(EncoderAPin);
boolean B_val = digitalRead(EncoderBPin);

//Record Pin A and B sequences in the global variables
seqA <<= 1; //shift the current byte date over one bit to the left
seqA |= A_val; //OR in, add, the new bit value, 0 or 1, of the encoder pin A
seqB <<= 1; //shift the current byte date over one bit to the left
seqB |= B_val; //OR in, add, the new bit value, 0 or 1, of the encoder pin A
//Mask the Most Significant four bits
seqA &= 0b00001111; // wipes off the previous four reads that were moved
seqB &= 0b00001111; // to the four higher bits
//Compare the recorded sequence with the expected sequence
if (seqA == 0b00000011 && seqB == 0b00001001){
InputUpInt = true;
}
if (seqA == 0b00001001 && seqB == 0b00000011){
InputDownInt = true;
}
} // end ISR

void loop() {

//Booleans for task status, to be set true when a task is selected
bool inputUp=false, inputDown=false, task=false;

if(InputUpInt){
task=true;
InputUpInt=false;
if(input < 4){ // if not at 4 then add 1
input=input+1;
}
}//end of if(InputUpInt)

if(InputDownInt){
task=true;
InputDownInt=false;
if(input > 1){ // input not 1 then subtract 1
input=input-1;
}
}//end of if(inputDownInt)

//Perform the appropriate task based on input
if(task){
digitalWrite(LED1, LOW);
digitalWrite(Relay1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(Relay2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(Relay3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(Relay4, LOW);

switch(input){
case 1: digitalWrite(LED1, HIGH);
digitalWrite(Relay1, HIGH);
break;
case 2: digitalWrite(LED2, HIGH);
digitalWrite(Relay2, HIGH);
break;
case 3: digitalWrite(LED3, HIGH);
digitalWrite(Relay3, HIGH);
break;
case 4: digitalWrite(LED4, HIGH);
digitalWrite(Relay4, HIGH);
break;
default: break;
} // End Switch
} //End IF

// delay(5); // delay needed to smooth out control
} // End of Loop
 
Hi RickRay, When you say "the volume control is still muting/unmuting when the button is held", are you referring to the encoder push button or the remote. The code is meant to stop the mute/unmute cycle from the encoder, if someone holds that button in. The remote will send repeating codes when a button is held, can't stop that, but not a bad thing as you want to be able to hold the volume buttons down to go up or down quickly, having to push and release a volume button on the remote to change one step at a time would be a pain. :)
 
Ok, checked the code for the volume of old verses new and they are the same. And the programming computer seems to have deleted all my files. I have backups of everything except the Volume programs update. So I will have to remember how I did it and recreate it. Fortunately I have one volume setup of the hardware to test on.
 
The other day my audio business friend had a request from a customer to use Caddock resistors for more than the input load. So I turned the board layout to have dual footprint for the large Vishay/Dale RN series resistors and the slightly smaller industrial versions and the smaller Caddock resistors. I can't justify the cost in my personal system but for someone with money who wants the ultimate in low distortion passives, this layout make it easier. Attached is the Gerbers for version 3 of the lower board and version 2 of the upper board.
 

Attachments

  • Vol Analog MicroP Board BOTv3_gerber.zip
    82.2 KB · Views: 69
  • Vol Analog MicroP Board TOPv2_gerber.zip
    42.3 KB · Views: 61
The input control has been separated from the volume section so that is not a problem. The remote control is handled by a receiver chip and a couple logic parts but is mostly software driven so if you don't populate the few parts the remote is gone; without it you can't do balance control so you would want the previous version which is what I currently use in my preamp. But the display, while not necessary to see if you are muted or the volume level you could leave it out and just have the rotary encoder board for volume and mute. Verify that all you want is volume and mute and then I will look up the post number.
 
  • Like
Reactions: 1 user
Member
Joined 2004
Paid Member
johnhenryharris:

I'm no coder, but the following portion of your code in Post #584 appears to have an error:

//set output pins for volume and mute to off, and input select relay to input 1
//Volume is in binary converted from Decimal, The input relay control is BCD
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
digitalWrite(Relay1, HIGH);
digitalWrite(Relay2, LOW);
digitalWrite(Relay4, LOW);
digitalWrite(Relay4, LOW);

I assume the penultimate line should read "digitalWrite(Relay3, LOW);"

Regards,
Scott
 
  • Like
Reactions: 1 user