Go Down

Topic: Software Debouncing Interrupts (Read 958 times) previous topic - next topic

dc42

You are collecting the data using interrupts, which means that the data collection is not affected by the speed of the floating point maths. Keep the interrupt service routines short and fast (as they are in the code sample you posted), then you can afford to use floating point maths in the main loop that picks up the data, does the calculations and displays it.

There are situations in which FP maths should be avoided, but this isn't one of them.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

GoForSmoke

As long as your data isn't changing while you're calculating with it then fine....

If it was me, I'd collect FirstISR times for a series of shots into an array. When the array is full, stop collecting and -then- process the data along with SecondISR data. At the end of processing and reporting, set the array counter to zero which would re-enable data collection.
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

DTM22

Ok, So how do I go about using floating point calculations?  What libraries do I need to add and how would I go about using them for my situation?

GoForSmoke

Just declare a float or double type variable and the support gets linked in.

And just a couple caveats, be sure to tell Toto you're not in PC-land any more. ATmega's are microcontrollers.

http://arduino.cc/en/Reference/Float
Quote
Floats have only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point. Unlike other platforms, where you can get more precision by using a double (e.g. up to 15 digits), on the Arduino, double is the same size as float.

Floating point numbers are not exact, and may yield strange results when compared. For example 6.0 / 3.0 may not equal 2.0. You should instead check that the absolute value of the difference between the numbers is less than some small number.


http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_math
Quote
I am using floating point math. Why is the compiled code so big? Why does my code not work?

You are not linking in the math library from AVR-LibC. GCC has a library that is used for floating point operations, but it is not optimized for the AVR, and so it generates big code, or it could be incorrect. This can happen even when you are not using any floating point math functions from the Standard C library, but you are just doing floating point math operations.

When you link in the math library from AVR-LibC, those routines get replaced by hand-optimized AVR assembly and it produces much smaller code.


And yet, from AVRLib.c math.h we have 20-digit defines and functions to use them.
Quote
<math.h>: Mathematics
Defines
#define    M_E   2.7182818284590452354
#define    M_LOG2E   1.4426950408889634074
#define    M_LOG10E   0.43429448190325182765
#define    M_LN2   0.69314718055994530942
#define    M_LN10   2.30258509299404568402
#define    M_PI   3.14159265358979323846
#define    M_PI_2   1.57079632679489661923
#define    M_PI_4   0.78539816339744830962
#define    M_1_PI   0.31830988618379067154
#define    M_2_PI   0.63661977236758134308
#define    M_2_SQRTPI   1.12837916709551257390
#define    M_SQRT2   1.41421356237309504880
#define    M_SQRT1_2   0.70710678118654752440

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

DTM22

Ok, so by simply declaring a float or double, the appropriate libraries get linked in.  What modifications do I need to make to my calculations?

GoForSmoke

Isn't 6 places enough precision for rate of fire?

ROF is shots per time. Usually rounds per minute but sometimes rounds per second.

If I fire 15 shots in 1.15 seconds then my per-second ROF is 15.0/1.15 and my answer in 32-bit float will be to 6 places. If I want to find my Rounds Per Minute Rate Of Fire using float, I would calculate 60.0x15.0/1.15.....

I think that to print floating point to serial you would make a char array buffer and use sprintf to fill it then print the buffer using Serial.print(). And yes, using sprintf() will make your program larger.

Using integers --- example of 7/4 to 3 decimal places. Our 'unit' becomes .001's instead of 1's.

1st, move 7 up 3 places = 7000
2nd, integer divide 7000 / 4 = 1750
3rd, print (the answer / 1000) then print a decimal point then print (the answer % 1000)
You will get printed out 1.750

I guarantee it is quicker and takes less program space than using float and sprintf().
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Go Up