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.begin(9600);
  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  
    if(inStep)
     {
    //ignore if too soon after last edge  
   if(sfactor > 10000)
     {for(n=1;n<10;n++)
           revs[n-1]=revs[n];
      revs[9]=sfactor;
      lastTime=tNow;
       inStep=true;  
     }
      
     }
   if(!inStep)
     {
      lastTime=tNow;
      inStep=true; 
     }
  }
if((tNow-lastReport)>250000ul)   //*****  how oftern to print ****
  reportFindings();
lastState=currentState;
}

//int pagelength=0;
//this is where we report back to the user
void reportFindings()
{
unsigned int actualRevs=0;
lastReport=micros();
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;
for(n=0;n<10;n++)
  if(revs[n]> longestRev)
    longestRev=revs[n];
if(longestRev>0)
 actualRevs=60000000ul/longestRev;
//if engine has stopped array will have stopped updating
if((micros()-lastTime)>200000)
  actualRevs=0;
if (actualRevs > rpm_max)
   rpm_max = actualRevs;
//Serial.println(rpm_max,DEC);

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;

    if(Power>Power_max)
      {Power_max=Power;
       Power_max_rpm=actualRevs;
      }

char report[100];
char floatString[10];
dtostrf(analogValueAverage,7,2,floatString);
sprintf(report,"%s [%5d:%-5d ]  [%5d:%-5d at %5d]  [%5d:%-5d at %5d]",
        floatString,
        actualRevs,rpm_max,
        load,torque_max,torque_rpm,              
        Power,Power_max,Power_max_rpm
        );      
   Serial.println(report);
    /*
    //Write it out to serial port
    Serial.print("DATA,");   
    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
    */
    delay(10);
    //************************************************
    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?

Mark

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