as a beginner with Arduino but with little experience in microcontroller programming I have a question to this forum:
I've got a vintage motor boat which carries a very nice original RPM counter, which I do not want to give up.
This counter displays 3000 RPM if it receives a 100 Hz signal (That fitted the original 4cyl 4 stroke engine).
The original 4cyl engine has now been replaced by a newer one which delivers 150 hertz signal at 3,000 RPM, hence the RPM counter displays is 50% too high.
To have the RPM counter display the correct RPM value I need a frequency divider which divides the incoming frequency by 1.5.
I've got two ideas how to realize that softwarely.
One who would be to bypass the incoming pulses and leaving out every third pulse. That would basically equal a frequency division by 1.5 but at the same time lead to an uneven signal at the output and I don't know how the vintage RPM counter reacts to that...
The other idea is to continually measure the incoming frequency i.e. with the 8-bit counter and parallely produce and independent frequency with a second 8-bit counter which is only two-thirds of the measured frequency.
The measurement of the incoming frequency and the generation of the output frequency would be done in two isrs. The main program would mainly consist of only one loop which performs the multiplication with 2/3.
What do you mean?
Could that work or do your perhaps have a better preposition?
You can measure the cycle time, time for one period, and apply math to it. That's the delay between output pulses. Measure pulse period * 15 / 10, or MPT * 3 / 2.
I've got a solution that gives the waveform that EmilyJane showed in post #5, if the input is a 50% duty cycle.
It counts the number of times the input changes state. After a count of two it toggles the output pin, after a count of three it toggles the output pin and resets the count.
const int inputPin = 7;
const int outputPin = 12;
int inputChangeCounter = 0;
int inputState = 0;
int lastInputState = 0;
int outputState = 0;
void setup() {
pinMode(inputPin, INPUT);
pinMode(outputPin, OUTPUT);
}
void loop() {
inputState = digitalRead(inputPin);
if (inputState != lastInputState) {
inputChangeCounter++;
if(inputChangeCounter == 2) {
outputState = !outputState;
digitalWrite(outputPin, outputState);
}
if (inputChangeCounter == 3) {
inputChangeCounter = 0;
outputState = !outputState;
digitalWrite(outputPin, outputState);
}
}
lastInputState = inputState;
}
At 100 Hz there is no need for ISR's.
Use something like post #8 or leave out every third pulse or use the solution given in #3.
My guess is that all will work...
Good morning,
sorry for not having answered before, it was late and I went to bed...
Thank you for your replies and especially the source code! This would be what I imagined in my first idea.
Special thanks also for the sophisticated TTL circuitry, I'm always amazed about such things!
But... Unfortunately the incoming signal is NOT a symmetric pulse but a series of peaks (coming from the ignition pickup).
Therefore I fear that the proposed solutions lead to an uneven output signal, which in turn will lead to a false display of the old (60s) RPM gauge (These meters depend on very simple analog circuits.
So - does anyone have an idea how to produce an even series of pulses with a frequency of 2/3 of the incoming frequency (consisting from short spikes)?
Do you have a ‘scope, or access to one? Depending on the nature of the source signal, a relatively simple RC front end might be able to clean it up before using one of the proposed solutions.
I wonder whether you can use the function pulseIn to measure the time between pulses, and then generate pulses with a period of 1.5 times the measured value.
Wrote an experimental library for pulse dividing a few years ago, might do the job.
Strong point is it allows runtime tuning of the ratio.
Weak point, it is software polling only so the output pulses are not equidistant.
That said, an 3 to 2 ratio might work well enough..
I think most analog meters work by counting pulses, and converting frequency to a voltage. Since the input comes from the ignition it is not well defined, so it would be bad for the meter
to rely on a particular pulse length or duty cycle.
Therefore I think any square wave with the right frequency would work, provided the pulse length is not too short. Either way, it seems like an easy test.
This IC would do what you want, convert the input to a fixed width pulse at the input frequency. It also has Schmitt-trigger inputs to help clean up noise. SN74LVC1G123
That is a retriggerable device where you can program the output pulse width. The output pulse duration is programmed by selecting external resistance and capacitance values. The output pulse just needs to be shorter then the time between the two fastest pulses. It usage is to clean up the input signal which still feeds the original circuit I posted in post 3. Check this link, it has a lot of information such as the technical guide and data sheet. https://www.ti.com/product/SN74LVC1G123