Analog value used in control loop is only updated on power on.

This is my first Arduino program - a controller for an audio turntable. There are 3 push-buttons for OFF, 33RPM, and 45RPM and 3 indicator LEDs that light the buttons when they are pushed. A DC motor is driven by a MOSFET and a PWM output. Pulse period from a tachometer is measured and used to servo control motor speed.

All of that stuff seems to work, but I have a remaining bug that, though I'm sure is elementary, is still beyond me. The circuit has 2 potentiometers for fine-adjust of the 33 and 45 RPM speed. The potentiometers are read by A0 and A1. The intent is to use the analog-read values to change the target period of the motor control for fine adjust. My problem is that these pots only seem modify the control point once on power up. Turning a potentiometer doesn't change the speed, but if I move the pot and reboot, I'll get a new value for t_set which, again, can't be changed with the potentiometer. I want to be able to change speed on the fly with the potentiometer.

In the code below there is a line:
t_set = t_set_33 + v_trim_33; //set target period for 33 RPM mode
about 2/3 of the way down beneath the comment: " ///// THIS IS WHERE I'M HAVING TROUBLE /////"

This is where I specify t_set, my target period for the motor control loop. t_set_33 is the base-line target period for 33 RPM and v_trim_33 is the number read from A0 that is supposed to add to t_set_33 to fine tune the period.

When I watch a serial print of these values while rotating the pot, I CAN see v_trim_33 change so the analog read is working, but I don't see any change to t_set. It seems that the value from v_trim_33 makes it into the v_set expression only once on power up.

Below is the entire code if that helps. Apologies in advance because I suspect it's pretty ugly. Any help will is very appreciated.

#define LEDOFF 6    // "OFF" LED drive output, LOW = on
#define LED33 5     // "33" LED drive output, LOW = on
#define LED45 7     // "45" LED drive output, LOW = on
#define BTNOFF 9    // "OFF" touch button input  
#define BTN33 8     // "33" touch button input
#define BTN45 10    // "45" touch button input

int stateOFF = LOW;      // current state of LEDOFF output, start LEDOFF low (on) at power up
int readingOFF= LOW;    // current reading from BTNOFF input, start BTNOFF low at power up
int previousOFF = LOW;   // the previous reading from the BTN input, start low at power up

int state33 = HIGH;      //start 33 RPM off at power up
int reading33 = HIGH;           
int previous33 = HIGH;    

int state45 = HIGH;      //start 45 RPM off at power up
int reading45 = HIGH;           
int previous45 = HIGH;

int trimpot_45 = A1;      //analog input pin for 45RPM fine adjust pot   
int trimpot_33 = A0;      //analog input pin for 33RPM fine adjust pot
int v_trim_45 = 512;      //preset 45RPM trimpot reading to center value
int v_trim_33 = 512;      //preset 33RPM trimpot trim reading to center value
int trim_range = 25;      //+/- adjust range of 33 and 45 RPM trim pots. A value of 25 means +/-2.5% trim range

int tach_in = 2;          //input pin for tach output from motor
int PWM_out = 11;         //PWM drive output to motor
int t_diff;              //difference between set and target period
int t_set;               //Tach period target value for the currently active RPM
int t_set_33;            //Tach period target value for 33RPM
int t_set_45;            //Tach period target value for 45RPM
int t_err_range;         //sets gain of motor control loop
int n_PWM = 0;            //PWM motor drive, start at 0 on power up    
int n_offset;
volatile unsigned long t_per;
unsigned long microseconds; 
    

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long timeOFF = 0;         // the last time the output pin was toggled
long time33 = 0;         
long time45 = 0;         
long debounce = 1;   // the debounce time, set to 1ms, can be short because the circuit the OFF, 33, and 45 states latch
                     // until another button pressed 
void setup()
{
  pinMode(BTNOFF, INPUT);  //set up OFF, 33, and 45 buttons
  pinMode(BTN33, INPUT);
  pinMode(BTN45, INPUT);
  pinMode(LED45, OUTPUT);  //set up OFF, 33, and 45 indicator LEDs
  pinMode(LED33, OUTPUT);
  pinMode(LEDOFF, OUTPUT);
  pinMode(tach_in, INPUT);
  pinMode(PWM_out, OUTPUT);
  attachInterrupt(0, tachometer, FALLING); // set external interrupt for tachometer period measurment
  Serial.begin(115200);
  
  t_set_33 = 24798;         //target period for 33RPM
  t_set_45 = 18083;         //target period for 45RPM
  t_per = 50000;            //start with long per to get this going
  t_err_range = 6000;      //+/- maps to PWM output to set gain
  n_offset = 127-43;        // PWM output that drives motor at 33.3 RPM. Measured to pick
                            // correct output when t_diff is 0
}

/* switch
 * 
 * Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
 * press), the corrosponding output pin goes low and the other two go high. 
 * Repeated button presses of the same button do nothing. A different button must be pressed to change state.
 * There's a minimum delay between toggles to debounce the circuit (i.e. to ignore
 * noise).  
 *
 * David A. Mellis (21 November 2006) with modification by L. Sherman for interlock mechanism
 * 
 */

void loop()

{  
/*    
// trouble-shooting
Serial.print(t_per);
Serial.print(" ");
Serial.print(t_diff);
Serial.print(" ");
*/
Serial.print(v_trim_33);
Serial.print(" ");
Serial.print(v_trim_45);
Serial.print (" ");
Serial.print (t_set);
Serial.print (" ");
Serial.print (n_PWM);
Serial.println();

v_trim_45 = analogRead (trimpot_45);
v_trim_33 = analogRead (trimpot_33);

readingOFF = digitalRead(BTNOFF);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, drive the output pin low and the other two outputs high and remember
  // the time
  
  // code for "OFF" button and LED
  
   if (readingOFF == LOW && millis() - timeOFF > debounce) {
    if (stateOFF == HIGH)
    {stateOFF = LOW;
      state33 = HIGH;     //turn off OFF and 45 LEDS
      state45 = HIGH;}    //turn off OFF and 33 LEDS
      
    else
      stateOFF = LOW;

    timeOFF = millis();     
  }

  digitalWrite(LEDOFF, stateOFF);
  previousOFF = readingOFF;

  
  // code for "33 RPM" button and LED
  reading33 = digitalRead(BTN33);

  if (reading33 == LOW && millis() - time33 > debounce) {
    if (state33 == HIGH)
       {stateOFF = HIGH;
      state33 = LOW;
      state45 = HIGH;

      ///// THIS IS WHERE I'M HAVING TROUBLE /////
      t_set = t_set_33 + v_trim_33; //set target period for 33 RPM mode
       }
 
      state33 = LOW;
    time33 = millis();    
  }

  digitalWrite(LED33, state33);

  previous33 = reading33;
  
  
  // code for "45 RPM" button and LED
reading45 = digitalRead(BTN45);

  if (reading45 == LOW && millis() - time45 > debounce) {
    if (state45 == HIGH)
       {stateOFF = HIGH;
      state33 = HIGH;
      state45 = LOW;
      t_set = t_set_45 + v_trim_45; //set target period for 45 RPM mode
      }
    
    else
      state45 = LOW;

    time45 = millis();    
  }

  digitalWrite(LED45, state45);
  previous45 = reading45;

//end of "45 RPM" code

 
// Read period from tach and control motor
 t_per = constrain(t_per, 5000, 50000);
 t_diff = t_per - t_set;
 n_PWM = map(t_diff, t_err_range, -t_err_range, 255, 0);
 n_PWM = n_PWM - n_offset;
 n_PWM = constrain(n_PWM, 0, 255);

if (stateOFF == LOW) analogWrite (PWM_out, 0);    //hold motor off during OFF state
else analogWrite(PWM_out, n_PWM);                 //else drive motor with PWM output
 
}

void tachometer() {

    //Determine time between pulses from tachometer
    t_per = micros() - microseconds;
microseconds = micros();
}

I stripped everything out of the program that was not related to my problem. Except now it works. The pot controls speed as intended. Here is what works. Maybe this will help someone point out what’s off in the original program (in original post)

Here the stripped code that works:

int trimpot_33 = A0;      //analog input pin for 33RPM fine adjust pot
int v_trim_33 = 512;      //preset 33RPM trimpot trim reading to center value
int tach_in = 2;          //input pin for tach output from motor
int PWM_out = 11;         //PWM drive output to motor
int t_diff;              //difference between set and target period
int t_set;               //Tach period target value for the currently active RPM
int t_set_33;            //Tach period target value for 33RPM
int t_err_range;         //sets gain of motor control loop
int n_PWM = 0;            //PWM motor drive, start at 0 on power up    
int n_offset;
volatile unsigned long t_per;
unsigned long microseconds; 
    
void setup()
{
  pinMode(tach_in, INPUT);
  pinMode(PWM_out, OUTPUT);
  attachInterrupt(0, tachometer, FALLING); // set external interrupt for tachometer period measurment
  Serial.begin(115200);
  
  t_set_33 = 24798;         //target period for 33RPM
  t_per = 50000;            //start with long per to get this going
  t_err_range = 6000;      //+/- maps to PWM output to set gain
  n_offset = 127-43;        // PWM output that drives motor at 33.3 RPM. Measured to pick
                           // correct output when t_diff is 0
}

void loop()

{  
/*    
// trouble-shooting
Serial.print(t_per);
Serial.print(" ");
Serial.print(t_diff);
Serial.print(" ");
*/
Serial.print(v_trim_33);
Serial.print(" ");
Serial.print (t_set);
Serial.print (" ");
Serial.print (n_PWM);
Serial.println();

v_trim_33 = analogRead (trimpot_33);

   
     ///// THIS IS WHERE I'M HAVING TROUBLE /////
      t_set = t_set_33 + v_trim_33; //set target period for 33 RPM mode
    
   // Read period from tach and control motor
 t_per = constrain(t_per, 5000, 50000);
 t_diff = t_per - t_set;
 n_PWM = map(t_diff, t_err_range, -t_err_range, 255, 0);
 n_PWM = n_PWM - n_offset;
 n_PWM = constrain(n_PWM, 0, 255);

analogWrite(PWM_out, n_PWM);                 //drive motor with PWM output
 
}

void tachometer() {

    //Determine time between pulses from tachometer
    t_per = micros() - microseconds;
microseconds = micros();
}

Never mind. The reason it doesn’t work is because t_set is calculated in an IF statement that’s only active while a button is pressed down. If I hold the button down while turning the pot, it works. Now to figure out how to do it properly.