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.
- How can I change those 2 pins( does not matter witch Display/Sensor )
- 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.
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.#include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h"
take care of communication with the MPU, and through previous tests theinterrupt 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.