How to use analogread() to get gear position on motorcycle

I am trying to figure out how to get the gear position on my bike by using the analogread() function, but I'm having trouble implementing the whole thing.

At this time, I know which wire to monitor to get the gear position and I know the approximate voltages for each gear as well. For reference, I've listed all the voltages for the gears below.

Gears:

  • 1st: ~3.0V
  • 2nd: ~2.5V
  • 3rd: ~2.0V
  • 4th: ~1.5V
  • 5th: ~1.1V
  • 6th: ~0.7V

What I would like to know is, how can I go from an analogread() raw output to a specific gear position. For tolerances, I am planning on using a +/- 0.20V window, so 1st gear would be 2.8-3.2V, etc.

I don't know of any look up tables that I could use to do something like this. I can do the calculations afterwards in the data file outputted, but would rather prefer doing it through the Arduino to save that step from happening.

Figure out the midpoints and use a nested if construct.

if > 0.9 then 6th
else if > 1.25 then 5th
else if > 1.85 then 4th

etc

aarg has the right idea but has it backwards. Try an input of 1.9 (3rd) to see that it is wrong. 1.9 is greater than 0.9 and thus will give 6th. You have to go from highest voltage to lowest voltage or reverse all of the comparisons and change all of the thresholds.

Better would be:

//
// position is the voltage, and gear is the result.
//
// error is a function that does something and then finishes with
// Serial.print("In error with position of ") ;
// Serial.println(position) ;
// while (true) ;
//
// so that the program gets stuck there.
//
//  This is the general idea, untested.
//
gear = 0 ;
if (position>3.2) error(position) ;
if (position>2.8) {
  gear = 1 ;
} else if (position>2.3) {
  gear = 2 ;
} else if (position>1.8) {
  gear = 3 ; 
} else ...
//
// etc.
//
//
// And if gear is still 0 after all of this then an error has occurred and the error function should
// be called.
//

Something like this? (untested of course);

With a 5 volt Arduino, the ADC results woud be:
3.0V   615
       563  midpoint
2.5    511
       460  midpoint
2      410
       386  midpoint
1.5    307
       225  midpoint
0.7    143

pseudo code:

if(ADC > 563)
  gear = 1;
else if(ADC > 460)
  gear = 2;
else if(ADC > 386)
  gear = 3;
  // etc.

edgemoron has data that leads to an even simpler solution because there is no need to convert to voltage prior to getting the gear position.

Thanks for the quick responses. I'll try this out and see how it goes.

fmemon:
I don't know of any look up tables that I could use to do something like this. I can do the calculations afterwards in the data file outputted, but would rather prefer doing it through the Arduino to save that step from happening.

How are you doing it with the datafile?

Do that in the Arduino code.

If you're doing the post-processing with some program it should be fairly easy to translate the code to the Arduino. If you're doing it manually, you need to write down the full list of steps you are doing to perform the conversion, then change that into code.

This is what I ended up doing [pretty much a copy-paste from edgemoron]

if (rGearVolt > 775)
        gearPos = 101;
      else if (rGearVolt > 563)
        gearPos = 1;
      else if (rGearVolt > 460)
        gearPos = 2;
      else if (rGearVolt > 358)
        gearPos = 3;
      else if (rGearVolt > 266)
        gearPos = 4;
      else if (rGearVolt > 184)
        gearPos = 5;
      else if (rGearVolt > 90)
        gearPos = 6;
      else if (rGearVolt < 89)
        gearPos = 99;

This is giving me the results that I’m looking for, so there is no post processing in the data files.

Unfortunately, this does not handle 89 or 90. Perhaps you intended:

if (rGearVolt > 775)
        gearPos = 101;
      else if (rGearVolt > 563)
        gearPos = 1;
      else if (rGearVolt > 460)
        gearPos = 2;
      else if (rGearVolt > 358)
        gearPos = 3;
      else if (rGearVolt > 266)
        gearPos = 4;
      else if (rGearVolt > 184)
        gearPos = 5;
      else if (rGearVolt > 90)
        gearPos = 6;
      else if (rGearVolt <= 90)  /*  NOTICE TWO CHANGES TO THIS LINE  */
        gearPos = 99;

vaj4088:
Unfortunately, this does not handle 89 or 90. Perhaps you intended:

if (rGearVolt > 775)

gearPos = 101;
      else if (rGearVolt > 563)
        gearPos = 1;
      else if (rGearVolt > 460)
        gearPos = 2;
      else if (rGearVolt > 358)
        gearPos = 3;
      else if (rGearVolt > 266)
        gearPos = 4;
      else if (rGearVolt > 184)
        gearPos = 5;
      else if (rGearVolt > 90)
        gearPos = 6;
      else if (rGearVolt <= 90)  /*  NOTICE TWO CHANGES TO THIS LINE  */
        gearPos = 99;

That’s a good point. I only added that line and the one that returns 101 for error catching, so I wasn’t thinking it through. I made the necessary changes.

Thanks!