Кодты іздеу

ESP32-S3 RGB LED матрица жобасы 5 - Көрсеткі әрқашан жоғары

ESP32-S3 RGB LED матрица жобасы 5 - Көрсеткі әрқашан жоғары

5-жоба – Көрсеткі әрқашан жоғары (QMI8658C көмегімен бағдар индикаторы)

5-жоба ESP32-S3 RGB LED матрицасының бағытын анықтау үшін QMI8658C қозғалыс сенсорын пайдаланады және ауырлық күшіне қатысты әрқашан ЖОҒАРЫНЫ көрсететін көрсеткіні көрсетеді. Тақтаны қалай бұрсаңыз да—USB жағы жоғары, OUSB жағы жоғары, “15” жағы немесе “34” жағы—көрсеткі автоматты түрде бұрылып, физикалық жоғары бағытты көрсетеді.

Бұл бортындағы акселерометрді қолданатын нақты уақыттағы бағдарды анықтаудың күшті демонстрациясы. Бұл модульге арналған барлық алты жоба бір YouTube бейнесінде көрсетілген, ол осы бетке де ендірілген. 5-жобаның толық коды мақаланың астында автоматты түрде жүктеледі, ал серіктестік сілтемелер код бөлімінің астында пайда болады.

ESP32-S3 RGB LED матрица модуліне шолу

ESP32-S3 RGB LED матрица модулі осы жобаны мүмкін ететін бірнеше компоненттерді қамтиды:

  • ESP32-S3 микроконтроллері — Wi-Fi, BLE қамтамасыз етеді және LED/IMU логикасын орындайды.
  • 8×8 RGB LED матрицасы — көрсеткіні төрт бағыттың кез келгенінде көрсетеді.
  • QMI8658C акселерометрі — қисаюды, қозғалысты және бағдарды анықтайды.:contentReference[oaicite:0]{index=0}
  • USB-C порты Arduino IDE-де қуаттандыру және бағдарламалау үшін.
  • Reset және Boot түймелері эскиздерді жүктеу үшін.
  • GPIO түйреуіштері қосымша жобалар үшін тақтаның айналасында қолжетімді.

Көрсеткі бағыты толығымен акселерометр көрсеткіштерімен анықталады. Тақта бұрылғанда, QMI8658C жаңа X/Y/Z мәндерін сезеді, ал эскиз қандай көрсеткі үлгісін (↑, ↓, ←, →) салу керектігін таңдайды.

Бейнеде қамтылған жобалар (уақыт белгілері)

  • 00:00 – Кіріспе
  • 02:01 – ESP32 тақталарын орнату
  • 03:32 – Кітапханаларды орнату
  • 05:32 – 1-жоба: Қозғалатын нүкте
  • 11:11 – 2-жоба: Мәтінді айналдыру
  • 12:59 – 3-жоба: HTTP мәтіні
  • 16:41 – 4-жоба: Қисаю нүктесі
  • 18:555-жоба: Көрсеткі әрқашан жоғары (осы жоба)
  • 20:02 – 6-жоба: Нысана ойыны

Бейне модульдің қалай бұрылғанына байланысты көрсеткінің бағытының қалай лезде өзгеретінін анық көрсетеді. Осы сегментті көру өте ұсынылады.:contentReference[oaicite:1]{index=1}

Arduino IDE-де ESP32 тақталарын орнату

Егер сіз бұрынғы жобалардың бірін аяқтаған болсаңыз, тақтаны орнату дайын. Әйтпесе:

  1. File > Preferences → ESP32 тақтасының URL мекенжайын қосыңыз
  2. Tools > Board > Boards Manager… → “ESP32” орнатыңыз
  3. Tools > Board бөлімінде ESP32-S3 тақтасын таңдаңыз
  4. Tools > Port бөлімінде дұрыс USB COM портын таңдаңыз

Қажетті кітапханаларды орнату

5-жоба келесілерді пайдаланады:

  • Adafruit NeoMatrix
  • Adafruit NeoPixel
  • Adafruit GFX
  • QMI8658 (қозғалыс сенсоры)
  1. Sketch > Include Library > Manage Libraries…
  2. Іздеу: NeoMatrix → Орнату
  3. Тәуелділіктерді орнату: NeoPixel + GFX
  4. QMI8658 кітапханасын авторы бойынша іздеп, орнатыңыз

5-жоба қалай жұмыс істейді

QMI8658C X, Y және Z осьтеріндегі ауырлық күшін өлшейді. Осы мәндерді салыстыра отырып, эскиз тақтаның қай физикалық жағы жоғары қарағанын анықтайды:

  • USB жағы жоғары
  • OUSB жағы жоғары (USB-ге қарама-қарсы)
  • “15” жағы жоғары
  • “34” жағы жоғары

Әр бағдар 8×8 матрицадағы әртүрлі көрсеткі үлгісіне сәйкес келеді. Карталау бұрынғы жөндеу сеанстарындағы расталған бағдар логикасына сәйкес келеді. Тақтаның айналуы үздіксіз оқылады және жоғары жағы өзгерген кезде көрсеткі бірден жаңартылады.

5-жоба – Код параметрлері (Көрсеткі әрқашан жоғары)

Төменде конфигурация аймағындағы пайдаланушы реттей алатын мәндер берілген. Толық жоба коды мақаланың астында автоматты түрде пайда болады.

Матрица конфигурациясы


// Матрица конфигурациясы
const int MATRIX_PIN    = 14;   // осы модуль үшін тұрақты
const int MATRIX_WIDTH  = 8;
const int MATRIX_HEIGHT = 8;

// Ұсынылатын бағдар: Жоғарғы-сол жақ бастапқы нүкте, прогрессивті режим
// (нақты конструктор төменде жүктелген кодтың ішінде)

Бұл жоба көрсеткінің нақты қозғалысқа негізделген дұрыс бағытталуын қамтамасыз ету үшін NEO_MATRIX_PROGRESSIVE орналасуын пайдаланады.

Жарықтық


uint8_t matrixBrightness = 40;   // 0–255

Жарық орталар үшін бұл мәнді арттыруға болады. Үй ішінде пайдалану үшін 30–60 қолайлы.

Көрсеткі түсі


// Көрсеткі түсі
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;   // көрсеткі тым оңай өзгерсе реттеңіз
  • Егер көрсеткі тым оңай ауысып кетсе → арттырыңыз шекті мәнді.
  • Егер көрсеткі өзгеруге тым баяу болса → азайтыңыз шекті мәнді.

Көрсеткі үлгілері

Эскизде келесі көрсеткі битмап үлгілері қамтылған:

  • ↑ жоғары
  • ↓ төмен
  • ← солға
  • → оңға

Бұларды өзгертудің қажеті жоқ, бірақ басқа стиль қаласаңыз, код ішіндегі пішіндерді өзгерте аласыз.

Қорытынды

5-жоба ESP32-S3 RGB LED матрицасы мен QMI8658C акселерометрінің бірге жұмыс істеп, бағдарды анықтап, әрқашан жоғарыны көрсететін көрсеткіні қалай шығаратынын көрсетеді. Бұл жоба Tilt Dot (4-жоба) негізінде құрылған және сізді 6-жобадағы қорытынды интерактивті ойынға дайындайды.

Толық “Arrow Always Up” эскизі осы мақаланың астында қолжетімді (автоматты түрде жүктеледі). Видеоның сәйкес бөлігін көру өте ұсынылады, себебі көрсеткінің тақтаның айналуына қаншалықты жылдам жауап беретінін көресіз. Егер бұл жобаны үйде жасағыңыз келсе, ESP32-S3 RGB LED матрица модуліне арналған серіктестік сілтемелер код бөлімінің астында орналасқан.

Суреттер

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 файлы