Making my own testbench

Hello,

I'm working on my own testbench to measure the power of a race engine
All my hardware is working, I'm now stumble with the software

First just a few pictures from stuff I already made.

http://img163.imageshack.us/img163/8646/09042012109.jpg
http://img442.imageshack.us/img442/3986/img181cy.jpg
http://img213.imageshack.us/img213/8867/02052012035.jpg
http://img248.imageshack.us/img248/2459/img037nv.jpg

The encoderdisc on the elektrical motor is for testing te program. This disc is also place on the drum of the testbench
The arduino board gets 2 signals; the rpm of the drum, and the rpm of the engine
Both pulses the arduino gets are good.

I using the code from the arduino site:

http://arduino.cc/playground/Learning/Tachometer

I have the code slightly modified so now the arduino reads 2 signals
I also downloaded software from parallax. This software reads the signals from arduino and then prints the values of the serial print in Excel.
This works just fine

Now only the following problems with the arduino code:

The encoderdisk has 100 notches. This means 100 pulses per revolution. The circumference of the drum is 1 meter. So if I calculate, the drum at 100 km/h makes 1667 rpm. That means 166,700 pulses in one minute, and that means 2778 pulses every second.
This should not be a problem for the arduino. It works fine if I only measure the rpm of the drum, but if i load the code in arduino with both readings, the rpm of the drum don’t go above 900 rpm. I know it's in the code, but how do I solve the problem?

Then the next problem. The Arduino sends 20 times in second a rpm update to excel. This is for the rpm of the drum not a problem, because he still receives enough pulses, but this updatespeed is too high voor the rpm reading of the engine. Set the engine turned 1500 rpm. This means 25 pulses at one second. But if he makes 20 times in one second an update, he’s gets 1.25 pulses. So 1 pulse per 0.05 sec. This produces a mega inaccurate measurement.

How can I modify my code so that I have the accurate measurement of 20 times in one second for the drum, but that the rpm of the engine updates 2 times in one second?

int val;
int valblok;
long last=0;
long lastblok=0;
int stat=LOW;
int statblok=LOW;
int stat2;
int stat2blok;
int contar=0;
int contarblok=0;

int sens=1000;  // this value indicates the limit reading between dark and light,
              // it has to be tested as it may change acording on the 
              // distance the leds are placed.
int nPalas=100; // the number of blades of the propeller
int nPalasblok=1;

int milisegundos=50; // the time it takes each reading
void setup()
{
  Serial.begin(128000);
  pinMode(50,OUTPUT);
  pinMode(51,OUTPUT);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Time,rpmrol,rpmblok");
}

void loop()
{
  val=analogRead(3);
  if(val<sens)
    stat=LOW;
   else
    stat=HIGH;
   digitalWrite(50,stat); //as iR light is invisible for us, the led on pin 13 
                          //indicate the state of the circuit.

   if(stat2!=stat){  //counts when the state change, thats from (dark to light) or 
                     //from (light to dark), remmember that IR light is invisible for us.
     contar++;
     stat2=stat;
   }
  valblok=analogRead(2);
  if(valblok<sens)
    statblok=LOW;
   else
    statblok=HIGH;
   digitalWrite(51,statblok); //as iR light is invisible for us, the led on pin 13 
                          //indicate the state of the circuit.

   if(stat2blok!=statblok){  //counts when the state change, thats from (dark to light) or 
                     //from (light to dark), remmember that IR light is invisible for us.
     contarblok++;
     stat2blok=statblok;
   }
   
   if(millis()-last>=milisegundos){
     double rpmrol=((double)contar/nPalas)/2.0*60000.0/(milisegundos);
     double rpmblok=((double)contarblok/nPalasblok)/2.0*60000.0/(milisegundos);
     Serial.print("DATA,TIME,"); Serial.print(rpmrol); Serial.print(","); Serial.println(rpmblok);
     contar=0;
     contarblok=0;
     last=millis();
   }
}

Has somebody a solution for me?

Sincerely,

Jordy Laan

This means 100 pulses in 1 rpm

No, this means there are 100 pulses per revolution
How many pulses there are in one minute is a different matter.

You're totally right.

Thnkx :slight_smile:

An analog read takes 104 uS. At 2778 pulses per second you have 360 uS between pulses. This is OK, but when you are reading two, your time is being used up.

Can you do a digital read? Or make a comparator circuit with an op amp?

Example here: Gammon Forum : Electronics : Operational Amplifiers : How to use an op-amp as a comparator

The digital read will be much faster.

I have also a program that send the pulses the encoderdisc make in 0,05 sec to Excel
This works fine, but calculate te pulses to rpm in excel gives not a accurate measurement.
I think that the solution is to combine the two codes, am I right ? But how I do that

unsigned long begintijd = millis();
unsigned long begintijd1 = millis();
unsigned int pulsen = 0;
unsigned int pulsen1 = 0;
 
const int Sensor = 23;
const int Sensor1 = 24;
 
void setup(){
  pinMode(Sensor, INPUT);
  pinMode(Sensor1, INPUT);
  Serial.begin(128000);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Time,pulsen,pulsen1");
}  
 
void loop(){ 
bool prevdetectorstate = digitalRead(Sensor);
bool detectorstate;
begintijd = millis();
 
while ((millis() - begintijd) < 50) {
  detectorstate = digitalRead(Sensor);
  if ((prevdetectorstate != detectorstate) && (detectorstate == true)) {
      pulsen++;
  }
  prevdetectorstate = detectorstate;
  }
bool prevdetectorstate1 = digitalRead(Sensor1);
bool detectorstate1;
begintijd1 = millis();
 
while ((millis() - begintijd1) < 50) {
  detectorstate1 = digitalRead(Sensor1);
  if ((prevdetectorstate1 != detectorstate1) && (detectorstate1 == true)) {
      pulsen1++;
  }
  prevdetectorstate1 = detectorstate1;
  }
 
  Serial.print("DATA,TIME,"); Serial.print(pulsen); Serial.print(","); Serial.println(pulsen1);

  pulsen = 0;
  pulsen1 = 0;
}

This works fine, but calculate te pulses to rpm in excel gives not a accurate measurement.

In what way?

I test it again, but i made a mistake, de reading of the drum is now accurate in Excel, but don't work for the rpm reading of te engine because 20 times in one second is to fast. There must be a way to update this rpm 2 times a second, instead of 20 times a second.

I believe that te code, I posted first is the best for accurate measurement for the drum
I tested both ways. In case of the pulses in excel the rpm can fluctuate 24 rpm. I think this is not accurate.
You can see that by the other measurement the rpm is fluctuate 6 rpm.
Do you think this differ can be neglected ?

I have nouw combine the 2 codes. Now i have a digital read. Measure up to 3000 rpm is not a problem anymore with 2 signals. :slight_smile:

Thank you for the advise

But the last problem is still standing.

Is it possible to keep the update speed of the drum at 20 timses per sec, but the update speed of the engine at 5 times per sec? That he continues to count the rpm of the engine and release this to the serial print 5 times per second.

unsigned long begintijd = millis();
unsigned long begintijd1 = millis();
unsigned int contar = 0;
unsigned int contar1 = 0;
int nPalas=100; // the number of blades of the propeller
int nPalas1=1; // the number of blades of the propeller
 
const int Sensor = 23;
const int Sensor1 = 24;
 
void setup(){
  pinMode(Sensor, INPUT);
  pinMode(Sensor1, INPUT);
  Serial.begin(128000);
  Serial.println("CLEARDATA");
  Serial.println("LABEL,Time,rpmrol,rpmblok");
}  
 
void loop(){ 
bool stat = digitalRead(Sensor);
bool stat2;
begintijd = millis();

bool stat1 = digitalRead(Sensor1);
bool stat21;
begintijd1 = millis();
 
while ((millis() - begintijd) < 50) {
  stat2 = digitalRead(Sensor);
  if ((stat != stat2) && (stat2 == true)) {
      contar++;}
      
      stat21 = digitalRead(Sensor1);
  if ((stat1 != stat21) && (stat21 == true)) {
      contar1++;
  }
  stat = stat2;
  stat1 = stat21;
  }
    
 
 double rpmrol=((double)contar/nPalas)/1.0*60000.0/50;
 double rpmblok=((double)contar1/nPalas1)/1.0*60000.0/50;
Serial.print("DATA,TIME,"); Serial.print(rpmrol); Serial.print(","); Serial.println(rpmblok);

  contar = 0;
  contar1 = 0;
}

Is it possible to keep the update speed of the drum at 20 timses per sec, but the update speed of the engine at 5 times per sec? That he continues to count the rpm of the engine and release this to the serial print 5 times per second.

Yes. Every 1/20th of a second, compute the drum speed, and print it. Every 4th time, compute the engine speed and print it, too.

That is an odd choice of baud rates that you have.

This are the baud rates i can choose in Parallax:

I understand what you mean with update separately, but i don't know how i do this in de code, can you pleas help me with that ?

That baud rate works nicely with 16MHz processors 16,000,000/128,000=125. Great project, BTW.