Newbie screwup I am Sure

I have been trying to build a paddle shifter for a vehicle I have been playing with. Im sure that is ill advised etc. but I have a weird situation I have been having trouble getting my actuator to move when told and when it does move it sure as hell dont want to stop where its told. By itself the actuator part of script works perfect 100 percent but when its all put together it does not want to recognize the goalPosition I am trying to relay. I finally have it working as of now but I cant figure out why. In the Loop lines 197 and 203. If I dont have some type of serial.print there the actuator will not move doesnt matter if its nuclear launch codes or transcripts from "green eggs and ham" if there is no print there it completely ignores the goalPosition. Any thoughts? I am pretty new at this only since about the first of the year. But I usually try to copy off knowledgable sources. I appologize if my script is a little all over the place I have been trying different approaches to get it going. I hope I get this markdown inserted correctly so I dont waste half the day getting yelled at for it.

#define NUM_FWD_GEARS               8       //#     number of forward speeds

#define BUTTON_READ_INTERVAL        50ul    //mS    time between up/down button reads

#define NO_PRESS                    0x00    //mask  bit mask for no buttons pressed
#define BUTTON_UP_PRESSED           0x01    //mask  bit mask for up button pressed
#define BUTTON_DOWN_PRESSED         0x02    //mask  bit mask for down button pressed

#define TCC_DELAY                   1000ul  //mS    after TCC is enabled, time delay before activation

const byte buttonUP = A0;                    //pin   Push Button for UP shift
const byte buttonDOWN = A3;                  //pin   Push Button for Down shift
const byte switchTOWMODE = 7;               //pin   Switch for tow/haul mode
const byte solA = 9;                        //pin   Solenoid A output
const byte solB = 10;                        //pin   Solenoid B output
const byte TCC  = 11;                        //pin   TCC output
const int relay1 = 7;     // extend relay output pin connection
const int relay2 = A5;     // retract relay output pin connection
const int HALL0 = 3; // interupt pin connection - See attachInterrupt() docs for your board
const byte MPS = A4;
volatile int counter = 0;
int counterState = 0;        // current state of the button
int lastButtonState = 0;     // previous state of the button
int buttonState;
long lastDebounce0 = 0;
long debounceDelay = 10;     // Ignore bounces under 10ms

int CurrentPosition = 0; 
volatile int goalPosition = 0;

boolean Extending = false;
boolean Retracting = false;



void actuatorExtend(){
     digitalWrite(relay1, HIGH);  // Always turn one off and then the other on
     digitalWrite(relay2, LOW);   // so that there are never two relays on (BIG!)
}

void actuatorRetract(){
     digitalWrite(relay2, HIGH);  // Always turn one off and then the other on
     digitalWrite(relay1, LOW);   // so that there are never two relays on (BIG!)
    
}
void actuatorStop() {
   digitalWrite(relay2, HIGH);
   digitalWrite(relay1, HIGH);
}



byte
   gearSelection,
   lastGearSelection,
   lastUp,
   lastDn,
   lastTM;
bool
   bTCCStatus;
unsigned long
   timeTCCSolenoid;


typedef struct structGearSolenoidProfiles
{
 byte    name;
 //byte    goalPosition;
 //byte    solenoid_A;
 //byte    solenoid_B;
 //byte    TC;

} sGearSolenoidProfiles;

//
const sGearSolenoidProfiles GearSolenoidProfiles[NUM_FWD_GEARS] =
{
 {
   .name = 1,
//   .goalPosition = 0,
  // .solenoid_A = LOW,
   //.solenoid_B = LOW,
 
 },
 {
   .name = 2,
  // .goalPosition = 200,
  // .solenoid_A = LOW,
  // .solenoid_B = HIGH,

 },
 {
   .name = 3,
 //  .goalPosition = 300,
//   .solenoid_A = HIGH,
  // .solenoid_B = LOW,

 },
 {
   .name = 4,
 //  .goalPosition = 400,
  // .solenoid_A = LOW,
  // .solenoid_B = HIGH,

 },
 {
   .name = 5,
//   .goalPosition = 400,
//   .solenoid_A = HIGH,
 //  .solenoid_B = HIGH,

 },
 {
   .name = 6,
 //  .goalPosition = 400,
//   .solenoid_A = HIGH,
 //  .solenoid_B = LOW,

 },
 {
   .name = 7,
///   .goalPosition = 400,
//   .solenoid_A = LOW,
 //  .solenoid_B = LOW,

 },
 {
   .name = 8,
 //  .goalPosition = 400, 
 //  .solenoid_A = HIGH,
//   .solenoid_B = LOW,
//   .TC= HIGH,
 }
};//GearSolenoidProfiles[]
void setup() 
{
   pinMode( buttonUP, INPUT_PULLUP );
   lastUp = digitalRead( buttonUP );       //set initial button state
   pinMode( buttonDOWN, INPUT_PULLUP );
   lastDn = digitalRead( buttonDOWN );     //set initial button state
   pinMode( switchTOWMODE, INPUT_PULLUP );
   pinMode(MPS,INPUT_PULLUP);    
   pinMode( solA, OUTPUT );                //Solenoid A set as output
   pinMode( solB, OUTPUT );                //Solenoid B set as output
   pinMode( TCC, OUTPUT );                 //TCC set as output

   digitalWrite( solA, HIGH );             //set intital state as off
   digitalWrite( solB, HIGH);
   digitalWrite( TCC, LOW );

   //internal flag for TCC status
   bTCCStatus = false;
   gearSelection = 0;          //start in "1st" gear for this test
   lastGearSelection = 0xff;   //ensure we change into correct gear first pass by making last != current
   
Serial.begin(9600);
 
 pinMode(HALL0, INPUT_PULLUP);        // hall is an input

 attachInterrupt(digitalPinToInterrupt (3), trigger0, CHANGE);  // See attachInterrupt() doc for YOUR BOARD

 
 // Set both output pins
 pinMode(relay1, OUTPUT);
 pinMode(relay2, OUTPUT);
 
 digitalWrite(relay2, HIGH);
 digitalWrite(relay1, HIGH);
}


void loop() {   
   trigger0();
   Gear_Selection_Control();
   Gear_Solenoid_Control();
   TCC_Control();
  // Serial.print(CurrentPosition);
 
 //  if (Extending == true && CurrentPosition > (GearSolenoidProfiles[gearSelection].goalPosition )) {    
 //     //we have reached our goal, shut the relays off
 //     actuatorStop();
 //     Extending = false;
 //     //Serial.println(CurrentPosition);  
 //      }
 
 // if (Retracting == true && CurrentPosition < (GearSolenoidProfiles[gearSelection].goalPosition )) {
 //      //we have reached our goal, shut the relay off
 //      actuatorStop();
 //      Retracting = false;
 //    //  Serial.println(HALL0);  
 //      }

 if (CurrentPosition < goalPosition ) {
       Retracting = false;
       Extending = true;
       actuatorExtend ();
       Serial.print("actuator");   
     } 
     else if (CurrentPosition == goalPosition ) {
       actuatorStop();
        Retracting = false;
        Extending = false;         
        Serial.print(goalPosition);
     } 
  if (CurrentPosition  > goalPosition) {
       Retracting = true;
       Extending = false;
       actuatorRetract();
        Serial.print(goalPosition);
     //  Serial.print(counter);            
      } 
      else if (CurrentPosition == goalPosition ) {
        actuatorStop();
        Retracting = false;
        Extending = false;     
      }
  
}//loop

void Gear_Selection_Control( void )
{
   byte
       btnState;
       
   btnState = ReadButtons();
   switch( btnState )
   {
       case    NO_PRESS:
           //nothing pressed or not read (interval not elapsed); no action
       break;

       case    BUTTON_UP_PRESSED:
           if( gearSelection < (NUM_FWD_GEARS-1) )
               gearSelection++;
               //Serial.print(counter);
           
       break;

       case    BUTTON_DOWN_PRESSED:
           if( gearSelection > 0 )
               gearSelection--;
               
       break;

       default:
           //only remaining possibility is both pressed; ignore with no action
       break;
       
   }//switch
   
}//void

void Gear_Solenoid_Control( void )
{
   if( gearSelection != lastGearSelection )
   {
       lastGearSelection = gearSelection;
   if ((GearSolenoidProfiles[gearSelection].name) == 1) {
     Serial.print("Park");
     digitalWrite(solA, HIGH);
     digitalWrite(solB, LOW);
     goalPosition = 0;
   }
       lastGearSelection = gearSelection;
   if ((GearSolenoidProfiles[gearSelection].name) == 2) {
     Serial.print("Reverse");
     digitalWrite(solA, LOW);
     digitalWrite(solB, LOW);   
     goalPosition = 200;   
    
   }
       lastGearSelection = gearSelection;
     if ((GearSolenoidProfiles[gearSelection].name) == 3) { 
     Serial.print("Neutral");
     digitalWrite(solA, HIGH);
     digitalWrite(solB, LOW);
     goalPosition = 300;
     
   }
       lastGearSelection = gearSelection;
     if ((GearSolenoidProfiles[gearSelection].name) == 4) {
     Serial.print("First");
     digitalWrite(solA, LOW);
     digitalWrite(solB, LOW);
     goalPosition = 400;
     
   }
           lastGearSelection = gearSelection;
     if ((GearSolenoidProfiles[gearSelection].name) == 5) {
     Serial.print("Second");
     digitalWrite(solA, HIGH);
     digitalWrite(solB, LOW);
   }
       lastGearSelection = gearSelection;
     if ((GearSolenoidProfiles[gearSelection].name) == 6) { 
     Serial.print("Third");
     digitalWrite(solA, LOW);
     digitalWrite(solB, LOW);
   }
       lastGearSelection = gearSelection;
     if ((GearSolenoidProfiles[gearSelection].name) == 7) {
     Serial.print("Fourth");
     digitalWrite(solA, HIGH);
     digitalWrite(solB, LOW);
   }
       lastGearSelection = gearSelection;
     if ((GearSolenoidProfiles[gearSelection].name) == 8) {
     Serial.print("Fifth");
     digitalWrite(solA, LOW);
     digitalWrite(solB, LOW);
     }
   }


          


       
}//Gear_Control

void TCC_Control( void )
{
   unsigned long
       tNow;
   bool
       bTCCEnabled;

   tNow = millis();
   
   //TCC enabled if:
   //  - 4th gear is engaged, OR
   //  - 3rd gear is engaged and tow-mode not selected, AND
   //  - TCC delay timer has expired
   bTCCEnabled =   ( (gearSelection == 3) || 
                   ( (gearSelection == 2 && digitalRead( switchTOWMODE ) == HIGH) ) ) &&
                   ( tNow - timeTCCSolenoid >= TCC_DELAY );  
   
   //if conditions passed and TCC is now off, turn on its solenoid
   if( bTCCEnabled )
   {
       if( bTCCStatus == false )
       {
           //turn on TCC
           digitalWrite( TCC, HIGH );
           bTCCStatus = true;
           
       }//if
       
   }//if
   else 
   {
       if( bTCCStatus == true )
       {
           //turn off TCC
           digitalWrite( TCC, LOW );
           bTCCStatus = false;
           
       }//if
       
   }//else
   
}//TCC_Control

//returns a mask:
//0b00000000 - no buttons pressed
//0b00000001 - up pressed
//0b00000010 - down pressed
//0b00000011 - both pressed
//
byte ReadButtons( void )
{
   static unsigned long
       timeButton = 0;
   unsigned long
     
       tNow;
   byte
       retval,
       nowButton;

   retval = NO_PRESS;
   
   tNow = millis();
   if( (tNow - timeButton) >= BUTTON_READ_INTERVAL )
   {
       //set up for next read interval
       timeButton = tNow;

       //read the button and set the flags
       nowButton = digitalRead( buttonUP );
       if( nowButton != lastUp )
       {
           lastUp = nowButton;
           if( nowButton == LOW )
               retval |= BUTTON_UP_PRESSED;
               
       }//if
       
       nowButton = digitalRead( buttonDOWN );
       if( nowButton != lastDn )
       {
           lastDn = nowButton;
           if( nowButton == LOW )
               retval |= BUTTON_DOWN_PRESSED;
               
       }//if
       
   }//if
   
   return retval;
   
}//ReadButtons
void trigger0() {
     if ( Extending == true) {
     counter++;
     CurrentPosition = counter;
   }
           
     if ( Retracting == true ) {
     counter--;
     CurrentPosition = counter;
   }       
}

At a glance it looks like your loop would be running very freely.

Using 9600 as a band rate means that if you hammer the printing, each character is about 1 millisecond of delay.

Try using delay() as the voodoo solution instead of printing - just delay about as many milliseconds as those print statements woukd take, that is to say the same number of milliseconds as characters. It would be a clue.

Alternately, try bumping your rate to something more 21st century- ish, like 115200 or even 1000000.

Set the same rate in you serial monitor and say whether the voodoo works.

Quick experiments, may shed light.

HTH

a7

Sorry, no line numbers shown.

Why are you calling trigger0() at the beginning of loop, and also using it as an interrupt handler? That could be messing up your counter.

There are several variables that you have neglected to declare as volatile. If a variable is used both inside an interrupt handler, and somewhere else in the code, then is needs to be volatile. You also need to be careful accessing any volatile variable that is larger than a single byte, an interrupt can occur between bytes when accessing a multi-byte variable, changing the value in unexpected ways.

Nice job with code tags on your first post
There are some issues with your interrupt handling.

attachInterrupt(digitalPinToInterrupt (3), trigger0, CHANGE);

void trigger0() {
     if ( Extending == true) {
     counter++;
     CurrentPosition = counter;
   }
           
     if ( Retracting == true ) {
     counter--;
     CurrentPosition = counter;
   }       
}
  1. Do not call trigger0() as a function on loop
  2. the transfer of counter to Current position is not correct

You need a "protected" transfer in loop. The ensures values aren't changing when you read them

noInterrupts();
CurrentPosition = counter;
interrupts();

I would start the loop() as follows

void loop() {   
   //trigger0();
   noInterrupts();
   CurrentPosition = counter;
   interrupts();

I will give it a shot the serial was only in there for debugging and maybe a little lcd screen eventually so I wasnt worried to much about speed. Anything is faster than I can type.

yea trigger got put in there for some reason and I never bothered to take it out since the interrupt pin calls it. I will give it a shot

just added a 50ms delay it did move the actuator but half way through started going nuts in and out etc. had to shut it down

moving the counter to the loop like that seems to have straightened it out. I had to remove the delay I had just tried because it was causing it to jump and bounce the actuator in and out not sure why. I know I got alot more cleaning to do on this thing but at least its a start.

The indentation of your code is inconsistent.
That makes it difficult to read and makes it error prone.
In ide press ctrl-t. That should give a proper indentation.

Is this allowed? Is it an alternative way to initialize a struct? If so: I have never seen it and learned something today.
I am surprised about the dot before name...

This:

lastGearSelection = gearSelection;

Can be moved after all ifs. It would be needed only once.

yea it works fine I cant take credit for it I stole it from another poster who was doing the same type thing. Makes it nice when building out structure. And can be refered to later if needed by calling (GearSolenoidsProfile.goalPosition) I will probably go back to that format when I get this actuator reliable

I thought I had this thing whooped went to install my little LCD I2c screen and lost the actuator I cannot get it back at all now. I will fix the indents I get a little sloppy when moving stuff around trying to figure it out. Is there a way other than auto format because it usually for me anyhow causes more problems than its worth I will have me half way across the screen struggling with curley brackets if I use it.

the lastGearSelection = gearSelection; I figured it could be removed but the copy and paste gods seen fit that it got picked up when I was lining them out and since it was half way working I didnt want to jinx it. but I will get them erased

Which is an option in your IDE.
File>Preferences>tick show line numbers
Leo..

Aha. Thanks.
How to do at the occasions cell phone or a none IDE tablet has to be used?

That is called designated initializers, and was added in c++20 (originally began in c99). I have seen some discussion that gcc allows it in earlier versions of c++, so it may cause problems with code portability if you are using another compiler or an older c++ standard.

If you have not resolved this, please post your attempt to add the display code.

If it is an hd44780 character display the best library to use is Bill Perry's hd44780.h It is available through the library manager. It will auto detect the i2c address and the chip configuration. It has a diagnostics routine if there are problems.

still fighting it everything is working except actuator extend. every time the uno does something IE delay ends for the lcd in setup or up or down button pushed the actuator ext relay bumps for a sec. there is nothing I can find thats telling it to do this. I have tried adding more power to breadboard thinking maybe it was just weak with everything running off USB acts the same. And when it is moved to 2nd gear it kicks on the TCC relay even though it is clearly written to keep it off, but it only does it in 2nd gear all the other gears it behaves correctly. Here is my cleaned up current script with the LCD its giving me no problems

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define NUM_FWD_GEARS 8  //#     number of forward speeds
#define BUTTON_READ_INTERVAL 50ul  //mS    time between up/down button reads
#define NO_PRESS 0x00             //mask  bit mask for no buttons pressed
#define BUTTON_UP_PRESSED 0x01    //mask  bit mask for up button pressed
#define BUTTON_DOWN_PRESSED 0x02  //mask  bit mask for down button pressed
#define TCC_DELAY 1000ul  //mS    after TCC is enabled, time delay before activation

LiquidCrystal_I2C lcd(0x27, 16, 2);

int 
sloppy = 11,
transbrake = A4,
counterState = 0,     // current state of the button
lastButtonState = 0,  // previous state of the button
buttonState;

const byte 
buttonUP = A0,     //pin   Push Button for UP shift
buttonDOWN = A3,    //pin   Push Button for Down shift
switchTOWMODE = 6,  //pin   Switch for tow/haul mode
solA = 9,           //pin   Solenoid A output
solB = 10,          //pin   Solenoid B output
TCC = 12;           //pin   TCC output


const int 
relay1 = 8,         // extend relay output pin connection
relay2 = A5,         // retract relay output pin connection
HALL0 = 3;           // interupt pin connection - See attachInterrupt() docs for your board

volatile int counter = 0;

long lastDebounce0 = 0;
long debounceDelay = 10;  // Ignore bounces under 10ms

volatile int
 CurrentPosition = 0, 
 goalPosition = 100;

boolean Extending = false;
boolean Retracting = false;

byte
  gearSelection,
  lastGearSelection,
  lastUp,
  lastDn,
  lastTM;
bool
  bTCCStatus;
unsigned long
  timeTCCSolenoid;

void actuatorExtend() {
  digitalWrite(relay1, HIGH);  // Always turn one off and then the other on
  digitalWrite(relay2, LOW);   // so that there are never two relays on (BIG!)
}

void actuatorRetract() {
  digitalWrite(relay2, HIGH);  // Always turn one off and then the other on
  digitalWrite(relay1, LOW);   // so that there are never two relays on (BIG!)
}
void actuatorStop() {
  digitalWrite(relay2, HIGH);
  digitalWrite(relay1, HIGH);
}


typedef struct structGearSolenoidProfiles {
  byte name;
  //byte    goalPosition;
  //byte    solenoid_A;
  //byte    solenoid_B;
  //byte    TC;

} sGearSolenoidProfiles;

//
const sGearSolenoidProfiles GearSolenoidProfiles[NUM_FWD_GEARS] = {
  {
    .name = 1,
    //   .goalPosition = 0,
    // .solenoid_A = LOW,
    //.solenoid_B = LOW,

  },
  {
    .name = 2,
    // .goalPosition = 200,
    // .solenoid_A = LOW,
    // .solenoid_B = HIGH,

  },
  {
    .name = 3,
    //  .goalPosition = 300,
    //   .solenoid_A = HIGH,
    // .solenoid_B = LOW,

  },
  {
    .name = 4,
    //  .goalPosition = 400,
    // .solenoid_A = LOW,
    // .solenoid_B = HIGH,

  },
  {
    .name = 5,
    //   .goalPosition = 400,
    //   .solenoid_A = HIGH,
    //  .solenoid_B = HIGH,

  },
  {
    .name = 6,
    //  .goalPosition = 400,
    //   .solenoid_A = HIGH,
    //  .solenoid_B = LOW,

  },
  {
    .name = 7,
    ///   .goalPosition = 400,
    //   .solenoid_A = LOW,
    //  .solenoid_B = LOW,

  },
  {
    .name = 8,
    //  .goalPosition = 400,
    //  .solenoid_A = HIGH,
    //   .solenoid_B = LOW,
    //   .TC= HIGH,
  }
};  //GearSolenoidProfiles[]
void setup() {
  pinMode(buttonUP, INPUT_PULLUP);
  lastUp = digitalRead(buttonUP);  //set initial button state
  pinMode(buttonDOWN, INPUT_PULLUP);
  lastDn = digitalRead(buttonDOWN);  //set initial button state
  pinMode(switchTOWMODE, INPUT_PULLUP);
  pinMode(transbrake, INPUT_PULLUP);
  pinMode(solA, OUTPUT);  //Solenoid A set as output
  pinMode(solB, OUTPUT);  //Solenoid B set as output
  pinMode(TCC, OUTPUT);   //TCC set as output
  pinMode(sloppy, OUTPUT);
  pinMode(HALL0, INPUT_PULLUP);  // hall is an input
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(3), trigger0, CHANGE); 


  digitalWrite(sloppy, HIGH);
  digitalWrite(solA, HIGH);  //set intital state as off
  digitalWrite(solB, HIGH);
  digitalWrite(TCC, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay1, HIGH);


  lcd.init();  // initialize the lcd
  lcd.backlight();

  lcd.print("No Airbags, we");
  lcd.setCursor(1,1);
  lcd.print("Die like Men");
  delay(5000);
  lcd.clear();
  lcd.print("Buckle UP,");
  lcd.setCursor(1,1);
  lcd.print("   BUTTERCUP!!");
  delay(5000);
  lcd.clear();
  lcd.print("     Paddle     ");

    //internal flag for TCC status
  bTCCStatus = false;
  gearSelection = 0;         // start in "1st" gear for this test
  lastGearSelection = 0xff;  //ensure we change into correct gear first pass by making last != current

  Serial.begin(9600);
 
}


void loop() {

  noInterrupts();
  CurrentPosition = counter;
  interrupts();
  Gear_Selection_Control();
  Gear_Solenoid_Control();
  //TCC_Control();
  transBrake();

  //  if (Extending == true && CurrentPosition > goalPosition);    //(GearSolenoidProfiles[gearSelection].goalPosition )) {
  //     //we have reached our goal, shut the relays off
  //     actuatorStop();
  //     Extending = false;
  //     //Serial.println(CurrentPosition);
       

  // if (Retracting == true && CurrentPosition < goalPosition);    //(GearSolenoidProfiles[gearSelection].goalPosition )) {
  //      //we have reached our goal, shut the relay off
  //      actuatorStop();
  //      Retracting = false;
  //    //  Serial.println(HALL0);
       

  if (CurrentPosition < goalPosition) {
    Retracting = false;
    Extending = true;
    actuatorExtend();
   
  } else if (CurrentPosition == goalPosition) {
    actuatorStop();
    Retracting = false;
    Extending = false;
   
  }
  if (CurrentPosition > goalPosition) {
    Retracting = true;
    Extending = false;
    actuatorRetract();
   
  } else if (CurrentPosition == goalPosition) {
    actuatorStop();
    Retracting = false;
    Extending = false;
  }

}  //loop

void transBrake() {
  buttonState = digitalRead(transbrake);
  if (buttonState != lastButtonState);
  if (buttonState == LOW) {
    digitalWrite(sloppy, LOW);
    Serial.print("Launch Control");
  } else {
    digitalWrite(sloppy, HIGH);
  }
}

void Gear_Selection_Control(void) {
  byte
    btnState;

  btnState = ReadButtons();
  switch (btnState) {
    case NO_PRESS:
      //nothing pressed or not read (interval not elapsed); no action
      break;

    case BUTTON_UP_PRESSED:
      if (gearSelection < (NUM_FWD_GEARS - 1))
        gearSelection++;
      //Serial.print(counter);

      break;

    case BUTTON_DOWN_PRESSED:
      if (gearSelection > 0)
        gearSelection--;

      break;

    default:
      //only remaining possibility is both pressed; ignore with no action
      break;

  }  //switch

}  //void

void Gear_Solenoid_Control(void) {
  if (gearSelection != lastGearSelection) {
    lastGearSelection = gearSelection;
    if ((GearSolenoidProfiles[gearSelection].name) == 1) {
      lcd.setCursor(1,1);
      lcd.print("     Park   ");
      digitalWrite(solA, HIGH);
      digitalWrite(solB, LOW);
      goalPosition = 0;
      digitalWrite(TCC, HIGH);
      Serial.println(goalPosition);
    }
    
    if ((GearSolenoidProfiles[gearSelection].name) == 2) {
       lcd.setCursor(1,1);
      lcd.print("    Reverse   ");
      digitalWrite(solA, LOW);
      digitalWrite(solB, LOW);
      goalPosition = 200;
      digitalWrite(TCC, HIGH);
      Serial.println(goalPosition);
    }
  
    if ((GearSolenoidProfiles[gearSelection].name) == 3) {
       lcd.setCursor(1,1);
      lcd.print("    Neutral  ");
      digitalWrite(solA, HIGH);
      digitalWrite(solB, LOW);
      goalPosition = 300;
      digitalWrite(TCC, HIGH);
      Serial.println(goalPosition);
    }
    
    if ((GearSolenoidProfiles[gearSelection].name) == 4) {
       lcd.setCursor(1,1);
      lcd.print("     First   ");
       lcd.setCursor(1,1);
      digitalWrite(solA, LOW);
      digitalWrite(solB, LOW);
      goalPosition = 400;
      digitalWrite(TCC, HIGH);
      Serial.println(goalPosition);
    }
    
    if ((GearSolenoidProfiles[gearSelection].name) == 5) {
       lcd.setCursor(1,1);
      lcd.print("    Second   ");
      digitalWrite(solA, HIGH);
      digitalWrite(solB, LOW);
      digitalWrite(TCC, HIGH);
      Serial.println(goalPosition);
    }

    if ((GearSolenoidProfiles[gearSelection].name) == 6) {
       lcd.setCursor(1,1);
      lcd.print("    Third    ");
      digitalWrite(solA, LOW);
      digitalWrite(solB, LOW);
      digitalWrite(TCC, HIGH);
    }
    
    if ((GearSolenoidProfiles[gearSelection].name) == 7) {
       lcd.setCursor(1,1);
      lcd.print("    Fourth    ");
      digitalWrite(solA, HIGH);
      digitalWrite(solB, LOW);
      digitalWrite(TCC, HIGH);
    }
    
    if ((GearSolenoidProfiles[gearSelection].name) == 8) {
       lcd.setCursor(1,1);
      lcd.print("    Fif'th    ");
      digitalWrite(solA, LOW);
      digitalWrite(solB, LOW);
      digitalWrite(TCC, LOW);
    }
  }
//  lastGearSelection = gearSelection;
//     digitalWrite( solA, GearSolenoidProfiles[gearSelection].solenoid_A );
//     digitalWrite( solB, GearSolenoidProfiles[gearSelection].solenoid_B );

}  //Gear_Control

// void TCC_Control(void) {
//   unsigned long
//     tNow;
//   bool
//     bTCCEnabled;

//   tNow = millis();

//   //TCC enabled if:
//   //  - 4th gear is engaged, OR
//   //  - 3rd gear is engaged and tow-mode not selected, AND
//   //  - TCC delay timer has expired
//   bTCCEnabled = ((gearSelection == 3) || ((gearSelection == 2 && digitalRead(switchTOWMODE) == HIGH))) && (tNow - timeTCCSolenoid >= TCC_DELAY);

//   //if conditions passed and TCC is now off, turn on its solenoid
//   if (bTCCEnabled) {
//     if (bTCCStatus == false) {
//       //turn on TCC
//       digitalWrite(TCC, HIGH);
//       bTCCStatus = true;

//     }  //if

//   }  //if
//   else {
//     if (bTCCStatus == true) {
//       //turn off TCC
//       digitalWrite(TCC, LOW);
//       bTCCStatus = false;

//     }  //if

  }  //else

}  //TCC_Control

//returns a mask:
//0b00000000 - no buttons pressed
//0b00000001 - up pressed
//0b00000010 - down pressed
//0b00000011 - both pressed
//
byte ReadButtons(void) {
  static unsigned long
    timeButton = 0;
  unsigned long

    tNow;
  byte
    retval,
    nowButton;

  retval = NO_PRESS;

  tNow = millis();
  if ((tNow - timeButton) >= BUTTON_READ_INTERVAL) {
    //set up for next read interval
    timeButton = tNow;

    //read the button and set the flags
    nowButton = digitalRead(buttonUP);
    if (nowButton != lastUp) {
      lastUp = nowButton;
      if (nowButton == LOW)
        retval |= BUTTON_UP_PRESSED;

    }  //if

    nowButton = digitalRead(buttonDOWN);
    if (nowButton != lastDn) {
      lastDn = nowButton;
      if (nowButton == LOW)
        retval |= BUTTON_DOWN_PRESSED;

    }  //if

  }  //if

  return retval;

}  //ReadButtons


void trigger0() {
  if (Extending == true) {
    counter++;
    //CurrentPosition = counter;
  }

  if (Retracting == true) {
    counter--;
    //CurrentPosition = counter;
  }
}

guess I can give more info in my setup if it matters. all the outs are ran to a relay module no motor shield involved for actuator. Actuator is powered seperatly through relays @12V for now I am using the lights on the relays to simulate SOLA SOLB and Tcc they will be 12v at relays when assembled figured the onboard LED for relay tells me they are opening and closing. I2c LCD is functioning perfectly as was the actuator for a little bit. when I say it bumps the ext everytime something happens on the uno it does just that you see the light on the relay flash for an instant and you see the actuator jump for an instant. Reason I know retract is working because all of those bumps of extend will advance my count so when you come back down to "park" goalPosition 0 it will engage retract and pull it back.