I am working on a project where apart from other functions i have to determine the elapsed time between input state changes, then if it is below a set threshold, enable the outputs.
The code needs to run pretty fast, as it handles two inputs of a camshaft sensor, one is 1 cycle/rotation, the other is 6 cycle/rotation. Expected max RPM is 3750.
Here are the relevant lines from my code :
unsigned long CurrTime;
unsigned long StrobeTime;
void loop(){
CurrTime=millis();
if (input state change detection) {
StrobeTime = millis();
}
if (CurrTime-StrobeTime > 500 ){
/disabling outputs/
}
Now when i use unsigned long for the variables, the code runs very slow, the outputs are acting funny, dropping out, etc.
I have tried using int, it runs perfectly even up to 4200 RPM, the max rpm of my drill that i use to test it.
If i use unsigned int, it behaves exactly like when using unsigned long.
Video:
unsigned long/int: unsigned long - YouTube
int: integer - YouTube
The three leds represent the outputs.
Is this simple math really this slow when using unsigned or long variables?
Can cause any problems if i use normal int for storing the millis() output?
You never update StrobeTime , so your timers runs only once after program statrts.
But if you using int for timer, it overflow after 32 seconds and the program start you logic from the beginning
INT is either 16-bit or 32-bit, depending upon hardware architecture: UNO, Mega, etc. being 8-bit uC but C/C++ does the 16-bit integer manipulation. Due and other more advanced microcontrollers are 32-bit architecture and C++ honors that native datatype.
Other casts in C++ are very efficient, a few clock cycles used only. Compilers are very optimized in this fundamental area.
I would not think your experience is indicative of INT byte-size or format.
It would be simple to test in loop() by just capturing micros() at the beginning, perform some integer math in a do-while loop, and capturing the elapsed time using micros before the close of loop(). Maybe to the inner loop for 10^4 - 10^5 times just to get a decent interval.
Repeat above only with an unsigned int.
Compare. And please post the results if you perform the experiment. Your current sketch is not provided, so further help is not possible.
UPDATE
See you posted your code and others are offering assistance.
So basically i have created a scenario, when StrobeTime > CurrTime can be true when using unsigned long, and this causes the errors?
Isnt StrobeTime being updated every time when
` if (cylState != LastCylState) {
if (cylState != HIGH) {`
is true?
Sorry but i have just picked up an arduino a week ago, this is the first ever program that i wrote in my life, sooo.. I dont really understand what you are saying
looks like the code turns on one of 3 LEDs depending on which pair of cylinders are being recognized and depending on identState that presumably toggles at once per rotation
shouldn't identState be the only thing resetting counterCyl ? i see counterCyl being set to 1, 4 depending on indentState and later reset to 1 when > 6
if identState toggles once per rotation, shouldn't it only reset counterCyl to something once (can't say it harmless otherwise
I want to use it for ditching the distributor on a 6 cylinder engine, and using a wasted spark coilpack.
counterCyl is reset to 1 when it is more that 6, to jump back to cyl #1 after detecting cyl#6.
identState resets counterCyl to 1 or 4 to eliminate incorrect counts if one input of cylState is not read for some reason.
This is the oscillogram of the two signals.
counterCyl cant be anything else than 1 when ident is going high. also it cant be anything else than 4 when ident is going low.
Don't use 'int', but 'unsigned int' is allowed, or even uin8_tDon't use uint8_t, see reply #25.
If your 'unsigned int' is 16 bits, then a millis-timer can run up to 65 seconds. As always, you have to carefully check your code that it is not doing funny things after another 65 seconds.
it looks ident rises just before the cylinder pulse and could be used to set the cylinder count to zero because the cylinder input would rise just after it and set it to 1
i think you're using sync as a flag to indicate the events are occurring and can toggles the LEDs and flag is reset after a timeout to inhibit toggling LEDs after a timeout period.
Rather it has everything to do with petty responses to how written communications are utilized. Not only wasting my time but yours; my time is better utilized to go for a fresh cup of coffee.