1

I am using an Arduino Uno and Relay Shield (http://www.seeedstudio.com/blog/2013/02/28/shield-evolution-flexible-add-ons-for-arduino/relay-shield/), and using a code similar to the Teapot Demo, in which an LED blinks when movement is detected. When I connect the shield, the LED blinks at the normal brightness when uploading the code, but blinks extraordinarily dimly when indicating movement. This is both the external and internal LED display for the Arduino.

This is my current setup:

enter image description here

I think it must be a code issue because the LED clearly has the ability to blink on and off normally. Any suggestions as to what is wrong or what I should do?

Below is my code:

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif
MPU6050 mpu;
// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
// components with gravity removed. This acceleration reference frame is
// not compensated for orientation, so +X is always +X according to the
// sensor, just without the effects of gravity. If you want acceleration
// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
#define OUTPUT_READABLE_REALACCEL

// uncomment "OUTPUT_TEAPOT" if you want output that matches the
// format used for the InvenSense teapot demo
#define OUTPUT_TEAPOT

//----------------------------------------------------------------------------------------------

const int LED_PIN = 13; // (Arduino is 13, Teensy is 11, Teensy++ is 6)
const int buzzerPin = 12;

bool blinkState = false;

// MPU control/status vars
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

// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };


// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #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

    // initialize serial communication
    // (115200 chosen because it is required for Teapot Demo output, but it's
    // really up to you depending on your project)
    Serial.begin(115200); // this is a "Baud" rate
    while (!Serial); // wait for Leonardo enumeration, others continue immediately

    // initialize device
    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();

    // verify connection
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

    // wait for ready
    Serial.println(F("\nSend any character to begin DMP programming and demo: "));
    while (Serial.available() && Serial.read()); // empty buffer
    while (!Serial.available());                 // wait for data
    while (Serial.available() && Serial.read()); // empty buffer again

    // load and configure the DMP
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

    // supply your own gyro offsets here, scaled for min sensitivity
    mpu.setXGyroOffset(220);
    mpu.setYGyroOffset(76);
    mpu.setZGyroOffset(-85);
    mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

    // make sure it worked (returns 0 if so)
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

        // get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }

    // configure LED for output
    pinMode(LED_PIN, INPUT);
    pinMode(buzzerPin, INPUT);
}

// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {
    // if programming failed, don't try to do anything
    if (!dmpReady) return;

    // wait for MPU interrupt or extra packet(s) available
    while (!mpuInterrupt && fifoCount < packetSize) {
        // other program behavior stuff here
    }

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);

        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;

        #ifdef OUTPUT_READABLE_REALACCEL
            // display real acceleration, adjusted to remove gravity
            int Mag;
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetAccel(&aa, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
            Serial.print("areal\t");
            Serial.print(aaReal.x);
            Serial.print("\t");
            Serial.print(aaReal.y);
            Serial.print("\n");
            Mag = sqrt((aaReal.x*aaReal.x) + (aaReal.y*aaReal.y));
            Serial.print("Accel. Mag. is ");
            Serial.print(Mag);
//            Serial.print("\t");
//            Serial.println(aaReal.z);
        #endif

        #ifdef OUTPUT_TEAPOT
            // display quaternion values in InvenSense Teapot demo format:
            teapotPacket[2] = fifoBuffer[0];
            teapotPacket[3] = fifoBuffer[1];
            teapotPacket[4] = fifoBuffer[4];
            teapotPacket[5] = fifoBuffer[5];
            teapotPacket[6] = fifoBuffer[8];
            teapotPacket[7] = fifoBuffer[9];
            teapotPacket[8] = fifoBuffer[12];
            teapotPacket[9] = fifoBuffer[13];
            Serial.write(teapotPacket, 14);
            teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
        #endif

        // blink LED and sound buzzer to indicate activity
        if (Mag > 120) {
          blinkState = !blinkState;
          digitalWrite(LED_PIN, blinkState);
//          delay(1000);
          tone(buzzerPin, 100);
        }
        else if (Mag <= 120) {
          digitalWrite(LED_PIN, LOW);
          noTone(buzzerPin);
        }

    }
}
  • 1
    If it gets dimmed when you're trying to switch the relay on, you don't have power supply powerfull enough to drive it. USB is too weak for this. – KIIV Jun 5 '18 at 15:21
  • I thought this may be the case - I am also using a wall wart to supply 12V of power. It is not changing the output brightness though. Is there another component missing? – elarr Jun 5 '18 at 15:34
1

Without seeing your code, it is hard to tell you directly what the problems is. If you can, please post your code.

Based on the information in your question, I can see two possible causes for this.

Firstly, it could be that there isn't enough power from your supply to power everything. So when the Arduino tries to turn on the relay, it doesn't have enough grunt and the voltage drops too low and the Arduino resets, de-energising the relay. This happens many times a second and shows up as a dull LED.

This can be proven by disconnecting the relay from the Arduino output. Run the sketch again, and if everything works at full brightness without the relay connected, then it is almost certainly not enough power.

My second theory is that it is a bug in your code. Some cycles it detects movement and so it turns the LED on. Others cycles it doesn't detect a change in movement so it turns the LED off. This happens many thousand times a second. It would be visible on an oscilloscope if you have one.

The simple thing you could do for this scenario is to add a delay (eg delay(1000);) straight after the LED is turned on when movement is detected. This should leave the LED on for at least a second after movement is detected.

  • You're probably right. I added a delay and the LED was dimly glowing even when using the wall wart. I have another wall wart that has bare wires so that I can use it as an external power source. Do you think this would work? If so, should I just hook the LED up directly to one end and ground the other? – elarr Jun 5 '18 at 17:38
  • What is the current output of the wall warts? What you suggest is what I would look into. I would just be cautious doing so. Examine the schematics of each to make sure that one doesn't feed into the other. – sa_leinad Jun 6 '18 at 2:50
  • The current output is 800mA. I got the larger LED to glow, which was the main goal, so it may have just been due to faulty wiring on my part. Thank you for your help! – elarr Jun 6 '18 at 11:45

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.