Motorcycle Gear Indicator

Hello,

I am building a gear indicator for my motorcycle. My main problem is that sometimes the shiftings are quite fast so I want my code to be as fast as possible because 1 gear up can take lets say 0.1 seconds.

I know my arduino (Uno) is fast enough for this but I dont know if my code is.

I also have a clock on the screen and a temp sensor. Does this slows my code so much?

Also I got an issue with the neutral gear. Going from the 1st to the 2nd gear will activate neutral gear for a few miliseconds. I though about adding a delay before I activate the neutral but this will slow down my code and will also not be stable as I cant be sure in puting 10ms or 100ms.

Note for gear I use 2 hall sensors. For the neutral I ll get the signal from the “neutral led” of the motorcycle.

Here is the main code. I would love any suggestions as I am still a newbie.

Thanks :slight_smile: :slight_smile:

void loop()
{ 
do //main loop
{
	
//=====code for clock=====//
  unsigned long currentMillis = millis();
  lcd.setBacklight(HIGH);
  lcd.setCursor (5,0); 
    if (RTC.hour < 10)                  
  {
    lcd.print("0");
    lcd.print(RTC.hour, DEC);
  }
  else
  {
    lcd.print(RTC.hour, DEC);
  }
    if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;  
    if (clockstate == HIGH){ 
        if (sensors.getTempCByIndex(1) < 6)
  {
      lcd.setCursor (13,0);
      lcd.print("!");
  }
      lcd.setCursor (7,0);
      lcd.print(":");
      clockstate = LOW;
    }
    else{  
        if (sensors.getTempCByIndex(1) < 6)
  {
      lcd.setCursor (13,0);
      lcd.print(" ");
  }
      lcd.setCursor (7,0);
      lcd.print(" ");
      clockstate = HIGH;
    }
  }
  lcd.setCursor (8,0); 
  if (RTC.minute < 10)                 
  {
    lcd.print("0");
    lcd.print(RTC.minute, DEC);
  }
  else
  {
    lcd.print(RTC.minute, DEC);
  }
  
  RTC.getTime();
  sensors.requestTemperatures();
  lcd.setCursor (14,0); 
  lcd.print(sensors.getTempCByIndex(1),0);
  
//========GEAR +=======//
  lcd.setCursor (7,1);
  lcd.print (gear);
  gearsin = digitalRead(gearsin);
  gearplin = digitalRead(gearplin);
  if (gearsin == LOW)
  {
  	gearstatesin = 1;
  }
  if (gearplin == LOW)
  {
  	gearstateplin = 1;
  }
} while (gearstatesin == 1 || gearstateplin == 1);
  
  if (gearstatesin == 1 != gear == 0) //1 gear up
  {
    gear = gear++;
    lcd.setCursor (7,1);
    lcd.print (gear);
    gearstatesin = 0;
  }
  if (gearstatesin == 1 && gear == 0) //1 gear up starting from neutral
  {
    gear = 2;
    lcd.setCursor (7,1);
    lcd.print (gear);
    gearstatesin = 0;
  }
	if (gearstateplin == 1 && gear !=0) //1 gear down NOT starting from neutral
	{
		gear = gear--;
		lcd.setCursor (7,1);
		lcd.print (gear);
		gearstateplin = 0;
	}
	if (gearstateplin == 1 && gear == 0) //1 gear down starting from neutral
	{
		gear = 1;
		lcd.setCursor (7,1);
		lcd.print (gear);
		gearstateplin = 0;
	}
  neutral = analogRead(analogPin); // checking for neutral
  if (neutral > 500)
  {
    delay(300);
  if (neutral >500)
  {
    gear=0;
  }
  }

}

I tried
to read your
code, but
I got
a headache
from it
jumping
all over the
place.

Use Tools + Auto Format to fix the piss-poor indenting, and post it again.

PaulS:
I tried
to read your
code, but
I got
a headache
from it
jumping
all over the
place.

Use Tools + Auto Format to fix the piss-poor indenting, and post it again.

I dont think it changed a lot using the “Auto Format”

void loop()
{
  do //main loop
  {

    //=====code for clock=====//
    unsigned long currentMillis = millis();
    lcd.setBacklight(HIGH);
    lcd.setCursor (5, 0);
    if (RTC.hour < 10)
    {
      lcd.print("0");
      lcd.print(RTC.hour, DEC);
    }
    else
    {
      lcd.print(RTC.hour, DEC);
    }
    if (currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;
      if (clockstate == HIGH) {
        if (sensors.getTempCByIndex(1) < 6)
        {
          lcd.setCursor (13, 0);
          lcd.print("!");
        }
        lcd.setCursor (7, 0);
        lcd.print(":");
        clockstate = LOW;
      }
      else {
        if (sensors.getTempCByIndex(1) < 6)
        {
          lcd.setCursor (13, 0);
          lcd.print(" ");
        }
        lcd.setCursor (7, 0);
        lcd.print(" ");
        clockstate = HIGH;
      }
    }
    lcd.setCursor (8, 0);
    if (RTC.minute < 10)
    {
      lcd.print("0");
      lcd.print(RTC.minute, DEC);
    }
    else
    {
      lcd.print(RTC.minute, DEC);
    }

    RTC.getTime();
    sensors.requestTemperatures();
    lcd.setCursor (14, 0);
    lcd.print(sensors.getTempCByIndex(1), 0);

    //========GEAR +=======//
    lcd.setCursor (7, 1);
    lcd.print (gear);
    gearsin = digitalRead(gearsin);
    gearplin = digitalRead(gearplin);
    if (gearsin == LOW)
    {
      gearstatesin = 1;
    }
    if (gearplin == LOW)
    {
      gearstateplin = 1;
    }
  } while (gearstatesin == 1 || gearstateplin == 1);

  if (gearstatesin == 1 != gear == 0) //1 gear up
  {
    gear = gear++;
    lcd.setCursor (7, 1);
    lcd.print (gear);
    gearstatesin = 0;
  }
  if (gearstatesin == 1 && gear == 0) //1 gear up starting from neutral
  {
    gear = 2;
    lcd.setCursor (7, 1);
    lcd.print (gear);
    gearstatesin = 0;
  }
  if (gearstateplin == 1 && gear != 0) //1 gear down NOT starting from neutral
  {
    gear = gear--;
    lcd.setCursor (7, 1);
    lcd.print (gear);
    gearstateplin = 0;
  }
  if (gearstateplin == 1 && gear == 0) //1 gear down starting from neutral
  {
    gear = 1;
    lcd.setCursor (7, 1);
    lcd.print (gear);
    gearstateplin = 0;
  }
  neutral = analogRead(analogPin); // checking for neutral
  if (neutral > 500)
  {
    delay(300);
    if (neutral > 500)
    {
      gear = 0;
    }
  }

}

I dont think it changed a lot using the "Auto Format"

Then you need to get your eyes examined.

Why are you printing the time and temperature to the LCD and then getting the current time and temperature?

    gear = gear++;

Absolutely not!

You can use

gear++;

or you can use

gear = gear + 1;

You can not use that crap you wrote.

  neutral = analogRead(analogPin); // checking for neutral

You are either in neutral or you are not. You can not be partly in neutral. Using an analog switch for digital purposes is nonsense.

    delay(300);

WTF?

  if (neutral > 500)
  {
    delay(300);
    if (neutral > 500)
    {
      gear = 0;

If the value in neutral was above 500, there is not a snowball's chance in hell that it won't still be above 500.

Does this slows my code so much?

Yes.

Also I got an issue with the neutral gear. Going from the 1st to the 2nd gear will activate neutral gear for a few miliseconds.

So?

If you ve ever drive a motorcycle with clutch you should know what I am looking for about the "neutral".

As for the rest of the replies thanks for the tips but you could be a bit more polite next time :slight_smile:

If you ve ever drive a motorcycle with clutch you should know what I am looking for about the "neutral".

Only about 750,000 miles in the last 30 years. Yes, the neutral light flashes going from 1st to 2nd, and from 2nd to 1st. But, so what? Showing Gear 1, Neutral, Gear 2 on the LCD will be accurate. Why do you want to show something else?

you could be a bit more polite next time

And you could indent your code properly, and comment it, before posting it. You could not take exception to the fact that code needs to look neat.

lets say I use:

+1 when I push the shift "up"
-1 when I push the shift "down"

if you push from 0 to 1st gear the indicator would be -1 (easy to solve)
if you push from 1st gear to second and the "gear" value becomes mementary 0 the indicator will show "1" insted of "2".

Thats why I need to "stay" a bit more on the neutral to confirm that the gear is really on neutral and not just "pass" from there.

I said from the start of the topic that I am a newbie so I think that there are thousands of ways to do this better and there will be obviously mistakes on my code (otherwise I would post it here).

thanks again for your time.

if you push from 1st gear to second and the "gear" value becomes mementary 0 the indicator will show "1" insted of "2".

I can up-shift from 1st to neutral or from 1st to 2nd. I presume that you can, too.

The key to knowing whether the up-shift was to neutral or to 2nd depends on how the hall-effect sensors are positioned. You have not explained that.

If the neutral light is not on, you must be in some gear. If you were in first, you shifted, and the neutral light is not on, then there is only one possibility.

PaulS:
I can up-shift from 1st to neutral or from 1st to 2nd. I presume that you can, too.

The key to knowing whether the up-shift was to neutral or to 2nd depends on how the hall-effect sensors are positioned. You have not explained that.

If the neutral light is not on, you must be in some gear. If you were in first, you shifted, and the neutral light is not on, then there is only one possibility.

yeah BUT...sometimes when I change from 1st to second the neutral light flashed momentary. So ,acording to my "idea", the momment that the ligh will flash the gear will go to "0" so the "up shift" will go to 1 instead of 2.

I think I have to think about a completely different code that this...

I use 2 hall sensors placed on the shift. One to determine the "up" and a second for the "down".

I use 2 hall sensors placed on the shift. One to determine the "up" and a second for the "down".

If the sensors are not placed so that you can tell the difference between shifting part way (to neutral) vs. all the way (to 2nd), then the sensors are not well positioned.

I like the idea of what you are doing, but apparently it is not all that easy. My Harley lights up an indicator when it is in neutral and another when it is in 6th. No other gear positions are shown.

My Aspencade showed what gear it was in, for every gear.

PaulS:
If the sensors are not placed so that you can tell the difference between shifting part way (to neutral) vs. all the way (to 2nd), then the sensors are not well positioned.

I like the idea of what you are doing, but apparently it is not all that easy. My Harley lights up an indicator when it is in neutral and another when it is in 6th. No other gear positions are shown.

My Aspencade showed what gear it was in, for every gear.

Well...I only need a way (if possible) to delay the input from the neutral...If I can do this everything will run smooth.

I though about putting a relay with a delay of 0.5 seconds to get the signal for the neutral in order to not "slow" my code more.

I dont know if there is any other way to force my arduino "read" an input after some time...

Looks like I ll have to use my brain a bit more...

PS My Honda got an indicator for the Neutral only. My main aim is the clock, but adding a temperature and a gear indicator would be great!

I dont know if there is any other way to force my arduino "read" an input after some time...

You can determine when it goes into neutral, by detecting the change from not-in-netral to in-neutral. The state change detection example shows how.

You can determine when it goes out of neutral. If the time is less than some amount, don't show that you were ever in neutral.

The blink without delay example shows how to record when an event happens.

Why is neutral light a problem? If you can accurately detect an upshift and a downshift of the gear lever, it's return to centre and the neutral light then internal to the code the gear numbers would go from -1 (first), 0 (neutral), 1 (second) and so on up to 5 (sixth). Just substitute these for gear numbers on the display.
If your in neutral and downshift it will be first gear. As you upshift, if the neutral light is still on when gear lever centres your back in neutral if the neutral light is not on then you must have moved through to second.
Resetting counter to zero if the neutral light comes on and gear lever is currently moved (off centre) then either increment or decrement counter when it returns to centre should work.

I had a Suzuki many many years ago with built in gear shift indicator but it never worked well as I could sometimes end up in 9th gear and that's hard to do with only 5 to start with. :confused: