Getting error in RPM calculation???

I am trying to simulate gear changes on a motorcycle (that I am displaying on an LCD). For some reason, periodically the RPM calculation goes haywire (becomes very large). It is probably due to my misunderstanding on specifying the correct type of variable to use here.
Does anyone have any suggestions on what/why I may be seeing. I am posting my code, and some of the output over time…

//Global Variables...
float RPM;
int Gear;
long MPH;
This calculates the RPM of the engine for a specific Gear using linear interpolation between two points
  This assumes that we "Shift UP" at around 8000 Rpm (arbitrary #)
   Based on the Gear ratio's from Suzuki Madura manual...
   May want to speed this up by attempting to use integer math.??
   and not brake the calculation into several parts.... [b](DONE)[/b]
   This has some glitches in it, must be due to overflow's or
   some error in variable types. 
  Broke the calculation into two parts to see where error is occuring... still not making sense to me...
void GetGearRPM(int MPH)
 unsigned long Part1,Part2;
static long LastRPM;
    if (MPH>=0 && MPH <= 45) {
      Part1=MPH*8000;           //break into two parts to see what the error is?????
      Part2 = Part1/45;
      RPM = Part2 + 45;
    } else if (MPH >= 46 && MPH <= 64) {
      Part2 = Part1/18;
      RPM = Part2 + 64;
    } else if (MPH >= 65 && MPH <= 82) {
      Part2 = Part1/17;
      RPM = Part2 + 62;
    } else if (MPH >= 83 && MPH <= 100) {
      Part2 = Part1/17;
      RPM = Part2 + 100;
     } else if (MPH >= 101 && MPH <= 122) {
      Part2 = Part1/21;
      RPM = Part2 + 122;
     } else if (MPH >= 123 && MPH < 151) {
      Part2 = Part1/28;
      RPM = Part2 + 151;
     }  //end if

  Serial.print("  Gear[");
  if (RPM > 40000000) {
    RPM = LastRPM;
    Serial.print("  ERROR in RPM Calculation");
  LastRPM = RPM;
}   //end sub

The results I"m seeing…

Starting Large Font Demo Mode
Revision: V11-04/03/14
Showing Menu 1Speeding Up…
MPH=0 Gear[1] Part1=0 Part2=0 RPM=45.00--------------------

MPH=1 Gear[1] Part1=8000 Part2=177 RPM=222.00--------------------

MPH=2 Gear[1] Part1=16000 Part2=355 RPM=400.00--------------------

MPH=3 Gear[1] Part1=24000 Part2=533 RPM=578.00--------------------

MPH=4 Gear[1] Part1=32000 Part2=711 RPM=756.00--------------------

MPH=5 Gear[1] Part1=4294941760 Part2=95443150 RPM=95443192.00 ERROR in RPM Calculation--------------------

MPH=6 Gear[1] Part1=4294949760 Part2=95443328 RPM=95443376.00 ERROR in RPM Calculation--------------------

MPH=7 Gear[1] Part1=4294957760 Part2=95443505 RPM=95443552.00 ERROR in RPM Calculation--------------------

MPH=8 Gear[1] Part1=4294965760 Part2=95443683 RPM=95443728.00 ERROR in RPM Calculation--------------------

MPH=9 Gear[1] Part1=6464 Part2=143 RPM=188.00--------------------

MPH=10 Gear[1] Part1=14464 Part2=321 RPM=366.00--------------------

MPH=11 Gear[1] Part1=22464 Part2=499 RPM=544.00--------------------

MPH=12 Gear[1] Part1=30464 Part2=676 RPM=721.00--------------------

MPH=13 Gear[1] Part1=4294940224 Part2=95443116 RPM=95443160.00 ERROR in RPM Calculation--------------------

MPH=14 Gear[1] Part1=4294948224 Part2=95443293 RPM=95443336.00 ERROR in RPM Calculation--------------------

MPH=15 Gear[1] Part1=4294956224 Part2=95443471 RPM=95443520.00 ERROR in RPM Calculation--------------------

MPH=16 Gear[1] Part1=4294964224 Part2=95443649 RPM=95443696.00 ERROR in RPM Calculation--------------------

MPH=17 Gear[1] Part1=4928 Part2=109 RPM=154.00--------------------

MPH=18 Gear[1] Part1=12928 Part2=287 RPM=332.00--------------------

MPH=19 Gear[1] Part1=20928 Part2=465 RPM=510.00--------------------

MPH=20 Gear[1] Part1=28928 Part2=642 RPM=687.00--------------------

MPH=21 Gear[1] Part1=4294938688 Part2=95443081 RPM=95443128.00 ERROR in RPM Calculation--------------------

MPH=22 Gear[1] Part1=4294946688 Part2=95443259 RPM=95443304.00 ERROR in RPM Calculation--------------------

MPH=23 Gear[1] Part1=4294954688 Part2=95443437 RPM=95443480.00 ERROR in RPM Calculation--------------------

MPH=24 Gear[1] Part1=4294962688 Part2=95443615 RPM=95443664.00 ERROR in RPM Calculation--------------------

MPH=25 Gear[1] Part1=3392 Part2=75 RPM=120.00--------------------

MPH=26 Gear[1] Part1=11392 Part2=253 RPM=298.00--------------------

MPH=27 Gear[1] Part1=19392 Part2=430 RPM=475.00--------------------

MPH=28 Gear[1] Part1=27392 Part2=608 RPM=653.00--------------------

MPH=29 Gear[1] Part1=4294937152 Part2=95443047 RPM=95443088.00 ERROR in RPM Calculation--------------------

MPH=30 Gear[1] Part1=4294945152 Part2=95443225 RPM=95443272.00 ERROR in RPM Calculation--------------------

MPH=31 Gear[1] Part1=4294953152 Part2=95443403 RPM=95443448.00 ERROR in RPM Calculation--------------------

MPH=32 Gear[1] Part1=4294961152 Part2=95443581 RPM=95443624.00 ERROR in RPM Calculation--------------------

MPH=33 Gear[1] Part1=1856 Part2=41 RPM=86.00--------------------

MPH=34 Gear[1] Part1=9856 Part2=219 RPM=264.00--------------------

MPH=35 Gear[1] Part1=17856 Part2=396 RPM=441.00--------------------

MPH=36 Gear[1] Part1=25856 Part2=574 RPM=619.00--------------------

MPH=37 Gear[1] Part1=4294935616 Part2=95443013 RPM=95443056.00 ERROR in RPM Calculation--------------------

MPH=38 Gear[1] Part1=4294943616 Part2=95443191 RPM=95443232.00 ERROR in RPM Calculation--------------------

MPH=39 Gear[1] Part1=4294951616 Part2=95443369 RPM=95443416.00 ERROR in RPM Calculation--------------------

MPH=40 Gear[1] Part1=4294959616 Part2=95443547 RPM=95443592.00 ERROR in RPM Calculation--------------------

MPH=41 Gear[1] Part1=320 Part2=7 RPM=52.00--------------------

MPH=42 Gear[1] Part1=8320 Part2=184 RPM=229.00--------------------

MPH=43 Gear[1] Part1=16320 Part2=362 RPM=407.00--------------------

MPH=44 Gear[1] Part1=24320 Part2=540 RPM=585.00--------------------

MPH=45 Gear[1] Part1=32320 Part2=718 RPM=763.00--------------------

MPH=46 Gear[2] Part1=0 Part2=0 RPM=64.00--------------------

MPH=47 Gear[2] Part1=2400 Part2=133 RPM=197.00--------------------

MPH=48 Gear[2] Part1=4800 Part2=266 RPM=330.00--------------------

MPH=49 Gear[2] Part1=7200 Part2=400 RPM=464.00--------------------

MPH=50 Gear[2] Part1=9600 Part2=533 RPM=597.00--------------------

MPH=51 Gear[2] Part1=12000 Part2=666 RPM=730.00--------------------

MPH=52 Gear[2] Part1=14400 Part2=800 RPM=864.00--------------------

MPH=53 Gear[2] Part1=16800 Part2=933 RPM=997.00--------------------

MPH=54 Gear[2] Part1=19200 Part2=1066 RPM=1130.00--------------------

MPH=55 Gear[2] Part1=21600 Part2=1200 RPM=1264.00--------------------

MPH=56 Gear[2] Part1=24000 Part2=1333 RPM=1397.00--------------------

MPH=57 Gear[2] Part1=26400 Part2=1466 RPM=1530.00--------------------

MPH=58 Gear[2] Part1=28800 Part2=1600 RPM=1664.00--------------------

MPH=59 Gear[2] Part1=31200 Part2=1733 RPM=1797.00--------------------

That is not all of your code. You need to post ALL of it.


MPH is an integer, 5 * 8000 = 40000 which overflows an integer. It doesn't matter that the result type is a long integer, if all parts of the calculation are integers, the calculation is done in integer and afterwards converted to a long integer. That's exactly what you're seeing.

I have no idea what you’re trying to achieve with the calculations using Part1 and Part2. I can’t think of any reason why it would be sensible to carry out a linear scaling in two steps like this, and the two steps you are using do not look to me as if they will actually do linear scaling. The whole thing looks totally bizarre.

I assume you have got a sequence of MPH readings and you are trying to predict what gear would have been selected at each point.

One way to do this is to assume that gear changes always occur at consistent speeds. That seems to be what you’re doing here, but the arithmetic you’re using to do that looks nonsensical. Having used the MPH threshold to guess what gear is selected, you just need to multiply the MPH by the appropriate factor for that gear to calculate the corresponding RPMs.

By the way, since the speed ranges are not overlapping, you can simplify the threshold comparisons like this:

if(MPH < 0)
else if(MPH < 46)
else if (MPH < 65)
else if (MPH < 83)

Thank you Pylon, I knew it was probably something simple. I will give that a try.

Peter H. For a given MPH A to B, I know with a specific gear I have an RPM X to Y. The code just coverts the input MPH, to the corresponding RPM (between X & Y). a linear interpretation.
A = 10 MPH X=1000RPM
| |
@ 20 MPH Find RPM (based on 20MPH)
| |
B= 50 MPH Y= 2000 RPM

Calculation (50-10)/(20-10) = (200-1000)/(RPM - 1000), solve for RPM
That is what I am trying to do. Thank you for your reply!

A = 10 MPH X=1000RPM
| |
@ 20 MPH Find RPM (based on 20MPH)
| |
B= 50 MPH Y= 2000 RPM

If I solve that for RPM I get:

RPM = (MPH-10) * 25 = MPH * 25 - 250

Did I miss something?

PeterH was right with his suggestion, he just got the wrong numbers:

if(MPH < 46)
else if(MPH < 65)
else if (MPH < 83)
else if (MPH < 101)

A = 10 MPH X=1000RPM
| |
@ 20 MPH Find RPM (based on 20MPH)
| |
B= 50 MPH Y= 2000 RPM

This is a strange gearing system. How is it that speed is not directly proportional to RPM in each gear?

This is a strange gearing system. How is it that speed is not directly proportional to RPM in each gear?

That was just an example to show us what he calculates which didn't use the actual values. At least he made clear how he gets to the calculations.
But it's interesting that he has the same set-offs in his sketch too. So he must have an ultra-modern hybrid motorbike that has an additional electrical motor which acts as a generator while driving in that speeds, connected by a epicyclic gearing so the RPMs got lost there. Or the clutch is so old that he looses there so much rounds.

That was just an example to show us what he calculates which didn't use the actual values.

The fact that the input and output are not proportional to each other was in the original code, too. This is not how a conventional geared transmission behaves which makes me question what the algorithm is trying to do.

This was an attempt to simulate shifting, to show MPH vs Gear vs RPM on a display I am putting together for a motorcycle. With the info on Gearing (Primary => Secondary => Tranny => Final) and wheel dia. was trying to simulate a proper RPM based on speed ing up/down 0-150MPH. Since this discussing and the confusion it generated, I decided to take a closer look at my methodology. I put the numbers into a spreadsheet and plotted out the RPM vs MPH for each Gear. Then used this new data (along with a linear trend-plot) to come up with a better calculation. Thank you all for the discussion, and giving me some new ideas.
And for the simplification of the if-then-else statements, your suggestion is of course much simpler!

In that case a sequence of range checks with a simple scale factor for each range would be the simplest approach.

If you're aiming for realism, typically the shift points on up shifts and down shifts are not the same, so you would need to use a different set of ranges depending whether you were accelerating or decelerating.

One way to implement that would be to make the display statefull (make it remember which gear is engaged) and then change up or down as required as the speed changes to keep the rpm within a specified range. This would more closely model how a rider typically manages gear selection, and would give a more realistic outcome in scenarios other than a simple 0-150-0 sprint.

I will take the motorcycle out this weekend, to see what shift points I use (not necessarily optimal). Then modify the demonstration mode of the sketch. I’ve attached a video of what I have, based on previous feedback from everyone. This reflects just one possible operating mode for a computer display interface I’m creating for an older motorcycle… As a newbie to Arduino (and not combing from a C++ background), this is very much a learning process (as reflected by previous use of int vs long in calculation). One other aspect of this is learning when (and how) to use character array’s. I’m trying to avoid strings, but this part is confusing to me… the work goes on!

(sorry for grainey display, but reduces quality to fit in 4K attachment limit).

Madura SpeedOmeter-v3.mp4 (2.94 MB)