Inertia Dyno

Hi.

I’m building a inertiadyno, a thing to measure power from engines. I use a big flyweel that is connected to the engine and i’m measuring the acceleration of the flyweel, and from that i can calculate engine power.
To measure the acceleration I need the time for each rotation of the drum. I’m building this one to work on high rev engines up to 30000rpm.
On each rotation i get a short pulse via a hall-sensor. This pulse should be detected by my arduino and start a timer that counts to next pulse comes, and then send this time to the computer for storage.

My problem is that the times i get from my arduino isnt right. I have done some test for low rpm like 2000rpm up to 4000rpm and the times i get for one rotation for 4000rpm isnt even half the time i get for one rotation for 2000rpm. (that should be twice as long) It seems like either my arduino doesnt detect the pulses from my hall-sensor, or that my hall-sensor doesnt give the correct pulses or that my computer cant handle the stream of information.

If anyone could help me with this it would be very appreciate!!

The things I use is:

Arduino atmege328
Honeywell hall-sensor (attached data-sheet)
Arduino-0022 in my computer
The pull-up resistor in my arduino
1k pull-up resistor between 5V supply and my hall-sensor
1uF capacitor between 5V supply and GND

I have attached a circuit diagram and a data-sheet for my hall-sensor.

Here’s the code I use:

#define mTimeBufferSize 64 // MUST only be 2^x value, such as 2, 4, 8, 16, 32, 64, 128

volatile unsigned long mTimesBuffer[mTimeBufferSize]; // Buffer to store values before they are sent over serial
volatile unsigned long mTimesBufferStorePtr=0; // Pointer into the buffer showing where we are currently storing values to.  Note this pointer does not loop over, it counts up continually
volatile unsigned long mTimesBufferSendPtr=0; // Pointer into the buffer showing where we are currently sending values over serial from.  Note this pointer does not loop over, it counts up continually

unsigned long lastSent = 0; // Used to hold the previous micros() value sent to the PC so the difference from current micros can be calculated

void setup()
{
  Serial.begin(115200); // Enable serial port communication at 115200 baud
  pinMode(2, INPUT); // Set digital pin 2 to an input pin
  attachInterrupt(0, onChangeX, RISING); // Setup interrupt 0 (which is on digital pin 2), triggered on a rising edge input, calling the onChangeX function
  digitalWrite(2, HIGH);
}


void loop()
{
 
  if(mTimesBufferSendPtr < mTimesBufferStorePtr)
  {
    // The send pointer is behind the store pointer so there must have been a value written that we can send

    Serial.println(mTimesBuffer[mTimesBufferSendPtr & (unsigned long)(mTimeBufferSize-1)] - lastSent); // Subtract the previous micros from this micros to get the pulse time and send across serial port

    lastSent = mTimesBuffer[mTimesBufferSendPtr++ & (unsigned long)(mTimeBufferSize-1)];
  }
}


// Function called on every interrupt
void onChangeX()
{
  mTimesBuffer[mTimesBufferStorePtr & (unsigned long)(mTimeBufferSize-1)] = micros(); // Put the current micros() value into the next space in the buffer
  mTimesBufferStorePtr++; // Increment the buffer store pointer to the next location
}

Honeywell Halleffekt.pdf (280 KB)

kopplingsschema.bmp (774 KB)

You might be interested in this post that is related to high resolution/speed counting. Check the last posted code. It works but, will require you to make changes to suit your needs.

http://arduino.cc/forum/index.php/topic,68163.0.html

Mark

Thanks Mark!

So you think it is the program that doesnt work?
What do you think about my circuit then, do you think it would work?

Johan

Can you test the ouput of the Hall sensor with a scope or logic probe ?

well, I dont have my scope here at the moment, it is at my country house, so i guess i dont have anything to se the nature of the pulse. But i know i reach a pulse every time i "slowly" rotate my drum so the tooth passes the hall-sensor.

When the drum rotates fast the pulse will be very short, isnt there a chance my arduino board doesnt get in to read the pulse?

When the drum rotates fast the pulse will be very short, isnt there a chance my arduino board doesnt get in to read the pulse?

You need to calculate how short. If the interrupt handler can’t complete in that time, you will miss events.

It seems like you should just be incrementing a counter in your ISR. In loop(), every 1/4 second, or whatever is appropriate, compute RPM based on number of pulses counted in that period of time.

It seems like you should just be incrementing a counter in your ISR. In loop(), every 1/4 second, or whatever is appropriate, compute RPM based on number of pulses counted in that period of time.

Do you mean that i should count what max RPM for my cicuit is, based on how many pulses i can catch during the interrupt? isnt there any way to know what time the interrupt takes?

I'm still not sure it is the program that is bad, maybe it is the circuit?

isnt there any way to know what time the interrupt takes?

Yes, but you really want to work this backwards. How much time does each interrupt function have? Given max RPM and number of pulses per revolution, you can figure out the time between pulses. The interrupt handler needs to complete in less time than that, allowing time for the interrupt processing code to operate, and still allow the rest of the code to do something (like compute RPM or acceleration or whatever).

So, what is max RPM, and how many pulses per revolution?

So, what is max RPM, and how many pulses per revolution?

Hi PaulS!

Let's say we start from 15000rpm. Then we have 250rps. For one pulse for each rotation it means i've got 250pulses per revolution. It gives me a time of 0.004sec for each revolution. That means my interrupt needs to do the work in less that 0.004sec right? How do I know if that works?

thanks

For one pulse for each rotation it means i've got 250pulses per revolution.

That should be 250 pulses per second, right?

4 milliseconds is a long time, to the Arduino. Each machine instruction takes 62.5 nano-seconds (1/16 millionth of a second per instruction). You can execute a lot of instructions in that time.

I'd try something like using direct port manipulation to toggle the state of a pin, with LED and resistor attached, each time the interrupt handler fires. Rotate the drum at varying speeds, and see if the LED flashes to match.

thank you again PaulS!

The code I use is a code i've got from a nother one who made similar dyno, so i quess it would work fine, but i cant be sure of course.

couldnt it be any other thing that makes it loose signals? I was wondering if the high-signal from my hall-sensor doesnt reach full strength or of the low-signal never reads as low?

I was not trying to say your code was good or bad. I just wanted you to know about the code that Mem helped me with.

Is this an gas/Nitro airplane engine you are putting on the dyno? Or is it an electric motor?

Mark

I was not trying to say your code was good or bad. I just wanted you to know about the code that Mem helped me with.


 Is this an gas/Nitro airplane engine you are putting on the dyno? Or is it an electric motor?

Mark

Hi Mark!

No no it wasnt what i thought you were trying to say, sry! I'd very appreciate your help! I hade a look at that code and it looked very difficult to me, and also I use duemilanove so i have to modify a lot to get i work with my arduino i guess. For how high frequencies did your code work good?

What do you think about my curcuit? I use wire that is about 1m long right now, maybe that could be a problem to?

Yes it is a Nitro engine, but not for airplane but cars. I have to get this work before i start building own exhaustsystems to get a look of how my systems works..

Thank you very much!!! :)

This is out of the datasheet:

Absolute
Maximum
Ratings
Supply Voltage (Vs) ±30 VDC continuous
Voltage Externally Applied
To Output (output high) –0.5 to +30 V
Output Current 40 mA sinking

The part that is important here is that your sensor is made to "sink". Meaning you need a pull-up resistor from your 5v to your pin 2 which you have done by setting pin 2 high. Then when your sensor is active it will sink the voltage from 5 volts down to nearly zero. I could not find an example but, you might want a .1uf capacitor between pin 2 and gnd to suppress noise.

My problem is that the times i get from my arduino isnt right. I have done some test for low rpm like 2000rpm up to 4000rpm and the times i get for one rotation for 4000rpm isnt even half the time i get for one rotation for 2000rpm. (that should be twice as long) It seems like either my arduino doesnt detect the pulses from my hall-sensor, or that my hall-sensor doesnt give the correct pulses or that my computer cant handle the stream of information.

It may not matter but, you may want your interrupt to be set for falling instead of rising. The sensor will sink voltage to 0 when your tooth is at the sensor and the voltage will return to 5v when the tooth is away.

On other note, I think the sensor in the datasheet is more expensive than necessary but, it will certainly be rugged. Depending on how permanent you want your dyno to be you can get hall effect sensors for under a dollar but, you will need to make a insulation/mounting system.

Mark

lindgren2011: Yes it is a Nitro engine, but not for airplane but cars. I have to get this work before i start building own exhaustsystems to get a look of how my systems works..

I am fairly ignorant about cars (I can do basic to moderate repair work, but that's about it - and I certainly have never played with high-performance stuff) - so forgive me if I come off wrong here...

  1. What is the flywheel made out of? At 15K+ RPM - if something went wrong, I wouldn't want to be nearby...
  2. Aren't nitro engines fairly expensive?
  3. Don't they make such a tool as an "Inertia Dyno" as you are attempting to build? Why are you building one if this is the case?
  4. Regarding items 2 and 3 - if there are existing manufacturers of "Inertia Dynos" - even if they are expensive, certainly it might be better to use a professional tool for your purposes?

Building such a machine would seem to me to be the equivalent of building your own oscilloscope for design and testing custom PCBs for a business need or something; certainly doable, but not really advisable. Obviously in my ignorance of engines, I must be missing something here...?

:)

I googled nitro engine dyno and came up with lots of interesting stuff.

Here is just one forum thread. http://www.rctech.net/forum/nitro-road/2354-nitro-engine-dyno.html

Hi crOsh

  1. What is the flywheel made out of? At 15K+ RPM - if something went wrong, I wouldn't want to be nearby...

It's not running att 15000rpm yet, but when it will it is a small steeldrum with a diameter of less than 1dm, so it wont be any problem.

  1. Aren't nitro engines fairly expensive?

Yes, but funny to work with!

  1. Don't they make such a tool as an "Inertia Dyno" as you are attempting to build? Why are you building one if this is the case?

Yes they do, but i think it's intresting to try build one of those, also it will be much cheaper to make one of my own than buy one. Of course it would be better to buy one professional but less fun for me...

The part that is important here is that your sensor is made to "sink". Meaning you need a pull-up resistor from your 5v to your pin 2 which you have done by setting pin 2 high. Then when your sensor is active it will sink the voltage from 5 volts down to nearly zero. I could not find an example but, you might want a .1uf capacitor between pin 2 and gnd to suppress noise.

I only have a 1uF capacitor, no 0.1uF at home, but i guess 1uF works good too? So you mean I dont need any pull-up except setting pin 2 high as I allready have done?

It may not matter but, you may want your interrupt to be set for falling instead of rising. The sensor will sink voltage to 0 when your tooth is at the sensor and the voltage will return to 5v when the tooth is away.

I tested to switch to FALLING and it seems to work better. But my problem still remains. If i'm right the program gives me times for each revolution in micro() secunds? if so, the counter must give me VERY wrong numbers because I got times like 26500mircosecunds for one revolution when i measuring my drilling machine running on halv speed around 800RPM. What could be wrong? I got a very clean signal and no random numbers coming up, but also when i'm running faster than 800RPM something happens because then the times stop updating!

Thank you very much so far!

Micros depend of interrupts and using then inside another interrupt will cause errors.
Just increment a variable inside the ISR and then calculate the RPM in the main loop.

I only have a 1uF capacitor, no 0.1uF at home, but i guess 1uF works good too? So you mean I don,t need any pull-up except setting pin 2 high as I already have done?

That capacitor should work for the noise and setting pin 2 high will work for the pull-up.

If you are using an electric drill make sure you keep the Arduino and related parts away from the drill because the drill can put-out noise and affect your readings.

Mark