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