Fasted way to check if number is between interval

Hi,

I have numbers that comes from my sensor and I need to check if it’s inside an interval. I am not looking for the fewest lines possible to do the job, I am looking for the fastest way (that will consume less arduino clock cycles and memory) to accomplish that.

The code below will be executed inside an interrupt at every 20us so it needs to be very fast.

int center_value = 10;//this is the value that I want the sensor to be
int error_accepted = 2;//this is my tolerance

//I am using this code that I invented but I think abs is not fast.
if (abs(sensor_reading - center_value ) < error_accepted ) {

//GREAT

}

//This could also be good but it uses too much math.
if ( (sensor_reading < center_value + error_accepted) && (sensor_reading > center_value - error_accepted) ) {

//GREAT

}

Thank you.

``````  if ((unsigned int) (sensor_reading - lowest_value) <=
(unsigned int) (highest_value - lowest_value))
``````

Then you only have casts (no cost hopefully) and a subtract and single test.

try this:

``````int sensor_reading = 120;

const int center_value = 10;//this is the value that I want the sensor to be
const int error_accepted = 2;//this is my tolerance

``````

should be better if the compiler optimizes constant arithmetic… if not, you could use #define to do a similar thing…

Also, is the sensor reading really a 16 bit value?

@gilperon, out of curiosity, what kind of sensor gives you int values at such a high rate?

Running 1000 iterations in 450us means each iteration takes about 7 clock cycles. I don't think you'll do much better than that, and most certainly not significantly better enough to warrant stressing over this tiny optimization issue.

Remember: premature optimization is the root of all evil.

There is no logical reason for ever trying to read a gyro at that rate. You need to re-think how you’re doing things. You should only need to take periodic readings, perhaps at most every 10 mSec.

Regards,
Ray L.

gilperon:
Hi,

I am reading data from FIFO buffer from MPU6050 which appends data reallly fast to the buffer and if I dont read it fast enought my arduino crashes.

The code below will be executed inside an interrupt at every 20us

How many 400kHz I2C transactions do you expect to execute in 20us?
(Like Bernadette’s dad’s question to Howard about the number of bodies in the picture, it’s a trick question - it’s a fraction)

@gilperon: This is simply time-wasting. Please engage brain before posting this rubbish.

gilperon: I am just wondering if anyone else would have another approach. Thank you, I am not discarding your solution, it's way better than mine!

There isn't a better way, trust me I've worked on optimizing compilers. With luck the limits are constants and get constant-folded so the actual code becomes one subtract and one compare - that must be optimal.

MarkT: There isn't a better way, trust me I've worked on optimizing compilers. With luck the limits are constants and get constant-folded so the actual code becomes one subtract and one compare - that must be optimal.

The way I coded it would be two compares and an "and". But the "and" function can be incorporated into a machine branch, so in terms of overhead, that is a small improvement. Also if the optimization is working, if the first compare fails, the second one can be skipped, so sometimes it will be only one compare.

RayLivingston: There is no logical reason for ever trying to read a gyro at that rate. You need to re-think how you're doing things. You should only need to take periodic readings, perhaps at most every 10 mSec.

Regards, Ray L.

Entirely depends what performance you need. Faster means less systematic error due to discrete sampling of the angular velocity vector, and if you want to reliably track fast spins its all important to sample fast enough because the accelerometer data is meaningless during such motion.

You never told us whether the values were 16 bits. The values you're using suggest it might be 8 bits, and then you could use 8 bit data types, which would speed things up monumentally. So, can you provide details about that?

gilperon: I know I should not read the buffer so constantly BUT if I dont read it that fast the buffer overflows and my arduino resets, crashes... anything happen. I would like to be able to read 10 times a second but I cant, mpu6050 says I need to read it that fast or I will get problems.

You really should spend some time reading the MPU6050 data sheet in more detail, paying particular attention to the sample rate divider register. The sample rate is adjustable, and can be cranked all the way down to less than 4 samples/second. And anything over 1000 samples/second is repeating samples, so you're spending most of your time reading data you've already received. Even if you're reading it fast, if it's crashing your program, you're doing something very wrong - you should be managing the data buffering so that simply can't happen.

Regards, Ray L.

Let me get this right...... You don't want to do the calculations on the Arduino, due to "resources", so you instead use it in a way that required servicing the 6050 every 20 us??? And it makes obsess over minute optimizations to keep the whole thing working? That make no sense. What you're doing is consuming 100X the resources it has to, and is almost guaranteed to make the whole system very fragile and unstable over time.

Besides, the DMP library allows the sample rate to be selected, using the setrate() function in the MPU6050 library. By default, it sets a sample rate divisor of only 4....

Regards, Ray L.

gilperon: @RayLivingston I DIDNT KNOW THAT!!!! THANK YOU POINTING IT!!!! I didnt know I could change the sample rate!!! Your answer will solve many of my problems cause surelly I only need 10 samples per second, nothing more than that! You are awesome, thank you so much, I will look in the docs to see how to change the sample rate to the minimum possible!

It look less than 5 minutes of looking at the documentation for the library....

Regards, Ray L.