Tilt angles for LED using MPU6050

Hello, I'm working on a project where I have 7 Led's and want to turn each one on based on their angle (from -3 to +3) using a GY-521. I'm using a new library MPU6050_Light and using example GetAngle.ino, I'm having some trouble trying to get the LED to turn on, since I'm not sure how to set a specific angle for an individual LED using this library. I tired using an IF statement for pin 7 as a test but I'm not sure what to include for "if () < 3" between the parenthesis, I get an error "expected primary-expression after < " when verifying.

[code]
/* Get tilt angles on X and Y, and rotation angle on Z
 * Angles are given in degrees
 * 
 * License: MIT
 */

#include "Wire.h"
#include <MPU6050_light.h>

MPU6050 mpu(Wire);
unsigned long timer = 0;

//declaring pins 
int Pin_1= 4; 
int Pin_2= 5;
int Pin_3= 6;
int Pin_4= 7;
int Pin_5= 8;
int Pin_6= 9;
int Pin_7= 11;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  
  byte status = mpu.begin();
  Serial.print(F("MPU6050 status: "));
  Serial.println(status);
  while(status!=0){ } // stop everything if could not connect to MPU6050
  
  Serial.println(F("Calculating offsets, do not move MPU6050"));
  delay(1000);
  // mpu.upsideDownMounting = true; // uncomment this line if the MPU6050 is mounted upside-down
  mpu.calcOffsets(); // gyro and accelero
  Serial.println("Done!\n");

pinMode(Pin_1, OUTPUT); 
pinMode(Pin_2, OUTPUT);
pinMode(Pin_3, OUTPUT);
pinMode(Pin_4, OUTPUT);
pinMode(Pin_5, OUTPUT);
pinMode(Pin_6, OUTPUT);
pinMode(Pin_7, OUTPUT);

}

void loop() {
  mpu.update();
  
  if((millis()-timer)>10){ // print data every 10ms
	Serial.print("X : ");
	Serial.print(mpu.getAngleX());
	Serial.print("\tY : ");
	Serial.print(mpu.getAngleY());
	Serial.print("\tZ : ");
	Serial.println(mpu.getAngleZ());
	timer = millis();  
  }

if (mpu.getAngleY())<3
digitalWrite(Pin_7, HIGH); 


}


[/code]
  if (mpu.getAngleY()) < 3

You missed the closing ) on this line

1 Like

My aplologies, what I meant was that you misplaced the closing )

1 Like

no problem, thank you that helped. Also, do you know if it would be possible to use a switch break case instead of using if statements for this part? How should I do it?

// pin 7
  if ((mpu.getAngleX()) < -3)
digitalWrite(Pin_7, HIGH); 

else digitalWrite(Pin_7, LOW);

// pin 6
if ((mpu.getAngleX()) < -2)
digitalWrite(Pin_6, HIGH); 

else digitalWrite(Pin_6, LOW); 

// pin 5
if ((mpu.getAngleX()) < -1)
digitalWrite(Pin_5, HIGH); 

else digitalWrite(Pin_5, LOW); 

The "light" library seems okay, but they should have fixed my Issue by now.

The mpu.update() retrieves new data from the sensor. A update of 100Hz is normal for the MPU-6050 and you have already a millis-timer of 100Hz.
You could try to put the mpu.update() also in the millis-timer. The examples with the library don't do that, but it is worth a try.

I would do the updating of the leds also inside the millis-timer.

Could you get the angles and put them in variables ? That is a more common way to use a library.

You could put the pin numbers for the leds in a array. That makes the code easier.

Go through your sketch and make the text of the source code look nice, that is enough to fix the bug.

Does this look better ?

unsigned long previousMillis;

void loop() 
{
  // millis-timer of 100Hz
  unsigned long currentMillis = millis();

  // Get the sensor data every time the loop runs.
  // Could this be also put the millis-timer ?
  mpu.update();

  // -----------------------------------------------
  // A millis-timer of 100Hz
  // -----------------------------------------------
  if( currentMillis - previousMillis >= 10)
  {
    previousMillis = currentMillis;

    // Get the data
    float x = mpu.getAngleX();
    float y = mpu.getAngleY();
    float z = mpu.getAngleZ();

    // set the leds
    if( y < 3.0)
    {
      digitalWrite(Pin_7, HIGH);
    } 

    // print the values
    Serial.print( "X : ");
    Serial.print( x);
    Serial.print( "\tY : ");
    Serial.print( y);
    Serial.print( "\tZ : ");
    Serial.print( z);
    Serial.println();
  }
}
1 Like

yes this is a much better version, would it be possible to use a switch case, instead of using an if statement?

In order to use switch/case, which I am a fan of, the cases need to be an integer or an expression that resolves to an integer

The GCC compiler also allows the use of ranges in this format


void setup()
{
  Serial.begin(115200);
  while (!Serial);
  Serial.println();
  for (int x = 0; x < 15; x++)
  {
    Serial.print(x);
    switch (x)
    {
      case 0 ... 4:
        Serial.println(" 0 to 4");
        break;
      case 5 ... 10:
        Serial.println(" 5 to 10");
        break;
      case 11 ... 12:
        Serial.println(" 11 to 12");
        break;
      default :
        Serial.println(" out of range");
        break;
    }
  }
}

void loop()
{
}
1 Like

Why? Are you trying to earn your switch/case merit badge or something?

Sometimes if/else is better, sometimes switch/case works better.

Often you can do it either way. There are many things that go into choosing which to employ in a given circumstance. This may be a case where switching (see what I did there?) would be more trouble than it's worth.

a7

1 Like

switch/case never works better than if/else

What is true is that sometimes one or the other may be more convenient to use.

If there are more than 2 cases that already resolve to an integer then I would favour switch/case every time. It is so much easier to read and understand than if/else if/else and the more cases there are the better it gets

Yeah, OK.

I use works a little more broadly, along the lines of your remarks.

for loops work better than goto, &c.

And wouldn’t you say that switch/case (or if/else) might “work better” if one considers run time or space?

Asides, I kinda avoid never and always except when telling white lies to noobs. :expressionless:

a7

I'm working on converting my code using a switch case but running into the same "expected primary expression before ','" on for (pin_7) statement, what could be wrong?

[code]
/* Get tilt angles on X and Y, and rotation angle on Z
 * Angles are given in degrees
 * 
 * License: MIT
 */

#include "Wire.h"
#include <MPU6050_light.h>

MPU6050 mpu(Wire);
unsigned long timer = 0;



void setup() {
  Serial.begin(115200);
  Wire.begin();
  
  byte status = mpu.begin();
  Serial.print(F("MPU6050 status: "));
  Serial.println(status);
  while(status!=0){ } // stop everything if could not connect to MPU6050
  
  Serial.println(F("Calculating offsets, do not move MPU6050"));
  delay(1000);
  // mpu.upsideDownMounting = true; // uncomment this line if the MPU6050 is mounted upside-down
  mpu.calcOffsets(); // gyro and accelero
  Serial.println("Done!\n");

 

for (int pin_1 =4;,mpu.getAngleX()<3 )
pinMode(pin_1, OUTPUT); 

for (int pin_2 =7;,mpu.getAngleX()<2)
pinMode(pin_2, OUTPUT);


for (int pin_3 =6;,mpu.getAngleX()<1)
pinMode(pin_3, OUTPUT);


for (int pin_4 =7;,mpu.getAngleX()<0)
pinMode(pin_4, OUTPUT);


for (int pin_5 =8;,mpu.getAngleX()<-1)
pinMode(pin_5, OUTPUT);


for (int pin_6 =9;,mpu.getAngleX()<-2)
pinMode(pin_6, OUTPUT);


for ((int pin_7 =11); (mpu.getAngleX()<-3);)
pinMode(pin_7, OUTPUT);

}

void loop() {
  mpu.update();
  
  if((millis()-timer)>10){ // print data every 10ms
  Serial.print("X : ");
  Serial.print(mpu.getAngleX());
  Serial.print("\tY : ");
  Serial.print(mpu.getAngleY());
  Serial.print("\tZ : ");
  Serial.println(mpu.getAngleZ());
  timer = millis();  
  }


switch (mpu.getAngleX())
{
case 'a';
digitalWrite(Pin_1, HIGH); 
 break; 

 case 'b'
 digitalWrite(Pin_2, HIGH); 
break; 

case 'c';
digitalWrite(Pin_3, HIGH); 
 break; 

case 'd';
digitalWrite(Pin_4, HIGH); 
 break; 

case 'e';
digitalWrite(Pin_5, HIGH); 
 break; 


case 'f';
digitalWrite(Pin_6, HIGH); 
 break; 

case 'g';
digitalWrite(Pin_7, HIGH); 
 break; 
}

[/code]

You have done it again !

for loops do not work better than goto. They work differently, may be easier to understand and to debug, but they do they "work better" ?

As you say, "Work better" is meaningless without context
Does it mean that less memory is used ?
Does it mean that the code works faster ?
Both ?
Something else ?
Does it actually matter as long as the sketch works well enough to meet the requirements ?

Compared to C++ English is a terrible language, being so open to interpretation. What we need is the equivalent of K&R's " The C Programming Language" for English and that is before we introduce the idea of British English and American English into the discussion !