Gear indicator (manual H pattern)

Hi guys, Ive been working on a simple gear indicator for a manual H pattern type gearbox.

It uses 2 potentiometers to provide the Arduino with 0-5v on 2 of the analouge pins, to measure the x and y axis of the gear lever. The approprate digit is then displayed on a 7 segment.

Everything was going smoothly until I added the code for reverse, and now it displays r in both reverse and neutral (neutral should display n)

Its probably just a simple mistake somewhere, but i cant seem to figure it out.

//Gear indicator for 5 speed H pattern transmission (reverse next to 4th)
//Only 2 inputs needed! 
//1 poti for x axis (left right movement)
//1 poti for y axis movement (up down (or forward backward :s ))



int a = 2;  //For displaying segment "a"
int b = 3;  //For displaying segment "b"
int c = 4;  //For displaying segment "c"
int d = 5;  //For displaying segment "d"
int e = 6;  //For displaying segment "e"
int f = 7;  //For displaying segment "f"
int g = 8;  //For displaying segment "g"


int unsigned n; //neutral
int unsigned r; //reverse


  
// The following values are altered for calibration
const unsigned int Up    = 3;//voltage Y Axis between 3rd and neutral gearstick position
const unsigned int Down  = 2;//Vlotage Y Axis between 4th and neutral gearstick position
const unsigned int Left  = 2;//voltage X Axis between 1st and 3rd gearstick position
const unsigned int Right = 3;//Voltage x Axis between 3rd and 5th gearstick position




void setup()
{
  pinMode(A0, INPUT);  //x axis input
  pinMode(A1, INPUT);  //y axis input
  
  pinMode(a, OUTPUT);  //A
  pinMode(b, OUTPUT);  //B
  pinMode(c, OUTPUT);  //C
  pinMode(d, OUTPUT);  //D
  pinMode(e, OUTPUT);  //E
  pinMode(f, OUTPUT);  //F
  pinMode(g, OUTPUT);  //G
}



//Segment combinations for displaying each gear
void displayGear(int gear)
{
 if(gear !=1 && gear !=4 && gear !=n && gear !=r)
 digitalWrite(a,LOW);
  
 if(gear !=5 && gear !=n && gear !=r)
 digitalWrite(b,LOW);
  
 if(gear !=2  && gear !=r)
 digitalWrite(c,LOW);  
  
 if(gear !=1 && gear!=4 && gear !=n && gear !=r)
 digitalWrite(d,LOW); 
  
 if(gear!=1 && gear!=3 && gear!=4 && gear!=5)
 digitalWrite(e,LOW);  
  
 if(gear !=1 && gear !=2 && gear!=3 && gear !=n && gear !=r)
 digitalWrite(f,LOW); 
  
 if (gear !=1)
 digitalWrite(g,LOW);
}



  //to turn unused segments off
void turnOff()
{
  digitalWrite(a,HIGH);
  digitalWrite(b,HIGH);
  digitalWrite(c,HIGH);
  digitalWrite(d,HIGH);
  digitalWrite(e,HIGH);
  digitalWrite(f,HIGH);
  digitalWrite(g,HIGH);
}


void loop(){

  // read the input on analog pin 0:
  int xAxis = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float xPos = xAxis * (5.0 / 1023.0);
  
  // repeat for y axis
  int yAxis = analogRead(A1);
  float yPos = yAxis * (5.0 / 1023.0);
  
  
  

 
  
  
  if (yPos < Up && yPos > Down){
   //Neutral
    displayGear(n);
     }
	else if (xPos < Left && yPos > Up){
   //1st gear
      displayGear(1);
  }
 	else if (xPos < Left && yPos < Down){
   //2nd gear
      displayGear(2);
  }
  	else if (xPos > Left && xPos < Right && yPos > Up){
   //3rd gear
      displayGear(3);
  }
    else if (xPos > Left && xPos < Right && yPos < Down){
   //4th gear
      displayGear(4);
  }
    else if (xPos > Right && yPos > Up){
   //5th gear
      displayGear(5);
  }
    else if (xPos > Right && yPos < Down){
   //Reverse gear
      displayGear(r);
  }
    //Turn unused segments off
   turnOff();
  }

Im new to this and this is only my second Arduino project. Please let me know if I have done anything wrong with the code, if the layout is correct, and if there are any improvements that could be made ect.

You have a H type shifter. That looks like 4 gears, including the reverse, and neutral "in the middle". Is that correct?
Use the debug possibility provided by Serial Monitor ans Serial.print. In the code You print out the x_and Y- analog reading values caused by the gear shift. Easy test that can be performed inside the garage.

I built such a decoder using combined IR senders and receivers, and some easy mechanics and a Z80 based computer 30 years ago. It ran fault free for 10 years.

Hi, the gearbox is 5 speed plus reverse. There are some other arduino gear indicator projects on the web, but they are either for sequential gearboxes, or they use a switch or sensor for each position. I’m trying to get the job done using just 2 inputs rather than 6.

I forgot to mention, I haven’t built it yet, I’m just in the process of designing it on Tinkercad. Once it’s all working I’ll order the components and build it.

Im just a bit stumped, I can’t figure out why the 7 segment displays „r“ when the y and x position is in neutral. For some reason the c segment doesn’t show in neutral?

Okey. You need to detect 6 positions, like a dubble, H, like HH.
No problem.
Solve the pot arrangement for the gear shifter. I was hiding my one under the leather couver below the stick. It was slim but pots…..
Figure out the mechanics, build it and then do as I told, move the shifter to all possible positions and notice the A- and Y- pot values. I see no problem with that. As a matter of fact, a good solution that has al chanses to work well!

I had no idea you could make if statements without curly brackets.

mickymik:
Im just a bit stumped, I can’t figure out why the 7 segment displays „r“ when the y and x position is in neutral. For some reason the c segment doesn’t show in neutral?

Where are the values of 'r' and 'n' given? Help your future self and give the variables descriptive names.

rah1775:
I had no idea you could make if statements without curly brackets.

Only the next line is conditional of course.

if (foo)
doFoo(); //the if applies to this line only
doBar(); //this line will always run

I tend to use braces anyway, even if there's only one line following, so that one day when I add a second line I can't forget the braces since they're already there.

mickymik:
Hi guys, Ive been working on a simple gear indicator for a manual H pattern type gearbox.

It uses 2 potentiometers to provide the Arduino with 0-5v on 2 of the analouge pins, to measure the x and y axis of the gear lever. The approprate digit is then displayed on a 7 segment.

Next time maybe think about using hall effect sensors.
They could be activated by just the presence of the gear shift lever by placing a small magnet on the back of each hall effect which makes them detect the steel in the lever, acting like a switch.

Railroader:
Okey. You need to detect 6 positions, like a dubble, H, like HH.
No problem.
Solve the pot arrangement for the gear shifter. I was hiding my one under the leather couver below the stick. It was slim but pots……
Figure out the mechanics, build it and then do as I told, move the shifter to all possible positions and notice the A- and Y- pot values. I see no problem with that. As a matter of fact, a good solution that has al chanses to work well!

The mechanics are no problem, i have everything there worked out for that. I plan to build a similar system to this: Gear Indicator Project - Arduino Project Hub

dougp:
Where are the values of ‘r’ and ‘n’ given? Help your future self and give the variables descriptive names.

r and n are used just like 1-5. Nothing more than a digit that should be shown at a certain x-y position.

int unsigned n; //neutral
int unsigned r; //reverse

// ... //

//Segment combinations for displaying each gear
void displayGear(int gear)
{
 if(gear !=1 && gear !=4 && gear !=n && gear !=r)
 digitalWrite(a,LOW);
 
 if(gear !=5 && gear !=n && gear !=r)
 digitalWrite(b,LOW);
 
 if(gear !=2  && gear !=r)
 digitalWrite(c,LOW); 
 
 if(gear !=1 && gear!=4 && gear !=n && gear !=r)
 digitalWrite(d,LOW);
 
 if(gear!=1 && gear!=3 && gear!=4 && gear!=5)
 digitalWrite(e,LOW); 
 
 if(gear !=1 && gear !=2 && gear!=3 && gear !=n && gear !=r)
 digitalWrite(f,LOW);
 
 if (gear !=1)
 digitalWrite(g,LOW);
}


// ... //


void loop(){

// ... //

 if (yPos < Up && yPos > Down){
   //Neutral
    displayGear(n);
     }

// ... //

 else if (xPos > Right && yPos < Down){
   //Reverse gear
      displayGear(r);
  }

For me it makes sense, but if there is a better way to do it please explain, im very new to this :confused:

Next time maybe think about using hall effect sensors.
They could be activated by just the presence of the gear shift lever by placing a small magnet on the back of each hall effect which makes them detect the steel in the lever, acting like a switch.

It was also a thought, but i figure mouniting 2 poti’s is easier and better than 6 micro switches or 6 HALL sensors. Less cable and brackets and so on. Plus my car uses a linkage type shifter, the shifter goes through the floor. So whatever i do needs to be doable from only the top half of the shifter, what makes the poti’s the better option.

Is it possible the bug im experiencing has nothing to do with the code and is just a bug in Tinkercad?

The reason i ask is the following line that should hide segment c for "r" is actually hiding cegment c for "n"

if(gear !=2  && gear !=r)
 digitalWrite(c,LOW);

but everything else works fine.

Or is it possible that this needs to be written differently? :

int unsigned n; //neutral
int unsigned r; //reverse

Is it correct to use int unsigned for this purpose?

mickymik:
Or is it possible that this needs to be written differently? :

int unsigned n; //neutral

int unsigned r; //reverse




Is it correct to use int unsigned for this purpose?

It's not incorrect but, a refinement would be, since the values won't go over 255, to use a byte type - integers need two bytes. This saves one byte of RAM for each variable so declared.

The real problem, as I see it, is you're not assigning any values. The compiler assigns a default of zero for such.

So to correct this I could write:

int unsigned n = 0; //neutral
int unsigned r = 6; //reverse

(I tried this and it works!) but would this be the correct way? (Is this how you would do it?)

I’ve often been told in programming there are many ways to make something work, but few ways that are considered correct.

mickymik:
(Is this how you would do it?)

A lot is left to personal style. Seven people could get this assignment and there'd be seven interpretations. As long as there's a rational reason behind it it's OK (JMHO).

mickymik:
(Is this how you would do it?)

Again, JMO but the segment decoding seems awkward. I'd make an array of bytes where each represents a pattern to send to the segments. Then, once the gear is determined I'd use that as an index into the array to select the correct bit pattern. This should obviate the need for the turnOff function.

If you keep going and learn you'll see better/more efficient ways of doing things.

You use reverse logic when turning on segments. If You would use positive logic like this:
Change

if(gear!=1 && gear!=3 && gear!=4 && gear!=5)

Chnaged to
 digitalWrite(e,LOW); 
 if(gear== 0 || gear == 2 || gear== 6 )// Neutral, 2 or reverse
 digitalWrite(e,LOW);

That is easier to read in my opinion.

Where is the code making gear 1,2,3,4,5 appear?

mickymik:
The mechanics are no problem, i have everything there worked out for that. I plan to build a similar system to this: Gear Indicator Project - Arduino Project Hub

Rather complex mechanical setup compared to my suggestion.
I notice you have not built it yet.

bluejets:
Rather complex mechanical setup compared to my suggestion.
I notice you have not built it yet.

I could always mount a magnet to the bottom of the shifter, which is underneath the car. Build an elaborate mount for 6 hall sensors, that somehow magically doesn’t faul the tailshaft. Then drill a hole in my floor and run 8 wires to the Aurduino.

Or I could try and do it inside the car, but by the time I am high enough on the shifter to get a big enough range of movement for the to make the sensors or switches work I am no longer beneath the center console.

Or I can mount 2 potis inside the car next to the gear lever and run 3 wires to the Arduino.
3d Print some forks and a holding bracket, finished.

The mechanics of this are really the smallest undertaking.