Engine Governor

I have been trying to design a engine governor to govern my lawnmower engine to 3600 rpm. I am using a replica Arduino uno. More advanced functions to account for starting and such would be nice to have after this basic function. The problem I have been having is in the sensing of the rpm. I have been attempting to use FreqMeasure, and I don't understand it well at all. I have been trying to use an inductance sensor in the form of a coil of wire with a magnet on the flywheel to measure engine rotation, but I don't know where to put the outputs. FreqMeasure says to use digital pin number 8 but I don't know what else to connect to. I assume using some other type of sensor would be better but I hoped I could make this simple setup work. Any help would be appreciated. Thanks for reading.

We have no idea what "FreqMeasure" is. Post a link to its documentation.

A common way to measure the speed of an IC engine is with a Hall-effect sensor detecting a magnet on the flywheel or something else attached to the crankshaft.

...R

You ARE working on the easy part of the project. The hard part is controlling the speed of the engine so you can reduce the speed to 3600 rpm or increase the speed to 3600 rpm, without cycling above and below your desired speed.

Paul

There should already be a governor on a lawnmower engine, although the regulatuion isn't going to be extremely accurate, since the load varies greatly.

bestdayever:
I have been trying to use an inductance sensor in the form of a coil of wire with a magnet on the flywheel to measure engine rotation, but I don't know where to put the outputs.

A variable reluctance sensor, the inductive sensor, you are using will need some signal processing with either something like a LM1815 or MAX9924 that will process the sinusoidal waveform into a nice square wave that the Arduino can safely handle. This can be avoided by using a hall sensor on the flywheel as it already outputs a logic level signal. From here you could keep using the FreqMeasure library, but as I am not super familiar with it I would just write a clever hardware interrupt with a timeout.

As others have said, controlling it to a desired RPM will be tricky, likely need to use a PI or PID controller, on the OEM engines I calibrate we typically use a PI controller.

-Klotzy_550

klotzy_550:
A variable reluctance sensor, the inductive sensor, you are using will need some signal processing with either something like a LM1815 or MAX9924 that will process the sinusoidal waveform into a nice square wave that the Arduino can safely handle. This can be avoided by using a hall sensor on the flywheel as it already outputs a logic level signal. From here you could keep using the FreqMeasure library, but as I am not super familiar with it I would just write a clever hardware interrupt with a timeout.

As others have said, controlling it to a desired RPM will be tricky, likely need to use a PI or PID controller, on the OEM engines I calibrate we typically use a PI controller.

-Klotzy_550

Remember the OP has written NOTHING about the lawn mower. Could be powered by a 2-cycle air cooled gasoline engine, or a 4-cycle air cooled gasoline engine, or a 4-cycle liquid cooled engine, or a Diesel engine, air or liquid cooled, or a some use the term " engine" it could be a battery powered electric motor.

Paul

AND, a “coil of wire & magnet” could generate voltage pulses high enough to damage an input pin, higher RPM = higher volts. Have you measured that voltage?

Thanks for all the help everyone! freqMeasure link:FreqMeasure Library, for Measuring Frequencies in the 0.1 to 1000 Hz range, or RPM Tachometer Applications

The code so far I believe will work if I can get a means of inputting rpm is as follows:

#include <Servo.h>
#include <FreqMeasure.h>
Servo myservo; // create servo object to control a servo

int frequency; // frequency
int val; // value
int pos; //position of servo
int potpin = 1;

void setup() {
FreqMeasure.begin(); // begin tracking frequency
myservo.attach(11); // attaches the servo on pin 9 to the servo object
Serial.begin(57600);
pos = 45; // posotion of servo
val = 120; // throttle 120 equals 3600
myservo.write(pos);
delay(1000); // wait till startup
if (frequency > 0) { // wait till the engine starts
delay(10);
else () {
Serial.print(val);
continue;
}
}
}

void loop() {

delay(50); // wait
frequency = FreqMeasure.read(); // read the frequency
//Serial.print(frequency);
//Serial.print(pos);

frequency = analogRead(1);
val = 120;

if (frequency < val && frequency > val-20) { // this is to make the servo make the throttle higher if the rpm is too low.
pos = pos+1;
myservo.write(pos);
delay(100);
}
else if (frequency > val && frequency < val +10) { // this is to make the throttle higher if the rpm is too high
pos = pos - 1;
myservo.write(pos);
delay(100);
}
else if (frequency <= 0) { // this is to kill the the throttle if there is a malfunction
pos = 0;
myservo.write(pos);
delay(2000);
}
else if (frequency > 0 && frequency <= val-20) { // this is to make a more extreme throttle response if the rpm is much too low
pos = pos + 5;
myservo.write(pos);
delay(200);
}
else if (frequency >= val +10) { // this is for a more extreme response if the rpm is too high
pos = pos - 5;
myservo.write(pos);
delay(200);
}
delay(50);
}

The mower is a zero turn with a kohler courage 24 horsepower. It is a air-cooled gasoline combustion engine. The mechanical governor is nonfunctional as far as I can tell. I have a decent amount of experience with engines like this but much less experience with Arduino. The reason for the electronic governor is a potential upgrade over a repaired mechanical one, and I don’t have to take apart the engine. If anyone has a alternate method they believe could work for measuring the rpm I am willing to try it.

Have you designed the electronic governor so it can control the speed of the engine. As I wrote, that is the hard part. Won't it still be a mechanical control of some type?

Paul

Paul_KD7HB:
. Won't it still be a mechanical control of some type?

I would imagine that is what the servo is for.

Many engines require an "overshoot" of the throttle to give choke on cold start.
Others require separate control.
Many engines do not like starting at anything above idle or close to.
What you must also remember is that engine response to throttle input is not immediate.

The servo is what I am using to control the throttle. It is a futaba s3003 I had laying around, though I would rather use a stepper, I just don't have it on hand. Also the servo can be directly driven by the Arduino, which is a plus. I will attach the servo using a bent wire, similar to the way the original governor connected to the throttle on the carburetor. I am planning on having the Arduino powered by a modified usb car charger that is hooked to the mower battery.

klotzy_550:
A variable reluctance sensor, the inductive sensor, you are using will need some signal processing with either something like a LM1815 or MAX9924 that will process the sinusoidal waveform into a nice square wave that the Arduino can safely handle. This can be avoided by using a hall sensor on the flywheel as it already outputs a logic level signal. From here you could keep using the FreqMeasure library, but as I am not super familiar with it I would just write a clever hardware interrupt with a timeout.

As others have said, controlling it to a desired RPM will be tricky, likely need to use a PI or PID controller, on the OEM engines I calibrate we typically use a PI controller.

-Klotzy_550

I hope you will read my sample code to understand how I will control the rpm. If you could help me with the "Clever interrupt with a timer" that would be great. I am not committed to freqmeasure it was just the only thing I could find that seemed like it would work.

This link has code that I use to detect the speed of a small DC motor using an optical detector that produces one pulse per revolution. I expect it will work with a Hall effect sensor with no (or little) change.

…R

Did you ever complete this project?