0

I am using 2 accelerometers connected to an arduino. The code below does not work.

> if((acc1 >= 20 && acc1 <= 40) && (acc2 >= 20 && acc2 <=40)) //If acc1 is between 20 and 40 AND if acc2 is between 20 and 40
>     {
>         digitalWrite(13, HIGH);
>     }

But, the following code does:

> if((acc1 >= 20 && acc1 <= 40)) //If acc1 is between 20 and 40
>     {
>         digitalWrite(13, HIGH);
>     }

Can anyone tell me why please? Edit with full code:

const int acc1_xPin = 0; //X Pin on acc1
const int acc1_yPin = 1; //Y Pin on acc1
const int acc2_xPin = 2; //X Pin on acc2
const int acc2_yPin = 3; //Y Pin on acc2

int xAcc1_maxVal = 409; //Maximum value for X-axis Acc1
int xAcc1_minVal = 269; //Minimum value for X-axis Acc1
int yAcc1_maxVal = 410; //Maximum value for Y-axis Acc1
int yAcc1_minVal = 270; //Minimum value for Y-axis Acc1

int xAcc2_maxVal = 411; //Maximum value for X-axis Acc2
int xAcc2_minVal = 268; //Minimum value for X-axis Acc2
int yAcc2_maxVal = 402; //Maximum value for Y-axis Acc2
int yAcc2_minVal = 263; //Minimum value for Y-axis Acc2

//Hold Calculated Values
double acc1; //acc1 angle
double acc2; //acc2 angle

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {

  int acc1_xRead = analogRead(acc1_xPin); //acc1 X-axis
  int acc1_yRead = analogRead(acc1_yPin); //acc1 Y-axis
  int acc2_xRead = analogRead(acc2_xPin); //acc2 X-axis
  int acc2_yRead = analogRead(acc2_yPin); //acc2 Y-axis

  //convert read values to degrees -90 to 90 - Needed for atan2
  int acc1_xAng = map(acc1_xRead, xAcc1_minVal, xAcc1_maxVal, -90, 90);
  int acc1_yAng = map(acc1_yRead, yAcc1_minVal, yAcc1_maxVal, -90, 90);
  int acc2_xAng = map(acc2_xRead, xAcc2_minVal, xAcc2_maxVal, -90, 90);
  int acc2_yAng = map(acc2_yRead, yAcc2_minVal, yAcc2_maxVal, -90, 90);

  //Caculate 360deg values like so: atan2(-yAng, -zAng)
  //atan2 outputs the value of -π to π (radians)
  //We are then converting the radians to degrees
  acc1 = RAD_TO_DEG * (atan2(-acc1_yAng, -acc1_xAng) + PI); //acc1 in degrees
  acc2 = RAD_TO_DEG * (atan2(-acc2_yAng, acc2_xAng) + PI); //acc2 in degrees

  if((acc1 >= 20 && acc1 <= 40) && (acc2 >= 20 && acc2 <= 40))
  {
    digitalWrite(13, HIGH);
    Serial.println("HIGH");
  }
  else if ((acc1 >= 41 && acc1 <= 60) && (acc2 >= 41 && acc2 <= 60))
  {
    digitalWrite(13, LOW);
    Serial.println("LOW");
  }

  Serial.print("Acc1: ");
  Serial.print(acc1);
  Serial.print(" Acc2: ");
  Serial.print(acc2);
  delay(1000);

}

I'd really appreciate any input as to way the if statements are not working when I have 2 conditions in them but will work when I have 1 condition.

Edit: I have corrected the typos in the code. My laptop gave up on me last night so I had to retype the code on a friends laptop, hence the typos and why I didn't post the whole code initially. The IF statements still don't work as stated above when the 2 conditions are in the IF statements together, but when I only put 1 condition in, it works fine.

  • 1
    Because acc2 is never between 20 and 40 at the same time that acc1 is? – Majenko Jun 21 '16 at 23:08
  • @Majenko That makes no sense. They are 2 separate sensors so why can't they be between 20 and 40 at the same time? – Coder92 Jun 21 '16 at 23:10
  • I don't know. Maybe something else in your program, or in your setup, is stopping them being both between 20 and 40 at the same time. – Majenko Jun 21 '16 at 23:17
  • I have also put in code to check their values outside the if statement and they are between those values at the same time. I am not getting any errors when I use either if statement – Coder92 Jun 21 '16 at 23:20
  • 1
    Please post your entire code and a description or schematic of your setup. At the moment all we can do is wildly stab in the dark which is of no use to anyone. – Majenko Jun 21 '16 at 23:21
2

I think this is your problem (from the full code snapshot)

(acc2 >= 20 && acc2 >= 40))

I believe it should be (like your first snapshot)

(acc2 >= 20 && acc2 <= 40))

Note that the first is greater than or equal to 40 rather than less than or equal to. Also note you've done this when determining whether or not acc2 is between 41 and 60 in the else if part of that same if statement.

I have no idea why the code differs between your first and third snapshot. Potentially you have spotted this already and failed to update the full code being run?

  • I have corrected the typos in the code. My laptop gave up on me last night so I had to retype the code on a friends laptop, hence the typos and why I didn't post the whole code initially. The IF statements still don't work as stated above when the 2 conditions are in the IF statements together, but when I only put 1 condition in, it works fine. – Coder92 Jun 22 '16 at 11:33
  • Can you tell us what the values of acc1 and acc2 are when you are testing? They aren't negative? Can you also elaborate on what you mean by not working, I assume you just never see the LED on pin 13 be driven high? Maybe put some serial output inside the if statements too to rule out any possible hardware gremlins – Ben Southwell Jun 22 '16 at 23:54
  • When testing if Acc1 and Acc2 are between the values at the same time, I have put in Serial.println("HIGH") and Serial.println("LOW") within the IF statements but they are not coming up on the serial monitor when the 2 conditions are within the IF statements. So if I have (acc1 >= 20 && acc1>= 40) within the If statement it will work but if I have ((acc1 >= 20 && acc1>= 40)&&(acc2 >= 20 && acc2>= 40)) within the statement, the serial monitor just shows the values and 'HIGH' or 'LOW' does not appear even though I can see both acc1 and acc2 are within the values at the same time – Coder92 Jun 23 '16 at 11:35
  • The code you have sent in your comment ((acc1 >= 20 && acc1>= 40)&&(acc2 >= 20 && acc2>= 40)) is wrong. This will only execute when both are above 40 not in between the 20 and 40. Can you update your code in the OP to represent what you are actually running. – Ben Southwell Jun 23 '16 at 12:28
  • Sorry, it should b: ((acc1 >= 20 && acc1<= 40)&&(acc2 >= 20 && acc2<= 40)) and the other one should be (acc1 >= 20 && acc1<= 40). I actually have it correct in the code in the main question. – Coder92 Jun 23 '16 at 12:42
1

Your code has the following lines:

acc2 = RAD_TO_DEG * (atan2(-acc1_yAng, -acc1_xAng) + PI); //acc1 in degrees
acc2 = RAD_TO_DEG * (atan2(-acc2_yAng, acc2_xAng) + PI); //acc2 in degrees

If I'm going to believe the comments, the first line should start:

acc1 = ...
  • That doesn't fully explain: they are between those values at the same time. – Nick Gammon Jun 22 '16 at 3:34
  • Agreed - but it can't help! If acc1 meets the criteria when it isn't even initialised, then the formula could be wrong for both. He might see the arm with those angles, but maybe it comes out negative in the formula or something – John Burger Jun 22 '16 at 8:22
  • It's odd that his full code is nothing like the snippets in the original question. :) – Nick Gammon Jun 22 '16 at 9:12
  • I have corrected the typos in the code. My laptop gave up on me last night so I had to retype the code on a friends laptop, hence the typos and why I didn't post the whole code initially. The IF statements still don't work as stated above when the 2 conditions are in the IF statements together, but when I only put 1 condition in, it works fine. – Coder92 Jun 22 '16 at 11:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.