Kostka telebimowa

Typ_projektu
Arduino
Zdjecie główne
Krótki opis projektu

Sześcian obracający się, przesuwający po panelach i odbijający się od krawędzi telebimu

Niezbędne elementy

1. Płytka ESP32 Dev Board

2. Dowolna ilość matryc HUB75 (tutaj 3x rozdzielczość 64x32)

3. Płytka zasilająca

Sprzęt

Komputer PC z zainstalowanym Arduino IDE

Opis projektu

Kostka telebimowa to niesamowite doświadczenie ezoteryczno-imersyjne, które ukoi nawet najbardziej strudzonego studenta. Projekt składa się z 3 paneli HUB75 o rozdzielczości 64x32 Całość tworzy wyświetlacz o rozdzielczości 192x32. Projekt wyświetla przyjemną dla oka kostkę, która obraca się i odbija od krawędzi ekranu. Aby ułatwić obserwację kostki krawędzie wyświetlane są w 3 podstawowych kolorach.  

Zdjęcia
kod programu
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#include <Adafruit_GFX.h>
// ───── Pin eşlemesi ────────────────────────────────────────────── 
#define P_LAT  4
#define P_OE   2
#define P_A   13
#define P_B   21
#define P_C   17
#define P_D   12
#define P_E   -1
#define P_CLK 16
#define P_R1  26
#define P_G1  18
#define P_B1  19
#define P_R2  23
#define P_G2  14
#define P_B2  5
// ───── Panel konfigürasyonu ────────────────────────────────────── 
#define PANEL_WIDTH   64
#define PANEL_HEIGHT  32
#define PANELS_X       3
#define MATRIX_WIDTH  (PANEL_WIDTH * PANELS_X)
#define MATRIX_HEIGHT PANEL_HEIGHT
// ───── Global değişkenler ────────────────────────────────────────
MatrixPanel_I2S_DMA dma_display;

float cube[8][3] = {
  {-1, -1, -1}, {1, -1, -1},
  {1, 1, -1},   {-1, 1, -1},
  {-1, -1, 1},  {1, -1, 1},
  {1, 1, 1},    {-1, 1, 1}
};

float angleX = 0, angleY = 0, angleZ = 0;
float scale = 5.5;
float projected[8][2];

float rotVelX = 0.02;
float rotVelY = 0.03;
float rotVelZ = 0.025;
float posX = MATRIX_WIDTH / 2;
float posY = MATRIX_HEIGHT / 2;
float velX = 0.3;
float velX2 = 0.3;
float velY = 0.3;
float velY2 = 0.3;
// ───── Kurulum ─────────────────────────────────────────────────── 
void setup() {
  HUB75_I2S_CFG cfg(PANEL_WIDTH, PANEL_HEIGHT, PANELS_X, );
  cfg.gpio.r1 = P_R1; cfg.gpio.g1 = P_G1; cfg.gpio.b1 = P_B1;
  cfg.gpio.r2 = P_R2; cfg.gpio.g2 = P_G2; cfg.gpio.b2 = P_B2;
  cfg.gpio.lat = P_LAT; cfg.gpio.oe = P_OE; cfg.gpio.clk = P_CLK;
  cfg.gpio.a = P_A; cfg.gpio.b = P_B; cfg.gpio.c = P_C; cfg.gpio.d = P_D;
  dma_display.begin(cfg);
  dma_display.setBrightness8(90);
}
// ───── Ana döngü ──────────────────────────────────────────────── 
void loop() {
  dma_display.fillScreen(0); // ekranı temizle 

  float rotated[8][3];
  float maxX = -1000, minX = 1000, maxY = -1000, minY = 1000;
  
  if (maxX >= (MATRIX_WIDTH-1) || minX <= 1) velX = -velX;
  if (maxY >= (MATRIX_HEIGHT-1) || minY <= 1) velY = -velY;

  for (int i = 0; i < 8; i++) {
    float x = cube[i][0];
    float y = cube[i][1];
    float z = cube[i][2];

    // Rotation around X
    float ry = cos(angleX) * y - sin(angleX) * z;
    float rz = sin(angleX) * y + cos(angleX) * z;

    // Rotation around Y
    float rx = cos(angleY) * x + sin(angleY) * rz;
    rz = -sin(angleY) * x + cos(angleY) * rz;

    // Rotation around Z
    float finalX = cos(angleZ) * rx - sin(angleZ) * ry;
    float finalY = sin(angleZ) * rx + cos(angleZ) * ry;

    rotated[i][0] = finalX;
    rotated[i][1] = finalY;
    rotated[i][2] = rz;

    projected[i][0] = finalX * scale + posX;
    projected[i][1] = finalY * scale + posY;

    maxX = max(maxX, projected[i][0]);
    minX = min(minX, projected[i][0]);
    maxY = max(maxY, projected[i][1]);
    minY = min(minY, projected[i][1]);
  }

  // Collision with borders
  if (maxX >= MATRIX_WIDTH) {
  velX2 = -abs(velX);
  rotVelY += abs(velX) * 0.04;
  rotVelZ += random(-2, 2) * 0.01;
}

if (minX <= 0) {
  velX2 = abs(velX);
  rotVelY += abs(velX) * 0.04;
  rotVelZ += random(-2, 2) * 0.01;
}

if (maxY >= MATRIX_HEIGHT) {
  velY2 = -abs(velY);
  rotVelX += abs(velY) * 0.04;
  rotVelZ += random(-2, 2) * 0.01;
}

if (minY <= 0) {
  velY2 = abs(velY);
  rotVelX += abs(velY) * 0.1;
  rotVelZ += random(-5, 5) * 0.01;
}


  for (int i = 0; i < 4; i++) {
    int next = (i + 1) % 4;
    dma_display.drawLine(projected[i][0], projected[i][1], projected[next][0], projected[next][1], dma_display.color565(255, 0, 0));
  }
  for (int i = 4; i < 8; i++) {
    int next = 4 + (i + 1) % 4;
    dma_display.drawLine(projected[i][0], projected[i][1], projected[next][0], projected[next][1], dma_display.color565(0, 255, 0));
  }
  for (int i = 0; i < 4; i++) {
    dma_display.drawLine(projected[i][0], projected[i][1], projected[i + 4][0], projected[i + 4][1], dma_display.color565(0, 0, 255));
  }
//Tłumienie rotacji
  rotVelX *= 0.99;
  rotVelY *= 0.99;
  rotVelZ *= 0.99;

  posX += velX2;
  posY += velY2;
  angleX += rotVelX;
  angleY += rotVelY;
  angleZ += rotVelZ;

  delay(15);
}
Youtube
Tagi
kostka telebim ESP32 ESP ArduinoIDE