No title

#include <Adafruit_GFX.h>


#include <Adafruit_ST7735.h>


#include <SPI.h>


#include <Wire.h>


#include <MPU6050.h>




#define TFT_CS   10


#define TFT_RST  8


#define TFT_DC   9




Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);


MPU6050 mpu;




// Colors


#define SKY_BLUE   tft.color565(0, 102, 204)


#define GROUND_BR  tft.color565(153, 76, 0)


#define YELLOW     ST77XX_YELLOW


#define WHITE      ST77XX_WHITE


#define BLACK      ST77XX_BLACK




// Center


const int cx = 80;


const int cy = 64;




// ===== Control Tuning =====


const int frameDelay = 1;        // ⏱ ~40 FPS


const float threshold = 0.80;     // redraw sensitivity


const float alpha = 0.58;         // smoothing




// ===== Variables =====


float pitchFiltered = 0;


float lastPitch = 999;


unsigned long lastFrame = 0;




void setup() {


  Wire.begin();


  mpu.initialize();




  tft.initR(INITR_BLACKTAB);


  tft.setRotation(1);




  tft.fillScreen(BLACK);


  drawFrame();


}




void loop() {




  // ⏱ frame limiter


  if (millis() - lastFrame < frameDelay) return;


  lastFrame = millis();




  updateIMU();




  // 🔥 redraw only if movement detected


  if (abs(pitchFiltered - lastPitch) > threshold) {


    drawHorizon();


    lastPitch = pitchFiltered;


  }


}




// ================= MPU READ =================


void updateIMU() {




  int16_t ax, ay, az, gx, gy, gz;


  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);




  float axf = ax / 16384.0;


  float azf = az / 16384.0;




  float pitch = atan2(axf, azf) * 180 / PI;




  // smoothing filter (removes jitter)


  pitchFiltered = alpha * pitchFiltered + (1 - alpha) * pitch;




  // dead zone (stop micro noise)


  if (abs(pitchFiltered) < 0.1) pitchFiltered = 0;


}




// ================= FRAME =================


void drawFrame() {


  tft.drawCircle(cx, cy, 60, WHITE);


}




// ================= HORIZON =================


void drawHorizon() {




  int scale = 3;


  int offset = pitchFiltered * scale;


  offset = constrain(offset, -50, 50);




  int horizonY = cy + offset;







  // SKY


  tft.fillRect(0, 0, 160, horizonY, SKY_BLUE);




  // GROUND


  tft.fillRect(0, horizonY, 160, 128, GROUND_BR);




  // Horizon line


  tft.drawFastHLine(0, horizonY, 160, WHITE);




  // Pitch markings


  for (int i = -3; i <= 3; i++) {




    int y = horizonY - (i * 15);




    if (i != 0) {


      tft.drawFastHLine(cx - 20, y, 40, WHITE);


    }




    int value = i * 10;


    String valStr = (value > 0) ? "+" + String(value) : String(value);




    tft.setTextSize(1);


    tft.setTextColor(WHITE);




    tft.setCursor(2, y - 3);


    tft.print(valStr);




    tft.setCursor(142, y - 3);


    tft.print(valStr);


  }




  // Aircraft symbol (fixed center)


  tft.fillRect(cx - 30, cy, 60, 2, YELLOW);


  tft.drawLine(cx - 10, cy, cx, cy + 8, YELLOW);


  tft.drawLine(cx, cy + 8, cx + 10, cy, YELLOW);


  tft.fillCircle(cx, cy, 2, YELLOW);




  // frame border


  tft.drawCircle(cx, cy, 60, WHITE);


}

Post a Comment

Previous Post Next Post

Contact Form