0

Hardare used: Arduino nano ( old Bootloader ) Oled Monochrome Display ( 4 pins, 128 x 32 ) MPU 6050

Both display and MPU use A4 and A5 as I2C communication protocol, They interfere, as the MPU is used 2-way and the Display 1-way.

  1. How can I change those 2 pins( does not matter witch Display/Sensor )
  2. Can this method ( the one you propose ) be used for more cases like this? ( ex 3 sensors )

There is what I tried so far:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif
MPU6050 mpu;

#define OUTPUT_READABLE_YAWPITCHROLL
#define OUTPUT_READABLE_REALACCEL

// 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

#define INTERRUPT_PIN 2  // use pin 2 on Arduino Uno & most boards
volatile bool mpuInterrupt = false;
void dmpDataReady() {
  mpuInterrupt = true;
}

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

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
   for(;;); // Don't proceed, loop forever
  }

  // Clear the buffer
  display.clearDisplay();

  delay(150);

  #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    Serial.println(F("Initializing I2C devices..."));
    mpu.initialize();
    pinMode(INTERRUPT_PIN, INPUT);

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

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

  if (devStatus == 0) {
        // Calibration Time: generate offsets and calibrate our MPU6050
        mpu.CalibrateAccel(6);
        mpu.CalibrateGyro(6);
        mpu.PrintActiveOffsets();
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.print(F("Enabling interrupt detection (Arduino external interrupt "));
        Serial.print(digitalPinToInterrupt(INTERRUPT_PIN));
        Serial.println(F(")..."));
        attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), 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(")"));
    }

    
  
  Serial.begin(9600);
}

void loop() {
  if (!dmpReady) return;
    // read a packet from FIFO
    if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet 
        
        #ifdef OUTPUT_READABLE_YAWPITCHROLL
            // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            /*
            data.gyro_data[0] = ypr[0] * 180/M_PI;
            data.gyro_data[1] = ypr[1] * 180/M_PI;
            data.gyro_data[2] = ypr[2] * 180/M_PI;
            */
        #endif

        #ifdef OUTPUT_READABLE_REALACCEL
            // display real acceleration, adjusted to remove gravity
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetAccel(&aa, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
            /*
            data.acc_data[0] = aaReal.x;
            data.acc_data[1] = aaReal.y;
            data.acc_data[2] = aaReal.z;
            */
        #endif
    }
    
    display.print(String(ypr[0] * 180/M_PI));
    display.print('/');
    display.print(String(ypr[1] * 180/M_PI));
    display.print('/');
    display.print(String(ypr[2] * 180/M_PI));
    display.print("\n\n");
    display.print(String(aaReal.x));
    display.print('/');
    display.print(String(aaReal.y));
    display.print('/');
    display.print(String(aaReal.z));
    

    //display.print(String(data.id));
    display.display();
    
    
    delay(500);
}

Now I know this looks like a bunch of code thrown together with the hope to work, But it is composed from 2 other of my codes separately for MPU and Display, those work fine.

4
  • 4
    They interfere, as the MPU is used 2-way and the Display 1-way. -- No, that's nonsense. I2C is bidirectional half duplex regardless. Even if you only think you use one direction you're actually always using both. You have described everything except the actual problem You say they "interfere" but don't actually tell us how you think they interfere with each other or what the symptoms actually are.
    – Majenko
    Sep 16 at 18:18
  • 1
    Several devices can share an I2C bus, unless they have the same address (which is unlikely with a display and an MPU).
    – PMF
    Sep 16 at 18:36
  • There are many aspects of your code that don't make any sense. Such things as the whole of the interrupt system (which appears to do nothing at all).
    – Majenko
    Sep 17 at 12:34
  • #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" take care of communication with the MPU, and through previous tests the interrupt pin stabilises the z-axis. I used this as a reference. Then what I mean by interference is that normally the display would show 0.00/0.00/0.00 on two lines, ( as there is no data). But with the MPU added it just shows some random pixels on. Sep 20 at 17:26
1

So after repeated tests I found several problems, software and hardware.

  1. The cables I used on the breadboard where facing each other. The metal parts where touching ( from a defect of the cables ). Turned them 90*.

  2. The Oled display was NOT Initialized properly. When using display.write() or display.print() you must first put the cursor at (0;0) by display.setCursor(0,0). Furthermore for more compatibility in Setup(){} you have to add display.setTextSize(1) and display.setTextColor(WHITE).

  3. Power control. I found the best, either adding a capacitor on the VCC and GND lines when using them to power 2 Sensors at the same time, or ad a 5 mls delay in the first function. delay(5)

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.