Can someone try this sketch and help me to understand why the result on serial monitor is jumping at regular interval.
I'm feeding the input pin with a 10 Hz 0-5volts square wave (so low time is 100ms ).
I want to simulate a tachometer reading at 600 rpm. (I'know how to do with interrupt but not for now).
Thanks !
int rpm;
unsigned long tachTime;
unsigned long previousmicros;
void setup(){
pinMode(2,INPUT);
Serial.begin(2000000);
}
void loop()
{
byte n1=digitalRead(2);//read a pin and after 5 ms read that pin again
delay(5);
byte n2=digitalRead(2);
//action only on a high to low transition
if (n1==HIGH & n2==LOW)
{tachTime = micros() - previousmicros;
previousmicros = micros();rpm = 60000000 / tachTime; }
//Serial.print("Rpm ");
Serial.println(rpm);
}
However, you can now at least see the 10Hz signal in the timestamps.
I suspect every now and again the high to low transition occurs outside the 5ms window so you get spikes - 629 rpm is approximately an internal of 95ms.
That is not going to be reliable. What happens when the input switch states anywhere BUT between those two digitalReads? Answer: You will not see it.
Instead, read the input. Compare it to the previous read, and save the result of that compare. Then SAVE the new value as the previous value. Now look at the result of the compare, and, do whatever you need to do when you see the edge(s) of interest.
You will also need to make sure that whatever processing you do in loop() takes much less time than a single pulse cycle of the input, or, again, you will miss edges or entire pulses.
Your logic is flawed.. there are other things happening in your loop that use processing time.
You are assuming that nothing happens between reading the pin the 2nd time, and the subsequent loop cycle... that is not the case. You have other logic that takes time... and the signal could change during that period.
At 10Hz one cycle takes 100mS, and it is low during 50ms
I ran your sketch and I get sequences of 580 and 610. I don't think that logic will produce the right results.
You can set a flag when a high pulse is detected. Then, check if the flag is set and the input is low and then you have a transition. Compute the rpm and reset the flag. This is more accurate and you don't have to use delay(). I ran your sketch with this modification, and the reading at 10Hz is stable. It starts jumping at higher frequencies.
50ms low time yes , my mistake. In fact my goal is to detect only the clean part of the pulse (not the noise) by software with a simple clipper circuit. After that, i will adjust timing. Rpm range would be 500-6000 rpm (10-100hz).
You got it ! It is very stable now. But i' think that my approach is bad. Because at the end of the pulse, (when the high voltage spike come back) there is also very fast high to low transitions (oscillations) that the mcu will see. So i will have to go back to the drawing board...
Here's an approach which deals with the bouncing trailing edge by requiring a stable low period before recording the time to determine the rpm period. Tested with a 10 Hz square wave and gave 600 rpm.
int rpm;
unsigned long tachTime;
unsigned long previousmicros;
unsigned long lastTimeSignalWasHigh;
unsigned long stableLowPeriod = 1000; //1 ms stable low
boolean newInterval = false;
void setup()
{
pinMode(2, INPUT);
Serial.begin(115200);
}
void loop()
{
if (digitalRead(2)) //signal level is high
{
lastTimeSignalWasHigh = micros();
newInterval = true;
}
// will execute when signal reads low
else if (newInterval && (micros() - lastTimeSignalWasHigh >= stableLowPeriod))
{
newInterval = false;//only one print per period
unsigned long newMicros = micros();
tachTime = newMicros - previousmicros;
previousmicros = newMicros;
rpm = 60000000 / tachTime;
Serial.print("Rpm ");
Serial.println(rpm);
}
}
No John, there is no peripherals connected when i run the test. Later il will drive a mini servo as indicator.
Ray, it is exactly what i want to do.
Oh, Cattledog i'will try youre sketch tokay. You give me a good starting point.
Update I' just ran a test and it work ! I'Have a DDS signal generator to simulate the coil pack signal after clipping down to 5volts. And ajusting the stable period required do the job nicely.
Next step will be to test it on the motorcycle...