Gyroscope Led Control With Arduino

15,612

57

70

Posted

Introduction: Gyroscope Led Control With Arduino

In this project i will show you how to build a simple 4 led tilt dimmer with a gyroscope and an arduino uno. There are 4 leds arranged in a "+" shape and they will light up more as you tilt the breadboard.

This won't involve any soldering, just basic breadboard assembly and basic arduino programming.

Step 1: Materials:

1) An Arduino Uno board and a USB cable. You can use a different board if you like but keep in mind that different boards have different pin configs, for example if you use an Arduino Mega the SDA and SCL pins are 20 and 21.

2) 4 leds, the leds should be identical , the color doesn't matter it's up to you :)

3) 4 identical resistors anywhere between 100 ohms and 1 K ohm, i recommend around 200

4) a breadboard

5) dupont wires

6) MPU-6050 gyro

7) U-shape jumper cables (optional). I've used these jumper cables because they look better on the breadboard, and the leds are more visible this way. You can find a box of 140 on ebay at about 4$. If you don't have these cables you can replace them with dupont wires.

Step 2: Assembly

1) Begin by placing the 4 leds on the breadboard in a "+" shape. The long pins of the leds are positive. I've placed the positive pins for the top and bottom leds on the right, and for the left and right leds below (see on the first picture.

2) Insert the four resistors in the breadboard.

3) Place the MPU6050 like in the picture

4) Insert the wires. The leds ground pins will go directly to the ground. The positive pins will go through a resistor into the arduino pins: pin 3 through a resistor to the front led, pin 5 through a resistor to the bottom led, and similar with pin 6 right led, pin 9 left led

The MPU6050 must be connected to ground and 5V+, after that connect SDA to A4 (analog 4), SCL to A5

I've also attached an fritzig schematic, if you want to make sure the connections are correct.

Step 3: The Code

   You will need two external libs I2CDev and MPU6050, i've attached them here, and i've posted below the source of the code. I've not written those libs it's not my merit :)

If you don't know how to install a library check this instructable:

Then copy paste or download my library and give it a try.

* I2CDev library source: https://github.com/jrowberg/i2cdevlib

Step 4: Improvements and Different Uses of the Gyro

This is the simplest project i've done with MPU6050, i can think of many derivatives from this idea:

- adding two or more leds for each direction, so the steeper the angel, the more leds will light up

- making a wearable that will warn you with a sound that you don't have a correct upright position

Those ugly conditions i think can be improved with some math (replace if's with some equations).

As a BONUS :) i've made a youtube video with another version of the project, i've added 3 leds for up, e for down, 2 for left and two for right.

If you want to check the video click here. I've also attached a picture of the breadboard above.

For those who are interested the code go here, and replace this line

#define SIMPLE_IMPLEMENTATION true

---------- with -----------

#define SIMPLE_IMPLEMENTATION false<br>

The new led pinout is: front leds: 3,12,11, bottom leds: 5,6,7, left leds: 10, 4, right leds: 6, 9

In my other tutorial i've shown how the gyroscope can be used toflip the display on the computer when the display is physically rotated. The instructable is here.

If you liked the youtube videos, you can get more by subscribing to my channel here

Step 5: A Recent Add-on to This Tutorial, a Neopixel Ring Driven by a Gyroscope

You can find the code here if you're interested about that.

Share

  • Hello, help my to mo...-AlexR385

    AlexR385 made it!

Recommendations

  • Epilog Challenge 9

    Epilog Challenge 9
  • Sew Warm Contest 2018

    Sew Warm Contest 2018
  • Paper Contest 2018

    Paper Contest 2018
user

We have a be nice policy.
Please be positive and constructive.

Tips

Questions

62 Comments

Hi my friend,

My project is that assemble the gyro and arduino to bicycle helmet. When I assemble it ,i will solve my right and left signal problem. When i rotate my head 15 agree to left , the led will open. So, drivers will be understood what direction i will go.

Thank you for sharing the code . It help me so much to do my project. However, I struggle with a possibility of giving wrong decision. It means that when i want to turn right but i rotate my head15 degree to left. After that I understand my decision wrong and I changed my brain right but i wait the time to signal close for left.

How can I change your code according to my project. At the below , You can see my updated code

/**

* Simple implementation false

*

* means that for pitch/yaw there only be

* a single led for each direction. The led will get more bright

* as the direction increases

*

* Simple implementation true

* means that for pitch/yaw there will be multiple led's that light up one by one

*

* The accelerometer/gyro is a MPU6050, it should be wired to the SDA and SCL pins

*/

#define SIMPLE_IMPLEMENTATION false

const int frontLed = 3;

const int bottomLed = 5;

const int rightLed = 6;

const int leftLed = 9;

long int lastPrintTime;

typedef struct

{

byte pin;

byte positionInsideGroup;

char thePosition; // Left, Right, Up, Down

byte minAngle;

byte maxAngle;

} ledConfig;

ledConfig leds[] = {

{3, 1, 'u', 5,15},

{12, 2, 'u', 16, 30},

{11, 3, 'u', 5, 15},

{5, 1, 'd', 5, 15},

{6, 2, 'd', 16, 30},

{7, 3, 'd', 31, 45},

{8 , 1, 'r', 5, 23},

{9, 2, 'r', 24, 45},

{10, 1, 'l', 5, 23},

{4, 2, 'l', 24, 45},

};

#include "I2Cdev.h"

#include "MPU6050_6Axis_MotionApps20.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE

#include "Wire.h"

#endif

MPU6050 mpu;

bool dmpReady = false; // set true if DMP init was successful

uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU

uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)

uint16_t packetSize; // expected DMP packet size (default is 42 bytes)

uint16_t fifoCount; // count of all bytes currently in FIFO

uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars

Quaternion q; // [w, x, y, z] quaternion container

VectorInt16 aa; // [x, y, z] accel sensor measurements

VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements

VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements

VectorFloat gravity; // [x, y, z] gravity vector

float euler[3]; // [psi, theta, phi] Euler angle container

float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector

volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high

void setup()

{

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE

Wire.begin();

TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)

#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE

Fastwire::setup(400, true);

#endif

Serial.begin(9600);

while (!Serial); // wait for Leonardo enumeration, others continue immediately

Serial.println(F("Initializing I2C devices..."));

mpu.initialize();

Serial.println(F("Testing device connections..."));

Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

Serial.println(F("Initializing DMP..."));

devStatus = mpu.dmpInitialize();

mpu.setXGyroOffset(220);

mpu.setYGyroOffset(76);

mpu.setZGyroOffset(-85);

mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

if (devStatus == 0) {

// turn on the DMP, now that it's ready

Serial.println(F("Enabling DMP..."));

mpu.setDMPEnabled(true);

Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));

attachInterrupt(0, dmpDataReady, RISING);

mpuIntStatus = mpu.getIntStatus();

Serial.println(F("DMP ready! Waiting for first interrupt..."));

dmpReady = true;

packetSize = mpu.dmpGetFIFOPacketSize();

} else {

Serial.print(F("DMP Initialization failed (code "));

Serial.print(devStatus);

Serial.println(F(")"));

}

if (SIMPLE_IMPLEMENTATION) {

initializeLEDsSimple();

} else {

initializeLEDsMultiple();

}

lastPrintTime = millis();

}

void loop()

{

if (!dmpReady) return;

mpuInterrupt = false;

mpuIntStatus = mpu.getIntStatus();

fifoCount = mpu.getFIFOCount();

if ((mpuIntStatus & 0x10) || fifoCount == 1024) {

mpu.resetFIFO();

Serial.println(F("FIFO overflow!"));

} else if (mpuIntStatus & 0x02) {

while (fifoCount < packetSize) {

fifoCount = mpu.getFIFOCount();

}

mpu.getFIFOBytes(fifoBuffer, packetSize);

fifoCount -= packetSize;

mpu.dmpGetQuaternion(&q, fifoBuffer);

mpu.dmpGetGravity(&gravity, &q);

mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

int x = ypr[0] * 180/M_PI;

int y = ypr[1] * 180/M_PI;

int z = ypr[2] * 180/M_PI;

Serial.print(y);

Serial.print("\t");

Serial.println(z);

if (SIMPLE_IMPLEMENTATION) {

flashLEDsSimple(x, y, z);

} else {

flashLEDsMultiple(x, y, z);

}

}

}

void initializeLEDsSimple()

{

Serial.print("int simple");

pinMode(frontLed, OUTPUT);

pinMode(bottomLed, OUTPUT);

pinMode(rightLed, OUTPUT);

pinMode(leftLed, OUTPUT);

}

void initializeLEDsMultiple()

{ Serial.print("int multiple");

for (int i=0; i<10; i++) {

Serial.println(leds[i].pin);

pinMode(leds[i].pin, OUTPUT);

}

delay(3000);

}

void flashLEDsSimple(int x, int y, int z)

{

Serial.print("led simple");

if (y > 0) {

analogWrite(rightLed, y*4);

analogWrite(leftLed, 0);

} else {

analogWrite(leftLed, y*4*-1);

analogWrite(rightLed, 0);

}

if (z > 0) {

analogWrite(bottomLed, z*4);

analogWrite(frontLed, 0);

} else {

analogWrite(frontLed, z*4*-1);

analogWrite(bottomLed, 0);

}

}

void flashLEDsMultiple(int x, int y, int z)

{

//Serial.print(z);Serial.print(",");Serial.print(leds[i].thePosition);Serial.print(",");Serial.println(leds[i].minAngle);

bool modified = false;

if (z < 0 && leds[0].thePosition == 'u' && abs(z) > leds[0].minAngle) {

for (int b=1; b <= 5; b++){

digitalWrite(leds[0].pin, HIGH);

delay(500);

digitalWrite(leds[0].pin, LOW);

delay(500);

}

modified = true;

}

if (!modified) {

digitalWrite(leds[0].pin, LOW);

}

if (z > 0 && leds[3].thePosition == 'd' && abs(z) > leds[3].minAngle) {

for (int a=1; a <= 5; a++){

digitalWrite(leds[3].pin, HIGH);

delay(500);

digitalWrite(leds[3].pin, LOW);

delay(500);

}

modified = true;

}

if (!modified) {

digitalWrite(leds[3].pin, LOW);

}

}

void dmpDataReady()

{

mpuInterrupt = true;

}

So you want to turn 15 degrees right and signal right or turn it 15 degrees left and signal left am i correct so far? If not can you please rephrase , and if i am right, what did it go wrong with the project? I don't understand what do you mean by "struggle with the possibility of wrong decision"

Hi my friend I want to make the same project by using an arduino genuino 101 and a neopixel ring. I am not so experienced so I would appreciate any advice. Do you think that I can use your code with some modifications? Thanks in advance!

Hey, if you're interested i've finished the project you wore asking about. The video is here: https://youtu.be/MFQ2PecTw8g and the code here: https://github.com/danionescu0/arduino/blob/master/projects/neopixel_ring_gyroscope/neopixel_ring_gyroscope.ino

Hmm, you have to modifiy the code a bit more, i think i'll buy one of those strips and make a new instructable

Meanwhile you can chech these links:
https://learn.adafruit.com/florabrella/test-the-neopixel-strip
https://www.hackster.io/zanycadencedev/getting-started-with-arduino-and-neopixels-013360

Thank you very much my friend for the reply! I 'll give it a try and we 'll see :) !

Hello. And thank you for posting this great project. I would like to create a similar project but to have a spinning top that lights up LEDs in the direction of the turn and also shows tilt. I would also like it too be self contained so it can be mobile. Any idea where to start?

Thanks. What do you mean by a spinning top? can you give me more details, maybe a picture with a sketch? Does it involve a gyroscope too ?

I am having Error "no match for operator! (!serial)" Am I missing library?

GyroscopeLedControll:77: error: no match for 'operator!' in '!Serial'