Hi everyone
Firstly apologies if the title isn't descriptive enough, I don't really know whats causing my issue so its the best I could come up with.
I have a MPU 6050 connect to a Arduino Uno. I am taking gyro readings from the MPU and looking at displaying these on a 1.3" OLED.
I used a smaller 0.9" OLED with the Adafruit SSD1306 library and it worked great. I then replaced the smaller OLED with the larger 1.3" version and found a library based on the Adafruit one that supported the new SH1106 OLED. A link to the library and the display can be found below.
https://www.netram.co.za/3374-13-128x64-oled-display-blue-iic.html
I then updated my code to make provision for the new display. Its not working however and I cant seem to figure out why. When I delete some of the MPU code in the void loop and setup, the display starts working but then obviously I cant read the MPU data. Please see below my code as reference. Any advice would be much appreciated.
#include <SPI.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include <Average.h>
//#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 mpu(0x68);
#define OUTPUT_READABLE_YAWPITCHROLL
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
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
//Calibration
float RollCalibrationReading; // initial roll reading before calibration, this value is used for calibrtion
float RollValue; // Roll angle
float CallibrationAdjustment; // Calibration adjustment
boolean RunCalibration = false; // has calibration run yet
// Handstand
boolean standStatus;
int HandStandCount = 0;
//Average<long> StandArray(100);
long recordDuration;
// timing
unsigned long startMillis;
unsigned long currentMillis;
unsigned long strandStartTime;
unsigned long standDuration;
unsigned long previousMillis = 0;
const long interval = 1000;
// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '
, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
mpuInterrupt = true;
}
//display
#define OLED_RESET 4
Adafruit_SH1106 display(OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000 };
#if (SH1106_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SH1106.h!");
#endif
void setup()
{
startMillis = millis();
// 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
Serial.begin(9600);
while (!Serial); // wait for Leonardo enumeration, others continue immediately
mpu.initialize();
devStatus = mpu.dmpInitialize();
mpu.setXGyroOffset(138);
mpu.setYGyroOffset(-37);
mpu.setZGyroOffset(41);
mpu.setZAccelOffset(1338); // 1688 factory default for my test chip
mpu.setDMPEnabled(true);
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
dmpReady = true;
packetSize = mpu.dmpGetFIFOPacketSize();
//display
display.begin(SH1106_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
// init done
// Show image buffer on the display hardware.
// Since the buffer is intialized with an Adafruit splashscreen
// internally, this will display the splashscreen.
display.display();
delay(1000);
// Clear the buffer.
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
}
void loop()
{
currentMillis = millis();
//avareage, max etc
int minat = 0;
int maxat = 0;
// if programming failed, don't try to do anything
if (!dmpReady) return;
while (!mpuInterrupt && fifoCount < packetSize) {
}
// 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;
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
RollValue = (ypr[2] * 180 / M_PI);
}
TestMeasurements();
}
// ================================================================
// === TEST MEAUSREMENTS ===
// ================================================================
void TestMeasurements() {
//current angle after calibration
if (currentMillis - previousMillis >= interval){
previousMillis = currentMillis;
display.clearDisplay();
display.setCursor(0, 0);
//display.println(RollValue);
display.print(millis()/1000);
display.display();
}
}