Yes, we got way off topic, sorry!
GoForSmoke:
To miss a tick it's only got to be processing an IRQ during the 'tick'. But for 99.999% of use I don't think it's a problem.
Much as I hate contradicting people ...
The timer interrupt (the overflow after 1024 uS) is remembered. It doesn't matter whether or not you are in an interrupt. Or another higher priority one happens next. The only thing that has to happen is that the interrupt is serviced within the 1024 uS before the next overflow (it won't remember two of them). So if, taken altogether, the interrupt is able to be serviced within 1024 uS of the timer overflow, you won't lose any accuracy at all.
This isn't saying the crystal will be 100% accurate, but that's another issue.
Again, Serial.print does not cause an interrupt.
Correct. Well, not directly. Serial.print under version 1.0 puts things into a buffer. And if the flag is not already set, it sets a flag (output buffer empty) which will cause an interrupt to occur (at some later stage) to empty that buffer. If the buffer is not empty then the interrupt will occur when the current byte has finished transferring.
We're in agreement! Finally the world can take another breath and move on...
Seriously, I'm glad we learned something new in this thread!
I've made a circuit to detect electrical pulse from spark plug wire.
To test it I've made a simple program that every second check the sensor value and turn on a red LED if sensor value is HIGH and a YELLOW LED if RPM ( = (1/time)*60000) ) is over 4000. The 2 LEDs works, but when I try to connect arduino on serial monitor, when the engine is running connection is lost, but the LEDs still light up.
I have that problem with serial monitor
I thought there might be some short-circuit or something like that...
Who can help me?
P.S. If you need the circuit sketch I'll let you have.
I've made a simple program ...
Perhaps share that with us.
If you need the circuit sketch I'll let you have.
Good idea.
cntntn:
I've made a circuit to detect electrical pulse from spark plug wire.
To test it I've made a simple program that every second check the sensor value and turn on a red LED if sensor value is HIGH and a YELLOW LED if RPM ( = (1/time)*60000) ) is over 4000. The 2 LEDs works, but when I try to connect arduino on serial monitor, when the engine is running connection is lost, but the LEDs still light up.
I have that problem with serial monitor
I thought there might be some short-circuit or something like that...
Who can help me?P.S. If you need the circuit sketch I'll let you have.
You didn't by some chance use one of the serial pins to detect the spark pulse?
That's the code:
float time;
const int redLed = 10;
const int yellowLed = 9;
const int sparkPin = 2;
int sensorValue = 0;
int lastSensorValue = 0;
void setup() {
Serial.begin(9600);
pinMode(redLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(sparkPin, INPUT);
}
void loop() {
int sensorValue = digitalRead(2);
float rpm = 0;
time = millis();
if (sensorValue == HIGH) {
if (sensorValue != lastSensorValue) {
rpm = (1/time)*60000;
Serial.println(rpm);
digitalWrite(redLed, HIGH);
if (rpm > 4000) {
digitalWrite(yellowLed, HIGH);
}
delay(1000);
time = 0;
}
}
digitalWrite(redLed, LOW);
digitalWrite(yellowLed, LOW);
lastSensorValue = sensorValue;
}
the circuit is attached (thanks to mister_rf to that)
The LEDs works all th time, but when the engine is running, the connection on serial port (with USB) is lost.
What's the problem??
I have no idea why the serial connection is lost but I can tell you that what you call rpm is not sparks per minute or engine rpm for more than one reason.
A) millis() is time since the sketch started running. It will increase for about 2 months before rolling over at a rate of 1000/second. Your code time=0 does not reset millis().
B) With the delay(1000) there you are not measuring sparks per anything but chance and error.
Perhaps it has something to do with your actual wiring.
A) Are you sure that if I write time = 0 , the time don't come to zero?
B) This is only a test, I've written delay(1000) to not go mad with the data.
So, how can I reset the time every sensor read?
cntntn:
A) Are you sure that if I write time = 0 , the time don't come to zero?
Sure it does. Then you set it to millis(). Read the code!
What's worse is you made time a float when it should be an unsigned long. The float is less accurate and completely unnecessary.
B) This is only a test, I've written delay(1000) to not go mad with the data.
Your test is bliviting your results.
So, how can I reset the time every sensor read?
You don't. You store the current value of not millis() but micros() in an unsigned long and subtract the last value to get elapsed microseconds which you will give you the accuracy you need at 1000+ rpm when using integer math.
Arduino floats and doubles are 4-byte IEEE floating-point running on an MCU with no FPU. They are s-l-o-w and inaccurate. Choose the right units and you can do better and faster math with integers. Arduino not only has 32-bit integers, it has 64-bit integers both signed and unsigned.
