jremington:
The sketch you posted has nothing to do with the problem.
With the MPU-6050, yaw will always drift. The combination of the display code and the MPU-6050 code will take up most of the memory, and if you use String objects, the memory problems with Strings will cause it to crash.
You're right, Ill try and post the correct one within a code block here. It has a library in it I created which is used to find the intersections between the horizon line and points on the circle:
#include <DQCircular.h>
#include <SPI.h>
#include <Wire.h>
#include <MPU6050_light.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
MPU6050 mpu(Wire);
float basex;
float basey;
int samples = 0;
/*
Attitude Indicator on supper small 128/64 screen
*/
void setup() {
Serial.begin(115200);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
byte status = mpu.begin();
while (status != 0) { } // stop everything if could not connect to MPU6050
mpu.calcOffsets(true, true); // gyro and accelero
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(250); // Pause for 2 seconds
// Clear the buffer
display.clearDisplay();
display.display();
delay(200);
// Let user know wer are initializing variables
display.clearDisplay();
display.setTextSize(1); // Draw 2X-scale text
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 0);
display.print(F("Initializing"));
display.setCursor(10, 20);
display.print(F("Unit"));
display.display(); // Show initial text
delay(100);
display.startscrolldiagright(0x00, 0x07);
bool changes = true;
double startup = millis();
while (changes && millis() - startup < (30000))
{
mpu.update();
basex += mpu.getAngleX();
basey += mpu.getAngleY();
samples++;
delay(100);
}
basex = basex / samples;
basey = basey / samples;
delay(2000);
display.stopscroll();
show(mpu.getAngleX() - basex, mpu.getAngleY() - basey);
delay(1000);
}
void loop() {
mpu.update();
//Serial.print("X: "); Serial.println(mpu.getAngleX());
//Serial.print("Y: "); Serial.println(mpu.getAngleY());
show(mpu.getAngleX() - basex, mpu.getAngleY() - basey);
delay(500);
}
void show(int deg, int attitude) {
// fill in all the circle to start
display.fillCircle(display.height() / 2, display.height() / 2, (int) display.height() / 2, SSD1306_WHITE);
Intercepts ipt = Intercepts(display.height() / 2, deg, attitude);
// find out if the left or right is the highest point (we will be blackening up to here with a rectangle);
Point rtop = ipt.right;
Point rbot = ipt.left;
if (ipt.left.Y > rtop.Y)
{
rtop = ipt.left;
rbot = ipt.right;
}
Point rtopfixed = ipt.refix(rtop, display.height() , display.height() );
Point rbotfixed = ipt.refix(rbot, display.height() , display.height() );
display.fillRect(0, 0, display.height() , rtopfixed.Y, SSD1306_BLACK);
// if the highest point also has the highest x value then we draw a triangle from that point down to the x intercept and back up to 0,0
Point tri_pt[3];
if (ipt.left.Y > ipt.right.Y)
{
tri_pt[0] = ipt.refix(ipt.left, display.height() , display.height() );
Point fig1 = ipt.refix(ipt.right, display.height() , display.height());
float m = (tri_pt[0].Y - fig1.Y) / (tri_pt[0].X - fig1.X);
float b = fig1.Y - fig1.X * m;
tri_pt[1] = Point(display.height(), display.height() * m + b);
tri_pt[2] = Point(display.height() , tri_pt[0].Y);
}
else
{
// our triangle goes from right point to x intercept to (0, right.Y)
ipt.left.prt();
ipt.right.prt();
//ipt->refix(ipt->left, display.height(), display.height())->prt();
//ipt->refix(ipt->right, display.height(), display.height())->prt();
tri_pt[0] = ipt.refix(ipt.right, display.height() , display.height() );
Point fig1 = ipt.refix(ipt.left, display.height() , display.height() );
float m = (tri_pt[0].Y - fig1.Y) / (tri_pt[0].X - fig1.X);
float b = fig1.Y - fig1.X * m;
tri_pt[1] = Point(0, b);
tri_pt[2] = Point(0, tri_pt[0].Y);
}
display.fillTriangle(tri_pt[0].X, tri_pt[0].Y, tri_pt[1].X, tri_pt[1].Y, tri_pt[2].X, tri_pt[2].Y, SSD1306_BLACK);
display.drawCircle(display.height() / 2, display.height() / 2, (int) display.height() / 2, SSD1306_WHITE);
// clear text area for our angle display and then display it
display.fillRect(display.height() + 1, 0, (display.width() - (display.height() + 1)), display.height(), SSD1306_BLACK);
//display.display();
display.setCursor(display.height() * 1.1, display.height() / 6);
display.print("Roll: ");
display.print(deg);
display.setCursor(display.height() * 1.1, display.height() / 6 * 5);
display.print("Pt: ");
display.print(0 - attitude);
display.println("");
int midbarwidth = display.height() * .65;
display.fillRect(display.height() / 2 - midbarwidth / 2, display.height() / 2 - 1, midbarwidth, 2, SSD1306_INVERSE);
const float w_mul[] = {15, 55, 15, 55};
for (int ii = 0; ii < 3; ii++)
{
// print a + and - line at 5 degree pitch intervals
Intercepts pos = Intercepts(display.height() / 2, 0, (ii + 1) * 5);
Intercepts neg = Intercepts(display.height() / 2, 0, (ii + 1) * -5);
midbarwidth = display.height() * w_mul[ii] / 100;
Point posleft = Point(display.height() / 2 - midbarwidth / 2, pos.refix(pos.left, display.height(), display.height()).Y);
Point posright = Point(display.height() / 2 + midbarwidth / 2, pos.refix(pos.right, display.height(), display.height()).Y);
Point negleft = Point(display.height() / 2 - midbarwidth / 2, neg.refix(neg.left, display.height(), display.height()).Y);
Point negright = Point(display.height() / 2 + midbarwidth / 2, neg.refix(neg.right, display.height(), display.height()).Y);
display.drawLine(posleft.X, posleft.Y, posright.X, posright.Y, SSD1306_INVERSE);
display.drawLine(negleft.X, negleft.Y, negright.X, negright.Y, SSD1306_INVERSE);
}
display.display();
}