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