Using Averages and IF Statements Please help

Hello all,

I have a piece of code that is calculating the roll of an IMU sensor from -50º - 50º in 10s i.e. ±50º, ±40º, ±30º, ±20º, ±10º and 0º. Once a value of ±10º has been reached I am using LEDs to indicate this, so I've used a bunch of IF statements saying to illuminate an LED if the roll is 10º, 20º and so on...

Now the code has to work to an accuracy of 5º i.e.if roll is between 5º-15º then an accuracy of 5º would mean the value is 10º, or if roll is between 15º-25º then an accuracy of 5º would make the roll 20º. I'm having trouble being able to incorporate this accuracy within my code I'm not sure if there's some kind of averaging I need to use? I've attached my code I'm quite a rookie at coding and I'm sure there's a much faster way of doing this than using a bunch of IF statements, so any advice would be greatly appreciated!

Please don't attached screen shots of code. Read the posting guides in the sticky. Use [​code]code tags[​/code] and include your code (all of it) in the post itself.

Your code only seems to ever turn most LEDs ON, never back OFF again?

Also not sure what all the delay(100) are for? Something more like this to check for ranges...

if (roll >= 40 && roll < 50)
{
  digitalWrite(ledPins[2], HIGH);
}
else
{
  digitalWrite(ledPins[2], LOW);
}

Or more simply...

digitalWrite(ledPins[2], roll >= 40 && roll < 50);

Repeat for each LED with appropriate ranges for when you want it to illuminate.

And do you expect the LEDs to light up...

10 *----
20 **---
30 ***--
40 ****-
50 *****

Or...

10 *----
20 -*---
30 --*--
40 ---*-
50 ----*

My code does the former.

My apologies I'm new to the forum. I tried uploading all my code but it exceeds 9000 characters so I've included to code that corresponds to the issue I'm having.

This is my code:

  float roll = 0; // this section is for the LED lights to show roll whilst on pitch mode
  roll = (atan2(normAccel.YAxis, normAccel.ZAxis) * 180.0) / M_PI; // this works out the roll
  roll = round(roll); // rounds roll to the nearest digital rather than being decimal

  if (roll == 0.00) { // if angle is 0 indicator LEDS off
    digitalWrite(ledPins[7], LOW);
    digitalWrite(ledPins[1], LOW);
  }
  if (roll >= 10) {
    digitalWrite(ledPins[7], LOW); // turns off other indicator
    digitalWrite(ledPins[0], HIGH); // turns on indicator
  }
  if (roll <= -10) {
    digitalWrite(ledPins[0], LOW); // turns off other indicator
    digitalWrite(ledPins[7], HIGH); // turns on indcator
  }
  if (roll >= 10) {
    digitalWrite(ledPins[5], HIGH);
    delay(100);
  }
  if (roll >= 20) {
    digitalWrite(ledPins[4], HIGH);
    delay(100);
  } 
  if (roll >= 30) {
    digitalWrite(ledPins[3], HIGH);
    delay(100);
  }
  if (roll >= 40) {
    digitalWrite(ledPins[2], HIGH);
    delay(100);
  }
  if (roll >= 50) {
    digitalWrite(ledPins[1], HIGH);
    delay(100);
    tone(13, 4000, 100);
  }
  if (roll <= -10) {
    digitalWrite(ledPins[2], HIGH);
    delay(100);
  }
  if (roll <= -20) {
    digitalWrite(ledPins[3], HIGH);
    delay(50);
  }
  if (roll <= -30) {
    digitalWrite(ledPins[4], HIGH);
    delay(100);
  }
  if (roll <= -40) {
    digitalWrite(ledPins[5], HIGH);
    delay(100);
  }
  if (roll <= -50) {
    digitalWrite(ledPins[6], HIGH);
    delay(100);
    tone(13, 4000, 100);
  }
  else {
    delay(50);
    for (int x = 1; x < 7; x++)(digitalWrite(ledPins[x], LOW)); // set all LEDS to off
  }

I am expecting my LEDs to light up in the former case, one-by-one without turning the previous one off. The program is an Attitude Indicator for an aircraft, so the LEDs will light up in an accumulative way. If there is a way for me to upload the entire code without the character limit do let me know please to make it easier.

mindthegap95:
My apologies I'm new to the forum. I tried uploading all my code but it exceeds 9000 characters so I've included to code that corresponds to the issue I'm having.

The accepted method for that in this forum, is to add the code as an attachment.

I still don't understand what the delays are for. Sorry.

Regardless, your IFs are structured all wrong. All of them are separate conditions, tested one after another.

None of them turn the LEDs OFF, except for in this ELSE...

 if (roll <= -50) {
    digitalWrite(ledPins[6], HIGH);
    delay(100);
    tone(13, 4000, 100);
  }
  else {
    delay(50);
    for (int x = 1; x < 7; x++)(digitalWrite(ledPins[x], LOW)); // set all LEDS to off
  }

That means if roll <= -50 you will turn on LED 6, in addition to any that have been turned on previously, or in previous times throughh loop().
Only when roll > -50 will you actually turn OFF LEDs 1 through 7 (otherwise they would stay set if set previously).

I find it hard to believe this is what you actually want, but I'm having trouble deciphering the exact pattern you are aiming for from your code. Perhaps you could complete a little table as to which LEDs should be illuminated in each range...

Range 123456
00-10 ------
10-20 *-----
20-30 **----
30-40 ***---
etc.

Then it really is very easy then to translate into code...

digtalWrite(ledPins[1], roll >= 10);
digtalWrite(ledPins[2], roll >= 20);
digtalWrite(ledPins[3], roll >= 30);
etc.

The key here is to write either TRUE/HIGH (ON) or FALSE/LOW (OFF) to EVERY LED on every time through loop() in order to obtain the pattern you want. Your current code doesn't do that.

I find it hard to believe this is what you actually want, but I'm having trouble deciphering the exact pattern you are aiming for from your code. Perhaps you could complete a little table as to which LEDs should be illuminated in each range...

Range 123456
00-10 ------
10-20 *-----
20-30 **----
30-40 ***---
etc.

Thanks for your reply pcbbc,

I'll include a table of what I'm wanting to achieve from my LEDs. A maximum roll angle of 50º will require 5 LEDs to work in 10nths. Therefore, the way I want the LEDs to illuminate is as follows:

0-10*---- (if 5º is achieved)
10-20**--- (if 15º is achieved)
20-30***-- (if 25º is achieved)
30-40****- (if 35º is achieved)
40-50***** (if 45º is achieved)

I must work to an accuracy of 5º within a specified range, so for example within the range of 0º-10º the LED shall remain off for any other angle, it shall only illuminate for 5º. Regarding the delay(100), I had this so that the LEDs would blink as I don't know how to keep them from blinking and remain a solid colour as I increase in roll angle from 5º, 15º, 25º, 35º and 45º as in the example above. I hope that clarifies a few things.

mindthegap95:

00-10*---- (if 5º is achieved)

10-20**--- (if 15º is achieved)
20-30***-- (if 25º is achieved)
30-40****- (if 35º is achieved)
40-50***** (if 45º is achieved)




I must work to an accuracy of 5º within a specified range, so for example within the range of 0º-10º the LED shall remain off for any other angle, it shall only illuminate for 5º.

Nope, still clear as mud - sorry.

The table you present says it should be on for any value between 0 and 10 degrees.
Your wording says it should be ON for exactly 5 degrees, and no other value - al least if I read your wording literally (but I suspect you only want it to illuminate for 5º and over).

Are you saying led 1 should only come on for any value over 5 degrees? Is that what you mean by "achieved"?

In that case I would expect the table to be...

00-05 ------
05-15 *-----
15-25 **----
etc

But lets say we "achieve 5º". When does led 1 go off again? When we drop below 5º again? Or drop below some other value? Or after some period of time after we drop below some value?

Also your original code has negative values. Those aren't listed in the table. Why not? What patterns do you want negative values to produce? Again, present a table.

Are you saying led 1 should only come on for any value over 5 degrees? Is that what you mean by "achieved"?

Yes exactly! Though it should come on exactly at 5º and remain on thereafter, so (roll >= 5º).

As I said (which is probably the confusing part) the LEDs should work to an accuracy of 5º that meaning only illuminate for a factor of 5 i.e. 5, 10, 15, 20. At this point I know what you're probably thinking why don't I just write:

if (roll >= 5) {

    digitalWrite(ledPins[7], HIGH)
}

But I need to specify a range i.e. 0º - 10º and write a piece of code that will only illuminate an LED when a factor of 5 has been achieved within that range. Which would be 5º.

But lets say we "achieve 5º". When does led 1 go off again? When we drop below 5º again? Or drop below some other value? Or after some period of time after we drop below some value?

Correct LED1 should go OFF when we drop below 5º. So LED1 should only come on when an angle of 5º is achieved and it should remain on thereafter for roll angles >= 5. LED2 should come on when an angle of 15º is achieved and remain on thereafter for roll angles >= 15. So at this point LED1 and LED2 are ON. LED3 shall turn on when an angle of 25º is achieved and remain on thereafter for angles >= 25º. At this point if I roll down to any less than 25 i.e. roll < 25, let's say 24 LED3 will turn OFF. Similarly, if I roll down to 4º, LED2 will have gone off since we came below 15º and LED1 will turn off since LED1 only turns on for an angle of 5º. Does that makes things more clearly?

Also your original code has negative values. Those aren't listed in the table. Why not? What patterns do you want negative values to produce? Again, present a table.
[/quote]

I hadn't listed the entire values since I wanted to dress first the criteria for the LEDs to turn on. The pattern for the negative values will follow the exact same for the positive values. Positive will imply an aircraft rolling right, negative will imply aircraft rolling left so their criteria will be identical, all that changes is the negative sign.

The problem with the table is

0 - 5-----

doesn't conform to: roll >= 5º should turn on an LED which is what's needed. So I will present a full table will comments

-5º - 5º-----                       (0º therefore all LEDs off)
5º - 15º*----                      (LED1 should turn on for roll >= 10º)
15º - 25º**---                    (LED2 should turn on for roll >= 20º)
25º - 35º***--                   (LED3 should turn on for roll >= 30º)
35º - 45º****-                   (LED4 should turn on for roll >= 40º)
45º - 55º*****                  (LED5 should turn on for roll >= 50º)

similarly, if I now roll in the opposite direction:

-5º - 5º-----                            (0º therefore all LEDs off)
-5º - (-15º)*----                      (LED1 should turn on for roll >= -10º)
-15º - (-25º)**---                    (LED2 should turn on for roll >= -20º)
-25º - (-35º)***--                   (LED3 should turn on for roll >= -30º)
-35º - (-45º)****-                   (LED4 should turn on for roll >= -40º)
-45º - (-55º)*****                  (LED5 should turn on for roll >= -50º)

Does this make things more clear?

It does. You're making things more complicated by mentioning the accuracy though. All you really require is what you mention in this statement...

So LED1 should only come on when an angle of 5º is achieved and it should remain on thereafter for roll angles >= 5. LED2 should come on when an angle of 15º is achieved and remain on thereafter for roll angles >= 15. So at this point LED1 and LED2 are ON. LED3 shall turn on when an angle of 25º is achieved and remain on thereafter for angles >= 25º.

This code will achieve that and handle negative angles as well (we just convert the negative values to positive ones with the abs() function)...

float roll = 0; // this section is for the LED lights to show roll whilst on pitch mode
roll = (atan2(normAccel.YAxis, normAccel.ZAxis) * 180.0) / M_PI; // this works out the roll
roll = abs(roll); //convert to absolute (positive) value

digitalWrite(ledPins[1], roll >= 5.0);  // turn on led 1 above 5 degrees, otherwise off
digitalWrite(ledPins[2], roll >= 15.0);  // turn on led 2 above 15 degrees, otherwise off
digitalWrite(ledPins[3], roll >= 25.0);  // turn on led 3 above 25 degrees, otherwise off
digitalWrite(ledPins[4], roll >= 35.0);  // turn on led 4 above 35 degrees, otherwise off
digitalWrite(ledPins[5], roll >= 45.0);  // turn on led 5 above 45 degrees, otherwise off
digitalWrite(ledPins[6], roll >= 55.0);  // turn on led 6 above 55 degrees, otherwise off

You should be able to adjust accordingly if I have got any thresholds wrong

pcbbc:
digitalWrite(ledPins[1], roll >= 5.0); // turn on led 1 above 5 degrees, otherwise off
digitalWrite(ledPins[2], roll >= 15.0); // turn on led 2 above 15 degrees, otherwise off
digitalWrite(ledPins[3], roll >= 25.0); // turn on led 3 above 25 degrees, otherwise off
digitalWrite(ledPins[4], roll >= 35.0); // turn on led 4 above 35 degrees, otherwise off
digitalWrite(ledPins[5], roll >= 45.0); // turn on led 5 above 45 degrees, otherwise off
digitalWrite(ledPins[6], roll >= 55.0); // turn on led 6 above 55 degrees, otherwise off[/code]
You should be able to adjust accordingly if I have got any thresholds wrong

Thanks for your response and your advise. The reason I keep talking about the accuracy is because it is a requirement that needs to be met. My maximum roll is 50º and I am required to work to an accuracy of 5º between specific ranges; I have to work within ranges and can't simply type what you wrote above unfortunately. I appreciate it sounds confusing it's not the easiest thing to understand at first. Anyhow gave me an idea using the initial code you had suggested for ranges at the beginning: digitalWrite(ledPins[2], roll >= 40 && roll < 50); to achieve an angle of 45º.

I have done this for my code and it seems to work well with the '&&' and the LEDs illuminate at each threshold. However, I just cannot get my LEDs to stop pulsing when each threshold is met, they don't remain a solid colour at all the way I want.

This is what I have:

 float roll = 0; // this section is for the LED lights to show roll whilst on pitch mode
  roll = (atan2(normAccel.YAxis, normAccel.ZAxis) * 180.0) / M_PI; // this works out the roll
  roll = round(roll); // rounds roll to the nearest digital rather than being decimal

  if (roll == 0.00) { // if angle is 0 indicator LEDS off
    digitalWrite(ledPins[7], LOW);
    digitalWrite(ledPins[1], LOW);
  }
  if (roll >= 10) {
    digitalWrite(ledPins[7], LOW); // turns off other indicator
    digitalWrite(ledPins[0], HIGH); // turns on indicator
  }
  if (roll <= -10) {
    digitalWrite(ledPins[0], LOW); // turns off other indicator
    digitalWrite(ledPins[7], HIGH); // turns on indcator
  }
  if (roll >= 10) {
    digitalWrite(ledPins[5], HIGH);
  }
  if (roll >= 20) {
    digitalWrite(ledPins[4], HIGH);
  }
  if (roll >= 30) {
    digitalWrite(ledPins[3], HIGH);
  }
  if (roll >= 40) {
    digitalWrite(ledPins[2], HIGH);
    delay(100);
  }
  if (roll >= 50) {
    digitalWrite(ledPins[1], HIGH);
    delay(100);
    tone(13, 4000, 100);
  }
  if (roll <= -10) {
    digitalWrite(ledPins[2], HIGH);
  }
  if (roll <= -20) {
    digitalWrite(ledPins[3], HIGH);
  }
  if (roll <= -30) {
    digitalWrite(ledPins[4], HIGH);
  }
  if (roll <= -40) {
    digitalWrite(ledPins[5], HIGH);
  }
  if (roll <= -50) {
    digitalWrite(ledPins[6], HIGH);
    tone(13, 4000, 100);
  }
  else {
    delay(50);
    for (int x = 1; x < 7; x++)(digitalWrite(ledPins[x], LOW)); // set all LEDS to off
  }

  delay(40);
  
  delay(450); //1Hz 1000 - 550
}

I can't see find anything that causes them to pulse, I will also attach my full code for you to make it easier. If you could spot where I'm going wrong as to why my LEDs keep pulsing I would massively appreciate it! Also programming is not my strength so please excuse any naivety.

AttitudeIndicator.ino (10.5 KB)

See post number #2 where I specifically drew you a picture of 2 ways the LEDs could possibly illuminate (either only one led on at a time, or in an increasingly long bar graph) and you chose the former. That’s also what you described in your text that I quoted in post #9. But anyway, now you want the latter... so let’s go with that.

The code you quoted in your post #10 does not include the...

digitalWrite(ledPins[2], roll >= 40 && roll < 50);

...logic you mention. In fact it doesn’t look much different from the code you started with? I can’t currently download the attached INO sketch because I’m on a tablet device, so looking at that will have to wait until later. But yes, you are correct that the && logic will work if you want the latter effect.

Can you provide a video of what you mean by pulsing? With the above line of code LED 2 will illuminate solidly for any value in the range 40 to 50 (exclusive). Any pulsing or flashing you are seeing must be because of either...
a) other code you have written is telling them to
or
b) your measurements are fluctuating
or
c) your calculations are wrong.
Although I don’t fully understand why you are back to comparing against 40 and 50 again. I thought you needed 5 degrees of accuracy around 10, 20, 30 etc, not around 45 (which is what comparing against 40 and 50 gives you)?

I would suggest you print your “roll” values out to the serial port so you can view them and see what raw data you are working with.

I’m not saying ignore the accuracy requirement. Just saying you need to describe and code what range of values (after taking the accuracy into account) should illuminate each led. If you cannot do that you have no hope of implementing this in code. Perhaps this seems counter intuitive to you somehow, or you aren’t getting the results you require and you are assuming this is down to the accuracy requirement. Regardless it’s how the code has to work. If I want to tell if a value is within 5 degrees of 40, I must compare against 35 and 45 as a range.

So I think what you are now saying your requirements are is that for rolls (either positive or negative) in the following ranges (and after taking into account the required 5 degree accuracy)...
0 to 5 degrees (exclusive) NONE of the LEDs should light?
5 (inclusive) to 15 (exclusive) ONLY the first LED should light?
15 (inclusive) to 25 (exclusive) ONLY the second LED should light?
etc.

Okay, looking at your sketch code...

  if (roll == 0.00) { // if angle is 0 indicator LEDS off
    digitalWrite(ledPins[7], LOW);
    digitalWrite(ledPins[1], LOW);
  }
  if (roll >= 10) {
    digitalWrite(ledPins[7], LOW); // turns off other indicator
    digitalWrite(ledPins[0], HIGH); // turns on indicator
  }
  if (roll <= -10) {
    digitalWrite(ledPins[0], LOW); // turns off other indicator
    digitalWrite(ledPins[7], HIGH); // turns on indcator
  }

When roll == 0.00 shouldn't you be turning off LEDs 7 and 0, and not 7 and 1???
Although I should point out that as you are using floating point numbers comparing with equal is not at all guaranteed. Your earlier use of round function may just save you here.

These all turn on the LEDs when roll is above various values (which gives you the bar graph effect you now claim you don't actually want), but nothing ever turns them off again...

  if (roll >= 10) {
    digitalWrite(ledPins[5], HIGH);
  }
  if (roll >= 20) {
    digitalWrite(ledPins[4], HIGH);
  }
  if (roll >= 30) {
    digitalWrite(ledPins[3], HIGH);
  }
  if (roll >= 40) {
    digitalWrite(ledPins[2], HIGH);
    delay(100);
  }
  if (roll >= 50) {
    digitalWrite(ledPins[1], HIGH);
    delay(100);
    tone(13, 4000, 100);
  }

Similarly these turn the LEDs ON when below various values. Again nothing to turn them off again...

  if (roll <= -10) {
    digitalWrite(ledPins[2], HIGH);
  }
  if (roll <= -20) {
    digitalWrite(ledPins[3], HIGH);
  }
  if (roll <= -30) {
    digitalWrite(ledPins[4], HIGH);
  }
  if (roll <= -40) {
    digitalWrite(ledPins[5], HIGH);
  }
  if (roll <= -50) {
    digitalWrite(ledPins[6], HIGH);
    tone(13, 4000, 100);
  }

Except for this ELSE clause to turn LEDS 1-6 OFF...

  else {
    delay(50);
    for (int x = 1; x < 7; x++)(digitalWrite(ledPins[x], LOW)); // set all LEDS to off
  }

As this is the ELSE for the preceding "if (roll <= -50) {" clause it is the equivalent of...

if (roll > -50)
{
    delay(50);
    for (int x = 1; x < 7; x++)(digitalWrite(ledPins[x], LOW)); // set all LEDS to off
}

Which is probably why you feel the need to put the delays in every where. Because (unless pitch <= -50) you are setting some LED values and then immediately erasing them again. Perhaps that is what is causing your pulse effect?

pcbbc:
The code you quoted in your post #10 does not include the...

digitalWrite(ledPins[2], roll >= 40 && roll < 50);

...logic you mention. In fact it doesn’t look much different from the code you started with? I can’t currently download the attached INO sketch because I’m on a tablet device, so looking at that will have to wait until later. But yes, you are correct that the && logic will work if you want the latter effect.

My apologies my concentration wasn't the best last night trying to figure out the pulsing, here is the correct piece of code with your initial idea incorporated.

  float roll = 0; // this section is for the LED lights to show roll whilst on pitch mode
  roll = (atan2(normAccel.YAxis, normAccel.ZAxis) * 180.0) / M_PI; // this works out the roll
  roll = round(roll); // rounds roll to the nearest digital rather than being decimal

  if (roll == 0.00) { // if angle is 0 indicator LEDS off
    digitalWrite(ledPins[7], LOW);
    digitalWrite(ledPins[0], LOW);
  }
  
  if (roll >= 10) {
    digitalWrite(ledPins[7], LOW); // turns off right roll indicator
    digitalWrite(ledPins[0], HIGH); // turns on left roll indicator
  }
  if (roll <= -10) {
    digitalWrite(ledPins[0], LOW); // turns off left roll indicator
    digitalWrite(ledPins[7], HIGH); // turns on right roll indcator
  }
  if ((roll > 5) && (roll < 15)) {
    digitalWrite(ledPins[5], HIGH);
  }
  if ((roll > 15) && (roll < 25)) {
    digitalWrite(ledPins[4], HIGH);
  }
  if ((roll > 25) && (roll < 35)) {
    digitalWrite(ledPins[3], HIGH);
  }
  if ((roll > 35) && (roll < 45)) {
    digitalWrite(ledPins[2], HIGH);
  }
  if ((roll > 45) && (roll >= 50)) {
    digitalWrite(ledPins[1], HIGH);
    tone(13, 4000, 100);
  }
  if ((roll < -5) && (roll > -15)) {
    digitalWrite(ledPins[2], HIGH);
  }
  if ((roll < -15) && (roll > -25)) {
    digitalWrite(ledPins[3], HIGH);
  }
  if ((roll < -25) && (roll > -35)) {
    digitalWrite(ledPins[4], HIGH);
  }
  if ((roll < -35) && (roll > -45)) {
    digitalWrite(ledPins[5], HIGH);
  }
  if((roll < -45) && (roll <=-50)) {
    digitalWrite(ledPins[6], HIGH);
    tone(13, 4000, 100);
  }
  else {
    delay(50);
    for (int x = 1; x < 7; x++)(digitalWrite(ledPins[x], LOW)); // set all LEDS to off
  }

pcbbc:
Can you provide a video of what you mean by pulsing? With the above line of code LED 2 will illuminate solidly for any value in the range 40 to 50 (exclusive). Any pulsing or flashing you are seeing must be because of either...
a) other code you have written is telling them to
or
b) your measurements are fluctuating
or
c) your calculations are wrong.
Although I don’t fully understand why you are back to comparing against 40 and 50 again. I thought you needed 5 degrees of accuracy around 10, 20, 30 etc, not around 45 (which is what comparing against 40 and 50 gives you)?
[/code]

See the link > IMG_4734.MOV - Google Drive

I couldn't upload it as an attachment.

pcbbc:
So I think what you are now saying your requirements are is that for rolls (either positive or negative) in the following ranges (and after taking into account the required 5 degree accuracy)...
0 to 5 degrees (exclusive) NONE of the LEDs should light?
5 (inclusive) to 15 (exclusive) ONLY the first LED should light?
15 (inclusive) to 25 (exclusive) ONLY the second LED should light?
etc.

This conforms to the code I have included yes. [/quote]

AttitudeIndicator.ino (10.6 KB)

You are seriously misunderstanding IF ELSE structure. Please see the explanation of how your...
IF
IF
IF
IF
ELSE
...structure works in post #12.

It might help your understanding if I restructure the following code for you...

 displayImage(roll_Mode[i]);
  if (roll >= 10) { // roll at 10D
    displayImage(roll_1[i]);
  }
  if (roll <= -10) { // roll at -10D
    displayImage(roll_1m[i]);
  }
  if (roll >= 20) { // roll at 20D
    displayImage(roll_2[i]);
  }
  if (roll <= -20) { // roll at -20D
    displayImage(roll_2m[i]);
  }
  if (roll >= 30) {
    displayImage(roll_3[i]);
  }
  if (roll <= -30) {
    displayImage(roll_3m[i]);
  }
  if (roll >= 40) {
    displayImage(roll_4[i]);
  }
  if (roll <= -40) {
    displayImage(roll_4m[i]);
  }
  if (roll >= 50) {
    displayImage(roll_5[i]);
  }
  if (roll <= -50) {
    displayImage(roll_5m[i]);
  }

While this code may appear to work, you are unnecessarily displaying unwanted images and then immediately overwriting them.

For example roll = +50 displays roll_1, roll_2, roll_3, roll_4 in quick succession before finally settling on roll_5.

Also why use i here? It seems you have i = 0 as a global? And it never changes? Besides your arrays of images are all only single elements, so no other value makes sense? Why not just...

displayImage(roll_1[0]);

...but anyway I digress.

A better approach would be as follows (notice the use of ELSE IF)...

 if (roll >= 50) {
    displayImage(roll_5[i]);
  }
  else if (roll <= -50) {
    displayImage(roll_5m[i]);
  }
  else if (roll >= 40) {
    displayImage(roll_4[i]);
  }
  else if (roll <= -40) {
    displayImage(roll_4m[i]);
  }
  else if (roll >= 30) {
    displayImage(roll_3[i]);
  }
  else if (roll <= -30) {
    displayImage(roll_3m[i]);
  }
  else if (roll >= 20) { // roll at 20D
    displayImage(roll_2[i]);
  }
  else if (roll <= -20) { // roll at -20D
    displayImage(roll_2m[i]);
  }
  else if (roll >= 10) { // roll at 10D
    displayImage(roll_1[i]);
  }
  else if (roll <= -10) { // roll at -10D
    displayImage(roll_1m[i]);
  }
  else
  {
    displayImage(roll_Mode[i]);
  }

Now you only every make a single call to displayImage, rather than potentially multiple calls.

Yep, having watched the video your "pulsing" is caused by your ELSE clause which, as I explained earlier, almost always (for any roll > -50) turns all LEDs 1 through 6 back OFF.

Remove all your current LED code for LEDs 1 through 6. Replace with...

  digitalWrite(ledPins[6], roll <= -45);
  digitalWrite(ledPins[5], (roll >= 5 && roll < 15) || (roll <= -35 && roll > -45));
  digitalWrite(ledPins[4], (roll >= 15 && roll < 25) || (roll <= -25 && roll > -35));
  digitalWrite(ledPins[3], (roll >= 25 && roll < 35) || (roll <= -15 && roll > -25));
  digitalWrite(ledPins[2], (roll >= 35 && roll < 45) || (roll <= -5 && roll > -15));
  digitalWrite(ledPins[1], roll >= 45);
  if (roll >= 45 || roll <= -45)
  {
    tone(13, 4000, 100);
  }

These digitalWrites contain all the necessary logic to turn the required LED both ON and OFF.
You do not need separate OFF logic.
If the condition is TRUE the LED will turn ON.
If the condition is FALSE the LED will turn OFF.

Also are you sure this is correct?

 if (roll == 0.00) { // if angle is 0 indicator LEDS off
    digitalWrite(ledPins[7], LOW);
    digitalWrite(ledPins[0], LOW);
  }
  
  if (roll >= 10) {
    digitalWrite(ledPins[7], LOW); // turns off right roll indicator
    digitalWrite(ledPins[0], HIGH); // turns on left roll indicator
  }
  if (roll <= -10) {
    digitalWrite(ledPins[0], LOW); // turns off left roll indicator
    digitalWrite(ledPins[7], HIGH); // turns on right roll indcator
  }

Consider...

  Roll  7 0
  0.00  - -  No roll.
+12.00  - *  In right roll, right roll indicator on
- 5.00  - *  Now in left roll, but nothing is updated by if statements (so still looks like right roll)
-13.00  * -  Now left roll and correctly updated for left roll (since -10 threshold exceeded)
- 3.00  * -  Still in left roll, but nothing updated by if statements
+ 2.00  * -  Now in right roll, but nothing is updated by if statements (so still looks like left roll)
+13.00  - *  Still right roll and correctly updated for right roll (since +10 threshold exceeded)

pcbbc:
Yep, having watched the video your "pulsing" is caused by your ELSE clause which, as I explained earlier, almost always (for any roll > -50) turns all LEDs 1 through 6 back OFF.

Remove all your current LED code for LEDs 1 through 6. Replace with...

  digitalWrite(ledPins[6], roll <= -45);

digitalWrite(ledPins[5], (roll >= 5 && roll < 15) || (roll <= -35 && roll > -45));
 digitalWrite(ledPins[4], (roll >= 15 && roll < 25) || (roll <= -25 && roll > -35));
 digitalWrite(ledPins[3], (roll >= 25 && roll < 35) || (roll <= -15 && roll > -25));
 digitalWrite(ledPins[2], (roll >= 35 && roll < 45) || (roll <= -5 && roll > -15));
 digitalWrite(ledPins[1], roll >= 45);
 if (roll >= 45 || roll <= -45)
 {
   tone(13, 4000, 100);
 }

Thanks again for your response pcbbc,

I see how this combines both positive and negative values in one statement rather than multiple 'IF' statements, however, my only problem is when rolling right, I want LEDs to light up from left-to-right (hence I was using LED 5, 4, 3, 2 and 1) indicating the motion, and when rolling left I want the LEDs to light up from right-to-left (hence I was using LEDs 2, 3, 4, 5 and 6). Whereas this piece of code will light up from left to right in both cases.Having it this way just makes things clearer as to how the LEDs are being used to explain the roll behaviour but without pulsing but increasing in an increasingly long bar graph as you called it.

And if I was to dip down below a certain range for example from 15º - 25º, to 5º - 15º it would turn off LED[4] as assigned in your example. And this is where my problem is, that's why I would write separate paragraphs for positive values and negative values because I could control particular LEDs.

pcbbc:
Also are you sure this is correct?

 if (roll == 0.00) { // if angle is 0 indicator LEDS off

digitalWrite(ledPins[7], LOW);
   digitalWrite(ledPins[0], LOW);
 }
 
 if (roll >= 10) {
   digitalWrite(ledPins[7], LOW); // turns off right roll indicator
   digitalWrite(ledPins[0], HIGH); // turns on left roll indicator
 }
 if (roll <= -10) {
   digitalWrite(ledPins[0], LOW); // turns off left roll indicator
   digitalWrite(ledPins[7], HIGH); // turns on right roll indcator
 }

Well spotted yes I guess they would just change to:

if (roll == 0.00) { // if angle is 0 indicator LEDS off
    digitalWrite(ledPins[7], LOW);
    digitalWrite(ledPins[0], LOW);
  }
  
  if (roll > 0) {
    digitalWrite(ledPins[7], LOW); // turns off right roll indicator
    digitalWrite(ledPins[0], HIGH); // turns on left roll indicator
  }
  if (roll < 0) {
    digitalWrite(ledPins[0], LOW); // turns off left roll indicator
    digitalWrite(ledPins[7], HIGH); // turns on right roll indcator
  }

What I want to achieve here is use two LEDs as indicators whether the IMU is rolling right or left i.e. greater than 0 or less than 0.

mindthegap95:
I see how this combines both positive and negative values in one statement rather than multiple 'IF' statements, however, my only problem is when rolling right, I want LEDs to light up from left-to-right (hence I was using LED 5, 4, 3, 2 and 1) indicating the motion, and when rolling left I want the LEDs to light up from right-to-left (hence I was using LEDs 2, 3, 4, 5 and 6). Whereas this piece of code will light up from left to right in both cases.

No it won't.
I respectfully ask - Have you actually tried the updated code I posted?

Having it this way just makes things clearer as to how the LEDs are being used to explain the roll behaviour but without pulsing but increasing in an increasingly long bar graph as you called it.

So you do want the bar graph effect, or the single illuminate led effect?

And if I was to dip down below a certain range for example from 15º - 25º, to 5º - 15º it would turn off LED[4] as assigned in your example. And this is where my problem is, that's why I would write separate paragraphs for positive values and negative values because I could control particular LEDs.

It may be clearer, but it won't do what you want.

Because you never turn any leds OFF, except for at the end of your code block, where you turn ALL LEDs 1-6 OFF again if roll > -50. That's what's making the pulsing effect happen:Turning LEDs on you want ON, then after a short delay nullifying that by turning them ALL OFF again.

But if you insist on writing separate statements for each LED, then in order to get correct operation, you MUST:
a) Write ONE, and ONLY ONE, condition to turn ON each LED.
b) in the ELSE condition for that LED you must turn the LED OFF.

Unless you do this (one way or another) the code you write is going to have one or more of...
i) IF statements that conflict with each other
ii) LEDs which stay ON when they should not (because you never turn them off)
iii) Pulsing effect because you wrongly turn all/some leds OFF when you need them to stay on

As my last word on this subject I will present you four choice of code. Two for each of graph and single illuminated LED. One coded the compact way, the other entirely equivalent but coded using longhand "if" logic (up to you which you use, but I would encourage you to try both so you can see they work).

// SINGLE LED EFFECT - COMPACT

digitalWrite(ledPins[6], roll <= -45);
digitalWrite(ledPins[5], (roll >= 5 && roll < 15) || (roll <= -35 && roll > -45));
digitalWrite(ledPins[4], (roll >= 15 && roll < 25) || (roll <= -25 && roll > -35));
digitalWrite(ledPins[3], (roll >= 25 && roll < 35) || (roll <= -15 && roll > -25));
digitalWrite(ledPins[2], (roll >= 35 && roll < 45) || (roll <= -5 && roll > -15));
digitalWrite(ledPins[1], roll >= 45);
if (roll >= 45 || roll <= -45)
{
  tone(13, 4000, 100);
}
// SINGLE LED EFFECT - IF STATEMENT LONGHAND

if (roll <= -45) {
  digitalWrite(ledPins[6], HIGH);
} else {
  digitalWrite(ledPins[6], LOW);
}
if ((roll >= 5 && roll < 15) || (roll <= -35 && roll > -45)) {
  digitalWrite(ledPins[5], HIGH);
} else {
  digitalWrite(ledPins[5], LOW);  
}
if ((roll >= 15 && roll < 25) || (roll <= -25 && roll > -35)) {
  digitalWrite(ledPins[4], HIGH);
} else {
  digitalWrite(ledPins[4], LOW);
}
if ((roll >= 25 && roll < 35) || (roll <= -15 && roll > -25)) {
  digitalWrite(ledPins[3], HIGH);
} else {
  digitalWrite(ledPins[3], LOW);
}
if ((roll >= 35 && roll < 45) || (roll <= -5 && roll > -15)) {
  digitalWrite(ledPins[2], HIGH);
} else {
  digitalWrite(ledPins[2], LOW);
}
if (roll >= 45) {
  digitalWrite(ledPins[1], HIGH);
} else {
  digitalWrite(ledPins[1], LOW);  
}
if (roll >= 45 || roll <= -45)
{
  tone(13, 4000, 100);
}
// BAR GRAPH EFFECT - COMPACT

digitalWrite(ledPins[6], roll <= -45);
digitalWrite(ledPins[5], roll >= 5 || roll <= -35);
digitalWrite(ledPins[4], roll >= 15 || roll <= -25);
digitalWrite(ledPins[3], roll >= 25 || roll <= -15);
digitalWrite(ledPins[2], roll >= 35 || roll <= -5);
digitalWrite(ledPins[1], roll >= 45);

if (roll >= 45 || roll <= -45)
{
  tone(13, 4000, 100);
}
// BAR GRAPH EFFECT - IF STATEMENT LONGHAND

if (roll <= -45) {
  digitalWrite(ledPins[6], HIGH);
} else {
  digitalWrite(ledPins[6], LOW);
}
if (roll >= 5 || roll <= -35) {
  digitalWrite(ledPins[5], HIGH);
} else {
  digitalWrite(ledPins[5], LOW);
}
if (roll >= 15 || roll <= -25) {
  digitalWrite(ledPins[4], HIGH);
} else {
  digitalWrite(ledPins[4], LOW);
}
if (roll >= 25 || roll <= -15) {
  digitalWrite(ledPins[3], HIGH);
} else {
  digitalWrite(ledPins[3], LOW);
}
if (roll >= 35 || roll <= -5) {
  digitalWrite(ledPins[2], HIGH);
} else {
  digitalWrite(ledPins[2], LOW);
}
if (roll >= 45) {
  digitalWrite(ledPins[1], HIGH);
} else {
  digitalWrite(ledPins[1], LOW);  
}
if (roll >= 45 || roll <= -45)
{
  tone(13, 4000, 100);
}