Help needed with a gearbox shifting sketch

Hey guys

I decided to try attempt a project that involves 4 solenoids and rams to shift an H pattern Gearbox.

Basically when it starts up it checks a number of limit switches and depending on what gear its in it’ll bump it into neutral. Then when button 1 pressed it will activate solenoids in a sequence to move up a gear (ive got this far and it works good on breadboard) it also displays what gear your in via a 7 segment display.

The problem im stuck on is going back down the gears.

id like to use another button to go back down the gears but obviously the solenoid sequence will be different

Just cant get my head around it.

Don’t laugh too hard at my probably substandard coding :confused:

Ive just uploaded the loop section as it exceded the max forum post limit if I put the rest of it in

Thanks

Russell

void loop() 
{
  delay(10);
  lastState = ButtonState; 

  ButtonState = digitalRead(buttonPin);


  if(ButtonState && ButtonState != lastState)  // button latch, no debounce needed!!!!!

    if(count < 5) // This will check to see if the count is within a range of 0 - 5, and anything over that, it will reset count back to 0. Of course, this will happen anyways because count is a BYTE, and not an int or any other type.
      count += 1; // same as count = count + 1;
      
    else
      count = 0;
      Serial.print("Gear: ");
    Serial.println(count);

  lastState = ButtonState;   
  myButton=digitalRead(buttonPin);
  if (myButton==false) mySet = false; // set bolean to true

    else

  {
    if    (count == 0)
    { 
      digitalWrite(10, LOW);
      digitalWrite(11, LOW);
      digitalWrite(12, LOW);
      digitalWrite(13, LOW);
      lastState = ButtonState;  
    }

    else if(count == 1)

    { 
      digitalWrite(8, LOW);
      delay(500);          // move from neurtal to first
      digitalWrite(8, HIGH);
      digitalWrite(6, LOW);
      delay(500);
      digitalWrite(6, HIGH);



      digitalWrite(10, HIGH);
      digitalWrite(11, LOW);
      digitalWrite(12, LOW); //1
      digitalWrite(13, LOW);
      lastState = ButtonState;  

    }
    else if(count == 2)
    {
      digitalWrite(8, LOW);  
      digitalWrite(7, LOW);
      delay(500);
      digitalWrite(8, HIGH);
      digitalWrite(7, HIGH);   //Move from first to second


      digitalWrite(10, LOW);
      digitalWrite(11, HIGH);
      digitalWrite(12, LOW); //2
      digitalWrite(13, LOW);
      lastState = ButtonState;  
    }
    else if(count == 3)
    {
      digitalWrite(6, LOW);
      delay(500);
      digitalWrite(6, HIGH);
      digitalWrite(9, LOW);          //Move from second to third
      delay(500);
      digitalWrite(9, HIGH);
      digitalWrite(6, LOW);
      delay(500);
      digitalWrite(6, HIGH);

      digitalWrite(10, HIGH);
      digitalWrite(11, HIGH); //3
      digitalWrite(12, LOW);
      digitalWrite(13, LOW);
      lastState = ButtonState;  


    }
    else if(count == 4)
    {
      digitalWrite(7, LOW);
      delay(1000);            //Move from third to fourth
      digitalWrite(7, HIGH);

      digitalWrite(10, LOW);
      digitalWrite(11, LOW); //4
      digitalWrite(12, HIGH);
      digitalWrite(13, LOW);
      lastState = ButtonState;  

    }
    else if(count == 5)
    {

      digitalWrite(6, LOW);
      delay(500);
      digitalWrite(6, HIGH);
      digitalWrite(9, LOW);          //Move from fourth to fifth
      delay(500);
      digitalWrite(9, HIGH);
      digitalWrite(6, LOW);
      delay(500);
      digitalWrite(6, HIGH);

      digitalWrite(10, HIGH);
      digitalWrite(11, LOW);
      digitalWrite(12, HIGH); //5
      digitalWrite(13, LOW);
      lastState = ButtonState;  
    }
  }
  
  lastState = ButtonState;  
}

Heres the rest of the sketch above void loop

const int  buttonPin2 =A0; //Forwards Limit
const int  buttonPin3 =A1; //Reverse Limit
const int  buttonPin4 =4; //Right Limit
const int  buttonPin5 =5; //Left Limit

int buttonState = 0;
int buttonState1 =0;
int buttonState2 =0;
int buttonState3 =0;
int buttonState4 =0;
int buttonState5 =0;

const byte buttonPin =2; //gear up
const byte buttonPin1 =3; //gear down

byte ButtonState;
byte lastState = LOW;  //gear up
byte count = 0;
byte maxCount =5;

byte ButtonState1;
byte lastState1 = LOW; //gear down
byte count1 = 0;

boolean mySet = false;
boolean myButton;

boolean mySet1 = false;
boolean myButton1;

void setup()

{
  Serial.begin(9600);
  pinMode(6, OUTPUT); //Forwards Sol
  pinMode(7, OUTPUT); //Backwards Sol
  pinMode(8, OUTPUT); //Left Sol
  pinMode(9, OUTPUT); //Right Sol
  pinMode(10, OUTPUT); //A LCD 
  pinMode(11, OUTPUT); //B LCD
  pinMode(12, OUTPUT); //C LCD
  pinMode(13, OUTPUT); //D LCD
  pinMode(buttonPin, INPUT); //Gear up
  pinMode(buttonPin1, INPUT); //Gear Down
  pinMode(buttonPin2, INPUT); //Forwards limit
  pinMode(buttonPin3, INPUT); //Reverse limit
  pinMode(buttonPin4, INPUT); //Right limit
  pinMode(buttonPin5, INPUT); //Left limit


  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);  //Switched to ground relays pulled high to avoid switching when unit powered up.
  digitalWrite(9, HIGH);


  digitalWrite(10, HIGH);
  digitalWrite(11, LOW);
  digitalWrite(12, HIGH); //5
  digitalWrite(13, LOW);
  delay(400);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW); //4
  digitalWrite(12, HIGH);
  digitalWrite(13, LOW);
  delay(400);
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH); //3
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  delay(400);
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH);
  digitalWrite(12, LOW); //2
  digitalWrite(13, LOW);
  delay(400);
  digitalWrite(10, HIGH);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW); //1
  digitalWrite(13, LOW);
  delay(400);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  delay(400);



  buttonState2 = digitalRead(buttonPin2); 
  buttonState5 = digitalRead(buttonPin5);
  if (buttonState2 == HIGH && buttonState5 ==HIGH)  //Car is in Gear 1 and will be moved to neutral
  {
    digitalWrite(10, HIGH);
    digitalWrite(11, LOW);
    digitalWrite(12, LOW); //1
    digitalWrite(13, LOW);
    digitalWrite(7, LOW);
    delay(500);
    digitalWrite(7, HIGH);
    delay(10);
    digitalWrite(9, LOW);
    delay(500);
    digitalWrite(9,HIGH);


  }
  else{

    buttonState3 = digitalRead(buttonPin3); 
    buttonState5 = digitalRead(buttonPin5);
    if (buttonState3 == HIGH && buttonState5 ==HIGH)  //Car is in Gear 2 and will be moved to neutral 
    {
      digitalWrite(10, LOW);
      digitalWrite(11, HIGH);
      digitalWrite(12, LOW); //2
      digitalWrite(13, LOW);
      digitalWrite(6, LOW);
      delay(500);
      digitalWrite(6, HIGH);
      delay(10);
      digitalWrite(9, LOW);
      delay(500);
      digitalWrite(9,HIGH);

    }
    else{

      buttonState2 = digitalRead(buttonPin2); 
      buttonState4 = digitalRead(buttonPin4);
      if (buttonState2 == HIGH && buttonState4 == HIGH)  //Car is in Gear 5 and will be moved to neutral
      { 
        digitalWrite(10, HIGH);
        digitalWrite(11, LOW);
        digitalWrite(12, HIGH); //5
        digitalWrite(13, LOW); 
        digitalWrite(7, LOW);
        delay(500);
        digitalWrite(7, HIGH);
        delay(10);
        digitalWrite(8, LOW);
        delay(500);
        digitalWrite(8,HIGH);                                    



      }
      else{

        buttonState2 = digitalRead(buttonPin2);
        buttonState3 = digitalRead(buttonPin3);
        if (buttonState2 == HIGH && buttonState3 ==LOW)  //Car is in Gear 3 and will be moved to neutral
        {
          digitalWrite(10, HIGH);
          digitalWrite(11, HIGH); //3
          digitalWrite(12, LOW);
          digitalWrite(13, LOW);
          digitalWrite(7, LOW);
          delay(500);
          digitalWrite(7, HIGH);
          delay(50);

        }
        else{

          buttonState3 = digitalRead(buttonPin3); 
          buttonState4 = digitalRead(buttonPin4);
          if (buttonState3 == HIGH && buttonState4 == LOW)  //Car is in Gear 4 and will be moved to neutral
          {
            digitalWrite(10, LOW);
            digitalWrite(11, LOW); //4
            digitalWrite(12, HIGH);
            digitalWrite(13, LOW);
            digitalWrite(6, LOW);
            delay(500);
            digitalWrite(6, HIGH);
            delay(500);



          }
          else{


            buttonState2 = digitalRead(buttonPin2);
            buttonState3 = digitalRead(buttonPin3);
            buttonState4 = digitalRead(buttonPin4); 
            buttonState5 = digitalRead(buttonPin5);
            if (buttonState2 == LOW && buttonState3 ==LOW && buttonState4 ==LOW && buttonState5 ==LOW)  //Car is in Neutral already
            {  
              digitalWrite(10, LOW);
              digitalWrite(11, LOW);
              digitalWrite(12, LOW);
              digitalWrite(13, LOW);

            }
            else{
            }
          }
        }
      }
    }
  }
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
}


//Gear 1 will be left then forwards
//Gear 2 will be left then backwards
//Gear 3 will be forwards then right the forwards
//Gear 4 will be back then back
//Gear 5 will be forwards then right then forwards

//Gear detection will be as follows
//Gear 1 Will have Forwards and left limit on rear and right off
//Gear 2 Will have Backwards and left limit on Forwards and left will be off
//Gear 3 will have only forwards limit on left right and back will be off
//Gear 4 will have only backwards limit on Left right and forwards will be off
//Gear 5 will have Forwards and right limit on Backwards and Left will be off
// no limit signal will be neutral

// Needs to figure out what gear it is in then move to Neutral when powered on.

Hi,

Welcome to the forum.

Just looking at your code , you need to assign names to outputs 6 to 13.

int ForwardSol = 6;

pinMode(ForwardSol, OUTPUT);

Also buttonPin replace with GearUp buttonPin1 replace with GearDown etc, this way you will not need lengthy comments.

Give them names that say what they do, this will help with some of your confusion.

Will you be allowing for clutch activation, that is you have a clutch switch, so you can't change gears unless the clutch is depressed.

Tom.. :)

Thanks for the welcome :)

I will go through and change it to make more sense. As you can tell ive used the names from examples ive read.

Not thought about a clutch switch yet as I will be experimenting with this in my race car.

For now I'd like to get the sketch working so the solenoids will activate in the correct sequence for going back down gears when the down button pressed.

Hi, Okay, no worries, I presume you only want sequential gear changes.

Tom... :)

You’ll have to consider 2 buttons, say shiftUp and shiftDown, and the current gear (count variable?). Then add another if statement to cover the new actions.

if (shiftUp)
{
  your existing code goes here
}
else if (shiftDown)
{
  do sanity check
  insert equivalent code for the other direction here
}

You also can use a single shiftCount variable, which is set to +1 (up) or -1 (down) by the buttons, and to zero if all done or illegal move rejected.

colecustoms: Not thought about a clutch switch yet as I will be experimenting with this in my race car.

If this is intended for a real car you might usefully read through this Thread - especially the many cautionary comments.

The fact that you are using buttons and your brain to decide when to shift gears does greatly simplify matters.

If you need a sequence of solenoid actions to cause a gear change it may be useful to store the sequence in an array for up moves and another array for down moves - for example

up[1] = [{-1,2,-5}];
up[2] = [{2,-6,7}];

down[1] = [{5,-2,1}];
//etc

I may have my array syntax wrong and the contents are just number plucked from the air.

My idea is that your button would cause the system to note (for example) that the second up-shift is required and the actual function that moves all the solenoids would then take its data from array up[2]. The exact same function could also handle a down-shift by using the data in the relevant down[n] array.

Hope that makes some sense.

...R

Thanks for your replay.

ive had a read through the thread mentioned and i understand the concerns raised.

I like this idea and can kind of see how it will work.

What id like to try to achieve with what ive written so far is.

say count = 3 (gear 3) i press the down shift button instead of count moving back to count 2 and outputting the count 2 sequence (as this will be incorrect for going from gear 3 to gear 2) it needs to do a different sequence ( down solonid , left solonoid , down solonoid ,

count will still need to = 2 afterwards as if i want to go back up a gear it will need to goto count = 3

This is where im stuck and cant get me head around it.

Cheers

Russell

Robin2: If this is intended for a real car you might usefully read through this Thread - especially the many cautionary comments.

The fact that you are using buttons and your brain to decide when to shift gears does greatly simplify matters.

If you need a sequence of solenoid actions to cause a gear change it may be useful to store the sequence in an array for up moves and another array for down moves - for example

up[1] = [{-1,2,-5}];
up[2] = [{2,-6,7}];

down[1] = [{5,-2,1}]; //etc



I may have my array syntax wrong and the contents are just number plucked from the air.

My idea is that your button would cause the system to note (for example) that the second up-shift is required and the actual function that moves all the solenoids would then take its data from array up[2]. The exact same function could also handle a down-shift by using the data in the relevant down[n] array.

Hope that makes some sense.

...R

colecustoms: count will still need to = 2 afterwards as if i want to go back up a gear it will need to goto count = 3

This is where im stuck and cant get me head around it.

I can't say I understand what you are trying to say.

Have you considered comparing the existing setting (say 3) with the new setting (2?) and doing something different because 2 is smaller than 3. Whereas for the upshift from 1 to 2 the destination will be bigger than the current setting.

Another way of thinking about it is that the UP button produces a +1 and the DOWN button produces a -1 either of which is added to the current setting to get the new setting.

...R

I bet you can't! haha this is why im so confused i know in my mind what needs to happen its just making it happen thats frustrating me.

as the code sits at the moment it works fine. It goes through reads the limit switches and bumps it into neutral.

Then i can press the gear up button it will count from 0 to 1 and activate the solenoids in the correct sequence to go from neutral to first gear.

it fires the left solenoid for half a second then fires the forwards solenoid for half a second then they turn off.

it then waits for the button to be pressed again

once you press it again it counts from 1 to 2 and fires the left and backwards solenoid they turn off and it waits again.

ive got no idea how to make it count down with another button.

one thing that bugs me is I dont want the count to decress from say 3 to 2 then it do what ive written in the count 2 section i want it to be something like if count = 3 - 1 do ......xyz (the correct solenoid sequence for going from gear 3 to gear 2)

Thanks :)

Robin2: I can't say I understand what you are trying to say.

Have you considered comparing the existing setting (say 3) with the new setting (2?) and doing something different because 2 is smaller than 3. Whereas for the upshift from 1 to 2 the destination will be bigger than the current setting.

Another way of thinking about it is that the UP button produces a +1 and the DOWN button produces a -1 either of which is added to the current setting to get the new setting.

...R

Hi, To help you keep your code structured you need to look up functions in the arduino reference.

you would have a function for - up 0 to1 - up 2 to 3 - etc - down 4 to 3 - down 3 to 2 - etc

You then decide which function to use depending on where the gear is and if you want to go up or down.

How many gears do you have in what configuration?

You code is all in one flow at the moment that makes following it hard. Functions for the actual changes will make it simpler to read and debug/edit in the long run.

Tom... :)

Yeah sorry about that im new to this whole programing thing functions sound like they will work but im unsure how to call apon them with 2 buttons.

so youd say i would still have a count so if gear up pressed call apon function 0-1, press gear up again it would call apon function 1-2, press gear down and it would call apon function 2-1.

i will put all my solenoid sequences into groups then I hope with help from you guys I will get this code worked out and can then continue on with some real life testing (insted of just watching leds blink haha)

:)

TomGeorge: Hi, To help you keep your code structured you need to look up functions in the arduino reference.

you would have a function for - up 0 to1 - up 2 to 3 - etc - down 4 to 3 - down 3 to 2 - etc

You then decide which function to use depending on where the gear is and if you want to go up or down.

How many gears do you have in what configuration?

You code is all in one flow at the moment that makes following it hard. Functions for the actual changes will make it simpler to read and debug/edit in the long run.

Tom... :)

colecustoms: one thing that bugs me is I dont want the count to decress from say 3 to 2 then it do what ive written in the count 2 section i want it to be something like if count = 3 - 1 do ......xyz (the correct solenoid sequence for going from gear 3 to gear 2)

That's what I was trying to deal with in Reply #8 - coupled with Reply #6.

You need to read up about the programming concept called a "state machine". It is a rather grand name for a simple idea. When your gear box is in (say) 2nd it is in a "state" and your button wants to move it to a different state.

...R