Tacho Limited to 5800 rpm

Hi There,
KenF helped me a few months ago with this code to read rpm and a load cell

/*   Dyno
 *  Tachometer -- Load Cell
 * A status LED is connected to pin 12. 
 * Pin 2 (interrupt 0) is connected to Inductive pickup.
 * Pin A1 is conected to INA125 out. 
 //******************** Load Cell ***********************************
 // Load cells are linear. So once you have established two data pairs, you can interpolate the rest.
 //************ 325 ohm resister on INA125 chip ********
 // Step 1: Upload this sketch to your arduino board

 // You need two loads of well know weight. In this example A = 10 kg. B = 30 kg
 // Put on load A
 // read the analog value showing (this is analogvalA)
 // put on load B
 // read the analog value B

// Enter you own analog values here
float loadA = 00; // kg
int analogvalA = 520; // analog reading taken with load A on the load cell

float loadB = 40; // kg
int analogvalB = 775; // analog reading taken with load B on the load cell

// Upload the sketch again, and confirm, that the kilo-reading from the serial output now is correct, using your known loads

float analogValueAverage = 1;

// How often do we do readings?
//long time = 0; 
//int timeBetweenReadings = 100; // We want a Load cell reading every 500 ms;
int rpm_max = 0;                  // maximum rpm value
int load = 0;                     // calculated average value from load sensor
int torque_max = 0;               // maximum torque value
int torque_rpm = 0;               // maximum torque rpm
int Power = 0;                    // Power value
int Power_rpm = 0;                // Power rpm
int Power_max = 0;                // maximum Power value
int Power_max_rpm = 0;            // maximum Power value

#define PMS_PIN 2 // Pin for signal from Photomicrosensor
#define LED_PIN 13 //Using Arduino's Internal LED; just as an indicator

boolean counted=false;
//holds duration for each of the last 10 revolutions in microseconds
unsigned long int revs[10]={0ul,0ul,0ul,0ul,0ul,0ul,0ul,0ul,0ul,0ul};                
unsigned long int lastTime=100ul;   //start time of the current revolution
unsigned long int lastReport=0ul;    //Time that value was last reported

void setup()
  pinMode(PMS_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);  
  //debug change this speed
  Serial.println("CLEARDATA"); //clears any residual data
 // Serial.println("LABEL,Analog,Torque,RPM,Max RPM, Max Torque,Max Torque RPM,Hp,Hp RPM");
//Serial.println("LAEL,AnalogAverage,Load,rpm,rpm-MAX,torque-MAX, torque-max-rpm, Power, Power-rpm, Power-max, Power-max-rpm");
Serial.println("Average [REVS PER MIN]  [----LOAD(Torque)----]  [-------POWER------- ]");
Serial.println("Analogue[  Now:Max   ]  [  NOW:Max   at rpm  ]` [  NOW:MAX   at rpm  ]");


//current revolution will be discarded if this is false
bool inStep=false;
//state of line last time we looked at i

int lastState=0;

void loop() 
unsigned long int tNow=micros();
unsigned long int sfactor=tNow-lastTime;
int n;

//make a reading of the load cell
int analogValue = analogRead(1);
//debug remove this next line
// running average - We smooth the readings a little bit
analogValueAverage = 0.99*analogValueAverage + 0.01*analogValue; 

int currentState = digitalRead(PMS_PIN);
//now check for leading edge
if (currentState>lastState)
  {//only record this revolution if we caught the start of it  
    //ignore if too soon after last edge  
   if(sfactor > 10000)
if((tNow-lastReport)>250000ul)   //*****  how oftern to print ****

//int pagelength=0;
//this is where we report back to the user
void reportFindings()
unsigned int actualRevs=0;
int n;
inStep=false;  //discard the next rev in case we missed it's start
//We'll only accept the duration of the longest revolution
unsigned long int longestRev=0;
  if(revs[n]> longestRev)
//if engine has stopped array will have stopped updating
if (actualRevs > rpm_max)
   rpm_max = actualRevs;

int load = analogToLoad(analogValueAverage)*9.80665; // 9.80665 is to convert Kg to Nm    
    if (load < 10) load=0;  
    if (load > torque_max){ 
    torque_max = load;
    torque_rpm = actualRevs;  
    Power = (load*actualRevs/9.549);
    Power_rpm = actualRevs;


char report[100];
char floatString[10];
sprintf(report,"%s [%5d:%-5d ]  [%5d:%-5d at %5d]  [%5d:%-5d at %5d]",
    //Write it out to serial port
    Serial.print(analogValueAverage); Serial.print(",");
    Serial.print(load); Serial.print(", ");      //torque Nm
    Serial.print(actualRevs,DEC); Serial.print("RPM, "); //RPM
    Serial.print(rpm_max); Serial.print(", ");      //RPM Max
    Serial.print(torque_max); Serial.print(",");   //torque max
    Serial.print(torque_rpm); Serial.print(",");   //torque rpm
    Serial.print(Power); Serial.print("HP,");   // will be Hp ********
    Serial.print(Power_rpm); Serial.print(",");    //Hp rpm
    Serial.print(Power_max); Serial.print("HP,");   // will be Hp ********
    Serial.print(Power_max_rpm); Serial.println(",");    //Hp rpm
    digitalWrite(LED_PIN, digitalRead(PMS_PIN));

float analogToLoad(float analogval){

  // using a custom map-function, because the standard arduino map function only uses int
  float load = mapfloat(analogval, analogvalA, analogvalB, loadA, loadB);
  return load;

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

It works great but the tacho crashes above 5800 rpm
I only understand parts of the code.
I am guessing its a speed/timing problem with all of the averaging calculations

I really hope KenF is still around

The original post is at http://forum.arduino.cc/index.php?topic=269823.60

What do you mean crashes?


When we get to above 5750 to 5800 the tacho reads 2900-3000rpm