کوډ ولټوئ

د ESP32-S3 RGB LED میټرکس پروژه ۵ - تل پورته تیر

د ESP32-S3 RGB LED میټرکس پروژه ۵ - تل پورته تیر

پروژه ۵ – تیر تلویحاً پورته (د سمت ښودونکی د QMI8658C په کارولو سره)

پروژه ۵ د QMI8658C حرکت سینسر کاروي ترڅو د ESP32-S3 RGB LED میټرکس سمت وپیژني او تل یو تیر ښکاره کړي چې د جاذبې په نسبت پورته ګوته کوي. مهمه نده چې تاسو بورډ څنګه وګرځوئ — د USB اړخ پورته، د OUSB اړخ پورته، اړخ "۱۵"، یا اړخ "۳۴" — تیر په اتوماتيک ډول ګرځي او د فزیکي پلوه پورته لوري ته اشاره کوي.

دا د آنبورډ اکسلرومیټر په کارولو سره د ریښتیني وخت سمت احساس یوه پیاوړې ننداره ده. د دې ماډل ټول شپږ پروژې په یوه YouTube ویډیو کې نندارې ته وړاندې شوي، کوم چې په دې پاڼه کې هم ځای پر ځای شوی. د پروژې ۵ بشپړ کوډ په اتوماتيک ډول د مقالې لاندې بار کیږي، او اړوند لینکونه د کوډ برخې لاندې ښکاري.

د ESP32-S3 RGB LED میټرکس ماډل عمومي کتنه

د ESP32-S3 RGB LED میټرکس ماډل ډیری برخې لري چې دا پروژه ممکنه کوي:

  • ESP32-S3 مایکروکنټرولر — Wi-Fi، BLE چمتو کوي، او د LED/IMU منطق چلوي.
  • ۸×۸ RGB LED میټرکس — تیر په څلورو سمتونو کې ښکاره کوي.
  • QMI8658C اکسلرومیټر — ټیلټ، حرکت، او سمت کشف کوي.:contentReference[oaicite:0]{index=0}
  • USB-C بندر د بریښنا او پروګرام کولو لپاره په Arduino IDE کې.
  • ریسیټ او بوټ تڼۍ د سکیچونو اپلوډ کولو لپاره.
  • GPIO پنونه د اضافي پروژو لپاره د بورډ شاوخوا شتون لري.

د تیر لوری په بشپړه توګه د اکسلرومیټر لوستلو لخوا ټاکل کیږي. کله چې بورډ وګرځول شي، QMI8658C نوي X/Y/Z ارزښتونه احساسوي، او سکیچ غوره کوي چې کوم تیر نمونه (↑، ↓، ←، →) باید رسم شي.

په ویډیو کې پوښل شوي پروژې (وختونه)

  • 00:00 – پیژندنه
  • 02:01 – د ESP32 بورډونو نصبول
  • 03:32 – د کتابتونونو نصبول
  • 05:32 – پروژه ۱: حرکت کوونکی نقطه
  • 11:11 – پروژه ۲: متن سکرول
  • 12:59 – پروژه ۳: HTTP متن
  • 16:41 – پروژه ۴: ټیلټ نقطه
  • 18:55پروژه ۵: تیر تل پورته (دا پروژه)
  • 20:02 – پروژه ۶: هدف لوبه

ویډیو په روښانه توګه ښیي چې تیر څنګه سمدلاسه خپل لوری بدلوي د دې پر بنسټ چې ماډل څنګه ګرځول شوی. د دې برخې لیدل په کلکه سپارښتنه کیږي.:contentReference[oaicite:1]{index=1}

په Arduino IDE کې د ESP32 بورډونو نصبول

که تاسو کوم مخکینی پروژه بشپړه کړې وي، د بورډ تنظیم دمخه ترسره شوی. په بل صورت کې:

  1. File > Preferences → د ESP32 بورډ URL اضافه کړئ
  2. Tools > Board > Boards Manager… → "ESP32" نصب کړئ
  3. د ESP32-S3 بورډ د Tools > Board لاندې غوره کړئ
  4. د سم USB COM بندر د Tools > Port لاندې غوره کړئ

د اړینو کتابتونونو نصبول

پروژه ۵ کاروي:

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX
  • QMI8658 (د حرکت سینسر)
  1. Sketch > Include Library > Manage Libraries…
  2. لټون: NeoMatrix → نصب کړئ
  3. انحصارونه نصب کړئ: NeoPixel + GFX
  4. د QMI8658 لټون او د هغه لیکوال لخوا نصب کړئ

پروژه ۵ څنګه کار کوي

QMI8658C په X، Y، او Z محورونو کې جاذبه اندازه کوي. د دې ارزښتونو پرتله کولو سره، سکیچ ټاکي چې د بورډ کوم فزیکي اړخ پورته دی:

  • د USB اړخ پورته
  • د OUSB اړخ پورته (د USB مخالف)
  • اړخ "۱۵" پورته
  • اړخ "۳۴" پورته

هر سمت د ۸×۸ میټرکس په بیلابیل تیر نمونه سره مطابقت لري. نقشه ستاسو د تایید شوي سمت منطق تعقیبوي د مخکینیو ډیباګ کولو ناستو څخه. د بورډ څرخول په دوامداره توګه لوستل کیږي، او تیر سمدلاسه تازه کیږي کله چې پورته اړخ بدل شي.

پروژه ۵ – د کوډ ترتیبات (تیر تل پورته)

لاندې د کاروونکي لخوا تنظیم کیدونکي ارزښتونه د ترتیب ساحې څخه دي. بشپړ پروژه کوډ په اتوماتيک ډول د مقالې لاندې ښکاري.

د میټرکس ترتیب


// د میټرکس ترتیب
const int MATRIX_PIN    = 14;   // د دې ماډل لپاره ټاکل شوی
const int MATRIX_WIDTH  = 8;
const int MATRIX_HEIGHT = 8;

// سپارښت شوی سمت: پورته-کیڼ اصل، پرمختللی حالت
// (اصلي جوړونکی د لاندې بار شوي کوډ دننه دی)

دا پروژه د NEO_MATRIX_PROGRESSIVE ترتیب کاروي ترڅو ډاډ ترلاسه شي چې تیر د اصلي حرکت پر بنسټ په سمه توګه ګوته کوي.

روښانتیا


uint8_t matrixBrightness = 40;   // 0–255

تاسو کولی شئ دا ارزښت د روښانه چاپیریال لپاره لوړ کړئ. د کورني استعمال لپاره، ۳۰–۶۰ آرام دی.

د تیر رنګ


// د تیر رنګ
uint8_t arrowRed   = 255;
uint8_t arrowGreen = 0;
uint8_t arrowBlue  = 0;

دا ارزښتونه بدل کړئ ترڅو د تیر رنګ تعدیل کړئ. د مثال په توګه:

  • شین تیر: (0, 255, 0)
  • نیلي تیر: (0, 0, 255)
  • سپین تیر: (255, 255, 255)

حساسیت او نرمول

د لړزیدو مخنیوي لپاره، کوډ د نرمولو او حد منطق شاملوي. په ترتیباتو کې تاسو ممکن داسې څه ومومئ:


// د حساسیت / نرمولو تنظیم
float tiltThreshold = 0.30f;   // تنظیم کړئ که تیر ډیر اسانه بدل شي
  • که ستاسې تیر ډېر اسانه ښورېږي → لوړ کړئ حد (threshold).
  • که تیر د بدلون لپاره ډېر ورو وي → کم کړئ حد (threshold).

د تیر نمونې (Arrow Patterns)

سکیچ (sketch) د تیر بټ میپ (bitmap) نمونې لپاره لاندې شاملوي:

  • ↑ پورته
  • ↓ ښکته
  • ← کیڼ
  • → ښي

تاسو اړتیا نلرئ دا بدل کړئ، مګر که تاسو بېله بڼه غواړئ، تاسو کولی شئ د کوډ دننه شکلونه بدل کړئ.

لنډیز

پروژه 5 ښیي چې څنګه ESP32-S3 RGB LED Matrix او QMI8658C accelerometer په ګډه کار کوي ترڅو سمت (orientation) وپېژني او یو تیر ښکاره کړي چې تل پورته ټکي کوي. دا پروژه د Tilt Dot (پروژه 4) پر بنسټ ولاړه ده او تاسو د پروژه 6 په وروستۍ متقابلې لوبې لپاره چمتو کوي.

د “Arrow Always Up” بشپړ سکیچ (sketch) د دې مقالې لاندې شتون لري (په اتوماتيک ډول بار شوی). د ویډیو اړونده برخه کتل خورا سپارښتنه کیږي ترڅو وګورئ چې تیر څنګه سمدستي د بورډ د څرخېدو سره ځواب ورکوي. که تاسو غواړئ دا پروژه په کور کې جوړه کړئ، د ESP32-S3 RGB LED Matrix ماډل لپاره اړوند (affiliate) لینکونه د کوډ برخې لاندې ښکاري.

انځورونه

ESP32 S3 Matrix
ESP32 S3 Matrix
ESP32 S3 Matrix  pin out
ESP32 S3 Matrix pin out
ESP32-S3_RGB_8x8_matrix-3
ESP32-S3_RGB_8x8_matrix-3
ESP32 S3 Matrix attached with buzzer to pin6 and GND
ESP32 S3 Matrix attached with buzzer to pin6 and GND
ESP32 S3 Matrix displaying red heart
ESP32 S3 Matrix displaying red heart
ESP32 S3 Matrix displaying green heart
ESP32 S3 Matrix displaying green heart
ESP32 S3 Matrix displaying rainbow heart 3
ESP32 S3 Matrix displaying rainbow heart 3
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix1
ESP32-S3_RGB_8x8_matrix-2
ESP32-S3_RGB_8x8_matrix-2
ESP32-S3-Mtrix - Alway Up
ESP32-S3-Mtrix - Alway Up
803-ESP32-S3 RGB LED Matrix Project 5 - Arrow always up
ژبه: C++
/* 
  Project 5: Arrow Always Up – ESP32-S3 RGB LED Matrix (Waveshare)
  This sketch reads tilt from the QMI8658C IMU and smoothly moves a dot 
  on the 8×8 RGB LED matrix based on board orientation.

  ▶️ Video Tutorial:
  https://youtu.be/JKLuYrRcLMI

  📚⬇️ Resources & Code Page:
  https://robojax.com/RJT833

  QMI8658_RGB_2
*/
#include <Arduino.h>
#include <math.h>

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#include <QMI8658.h>   // by Lahav Gahali

// -------- LED MATRIX SETUP --------
#define MATRIX_PIN    14
#define MATRIX_WIDTH  8
#define MATRIX_HEIGHT 8

Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(
  MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_PIN,
  NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE,
  NEO_RGB + NEO_KHZ800
);

// -------- QMI8658 IMU SETUP --------
QMI8658 imu;
QMI8658_Data imuData;

// -------- USER SETTINGS --------

// true  -> arrow points to opposite side
//         USB↔OUSB, 34↔15
// false -> arrow points to the same side that is UP
bool useOppositeMapping = false;

// Arrow color (0–255 each)
uint8_t dotRed   = 0;
uint8_t dotGreen = 150;
uint8_t dotBlue  = 0;

// Board sides
enum Side {
  SIDE_CENTER = 0,
  SIDE_USB,
  SIDE_OUSB,
  SIDE_15,
  SIDE_34
};

// Direction for arrow drawing
enum ArrowDir {
  ARROW_CENTER,
  ARROW_UP,
  ARROW_DOWN,
  ARROW_LEFT,
  ARROW_RIGHT
};

bool isFlat = false;

const char* sideName(Side s) {
  switch (s) {
    case SIDE_CENTER: return "CENTER";
    case SIDE_USB:    return "USB";
    case SIDE_OUSB:   return "OUSB";
    case SIDE_15:     return "15";
    case SIDE_34:     return "34";
    default:          return "?";
  }
}

// -------- ARROW DRAWING (YOUR CODE, UNCHANGED) --------

// Draw a simple arrow on 8x8 matrix pointing in the given direction
void drawArrow(ArrowDir dir, uint16_t color) {
  matrix.fillScreen(0);

  switch (dir) {
    case ARROW_UP:
      // Tip
      matrix.drawPixel(3, 0, color);
      matrix.drawPixel(4, 0, color);
      // Second row
      matrix.drawPixel(2, 1, color);
      matrix.drawPixel(3, 1, color);
      matrix.drawPixel(4, 1, color);
      matrix.drawPixel(5, 1, color);
      // Shaft
      matrix.drawLine(3, 2, 3, 6, color);
      matrix.drawLine(4, 2, 4, 6, color);
      break;

    case ARROW_DOWN:
      // Tip
      matrix.drawPixel(3, 7, color);
      matrix.drawPixel(4, 7, color);
      // Row above tip
      matrix.drawPixel(2, 6, color);
      matrix.drawPixel(3, 6, color);
      matrix.drawPixel(4, 6, color);
      matrix.drawPixel(5, 6, color);
      // Shaft
      matrix.drawLine(3, 1, 3, 5, color);
      matrix.drawLine(4, 1, 4, 5, color);
      break;

    case ARROW_LEFT:
      // Tip
      matrix.drawPixel(0, 3, color);
      matrix.drawPixel(0, 4, color);
      // Column after tip
      matrix.drawPixel(1, 2, color);
      matrix.drawPixel(1, 3, color);
      matrix.drawPixel(1, 4, color);
      matrix.drawPixel(1, 5, color);
      // Shaft
      matrix.drawLine(2, 3, 6, 3, color);
      matrix.drawLine(2, 4, 6, 4, color);
      break;

    case ARROW_RIGHT:
      // Tip
      matrix.drawPixel(7, 3, color);
      matrix.drawPixel(7, 4, color);
      // Column before tip
      matrix.drawPixel(6, 2, color);
      matrix.drawPixel(6, 3, color);
      matrix.drawPixel(6, 4, color);
      matrix.drawPixel(6, 5, color);
      // Shaft
      matrix.drawLine(1, 3, 5, 3, color);
      matrix.drawLine(1, 4, 5, 4, color);
      break;

    case ARROW_CENTER:
    default:
      // Simple plus in the center
      matrix.drawLine(3, 3, 4, 3, color);
      matrix.drawLine(3, 4, 4, 4, color);
      matrix.drawLine(3, 3, 3, 4, color);
      matrix.drawLine(4, 3, 4, 4, color);
      break;
  }

  matrix.show();
}

// -------- IMU → SIDE DETECTION --------
// We calibrated earlier:
//  +X = USB,   -X = OUSB
//  +Y = 15,    -Y = 34    (after your correction)

Side detectSideUp(float ax_g, float ay_g, float az_g) {
  // Flat detection
  const float flatThreshXY = 0.15f;
  const float flatThreshZ  = 0.15f;

  if (fabs(ax_g) < flatThreshXY &&
      fabs(ay_g) < flatThreshXY &&
      fabs(az_g - 1.0f) < flatThreshZ) {
    isFlat = true;
    return SIDE_CENTER;
  }
  isFlat = false;

  // Thresholds to say "this axis is really tilted"
  const float tiltThreshY = 0.5f;
  const float tiltThreshX = 0.5f;

  // Prefer Y axis for 15 / 34
  if (fabs(ay_g) >= tiltThreshY) {
    if (ay_g > 0) {
      return SIDE_34;   // +Y = 34 up
    } else {
      return SIDE_15;   // -Y = 15 up
    }
  }

  // Otherwise, use X axis for USB / OUSB
  if (fabs(ax_g) >= tiltThreshX) {
    if (ax_g > 0) {
      return SIDE_USB;   // +X = USB up
    } else {
      return SIDE_OUSB;  // -X = OUSB up
    }
  }

  // Not clearly tilted → treat as center
  return SIDE_CENTER;
}

// Map from UP side to where the arrow should point
Side arrowSideFromUpSide(Side upSide) {
  if (!useOppositeMapping) {
    // Arrow shows the side that is UP
    return upSide;
  }

  // Arrow shows the opposite side
  switch (upSide) {
    case SIDE_USB:   return SIDE_OUSB;
    case SIDE_OUSB:  return SIDE_USB;
    case SIDE_15:    return SIDE_34;
    case SIDE_34:    return SIDE_15;
    case SIDE_CENTER:
    default:         return SIDE_CENTER;
  }
}

// Convert SIDE to ArrowDir
ArrowDir arrowDirFromSide(Side s) {
  switch (s) {
    case SIDE_USB:    return ARROW_UP;
    case SIDE_OUSB:   return ARROW_DOWN;
    case SIDE_15:     return ARROW_LEFT;
    case SIDE_34:     return ARROW_RIGHT;
    case SIDE_CENTER:
    default:          return ARROW_CENTER;
  }
}

// ---------------- SETUP & LOOP ----------------

void setup() {
  Serial.begin(115200);
  delay(500);

  matrix.begin();
  matrix.setBrightness(20);
  matrix.fillScreen(0);
  matrix.show();

  // IMU: SDA=11, SCL=12 on ESP32-S3-Matrix
  if (!imu.begin(11, 12)) {
    Serial.println("Failed to initialize QMI8658!");
    while (1) { delay(1000); }
  }

  imu.setAccelUnit_mg(true);
  imu.setGyroUnit_dps(true);
  imu.setDisplayPrecision(4);

  Serial.print("QMI8658 initialized. useOppositeMapping = ");
  Serial.println(useOppositeMapping ? "TRUE" : "FALSE");
}

void loop() {
  if (!imu.readSensorData(imuData)) {
    return;
  }

  float ax_g = imuData.accelX / 1000.0f;
  float ay_g = imuData.accelY / 1000.0f;
  float az_g = imuData.accelZ / 1000.0f;

  Side upSide     = detectSideUp(ax_g, ay_g, az_g);
  Side arrowSide  = arrowSideFromUpSide(upSide);
  ArrowDir dir    = arrowDirFromSide(arrowSide);

  uint16_t color = matrix.Color(dotRed, dotGreen, dotBlue);
  drawArrow(dir, color);

  // Debug
  Serial.print("AX="); Serial.print(ax_g, 3);
  Serial.print(" AY="); Serial.print(ay_g, 3);
  Serial.print(" AZ="); Serial.print(az_g, 3);
  Serial.print(" | UP=");    Serial.print(sideName(upSide));
  Serial.print(" | ARROW="); Serial.println(sideName(arrowSide));

  delay(80);
}

هغه شیان چې تاسو ورته اړتیا لرئ

سرچینې او حوالې

فایلونه📁

Fritzing فایل