Mata Robot 72x7 Animasi — ESP32 simulation

Matriks NeoPixel 72x7 menampilkan sepasang mata robot merah dengan animasi buka, melirik, kedip, dan strobo.

An interactive ESP32 circuit simulation you can run free in your browser on Velxio, by rsetyo-widayanto.

Components

Sketch code

#include <FastLED.h>

#define DATA_PIN       21
#define BUTTON_PIN     5
#define MATRIX_WIDTH   72
#define MATRIX_HEIGHT  7
#define NUM_LEDS       (MATRIX_WIDTH * MATRIX_HEIGHT)
#define BRIGHTNESS     120
#define POWER_LIMIT_MA 18000
#define SERPENTINE     false

CRGB leds[NUM_LEDS];
unsigned long animasiMulai = 0;
unsigned long debounceMulai = 0;
bool tombolLama = HIGH;
uint8_t modeAnimasi = 0;          // 0 = siklus 16 detik, 1 = loading bar
const uint8_t JUMLAH_MODE = 2;

uint16_t XY(uint8_t x, uint8_t y) {
  if (x >= MATRIX_WIDTH || y >= MATRIX_HEIGHT) return 0;
  return (SERPENTINE && (y & 1))
    ? (y * MATRIX_WIDTH + (MATRIX_WIDTH - 1 - x))
    : (y * MATRIX_WIDTH + x);
}

void pixel(int x, int y, const CRGB &warna) {
  if (x >= 0 && x < MATRIX_WIDTH && y >= 0 && y < MATRIX_HEIGHT)
    leds[XY(x, y)] = warna;
}

const char mataKiri[7][31] = {
  "RR............................",
  ".RRRRRRRRR....................",
  "..RWWWWWWRRRRRR...............",
  "...RWWWWWWWWWWWRRRRRR.........",
  "....RRWWWWWWWWWWWWWWRRRR......",
  "......RRRWWWWWWWWWWWWWWRR.....",
  ".........RRRRRRRRRRRRRRRRRR..."
};

void gambarSatuMata(bool kanan, int pupil, int buka, bool aktif) {
  const int awalX = kanan ? 40 : 2;
  const int pusatPupil = 13 + pupil;

  for (int y = 0; y < 7; y++) {
    for (int x = 0; x < 30; x++) {
      int sumberX = kanan ? 29 - x : x;
      char bentuk = mataKiri[y][sumberX];
      int xx = awalX + x;

      if (!aktif || abs(y - 3) * 100 > buka * 4) {
        pixel(xx, y, CRGB::Black);
        continue;
      }

      CRGB warna = CRGB::Black;
      if (bentuk == 'R') warna = CRGB(255, 0, 12);
      if (bentuk == 'W') warna = CRGB(210, 210, 210);

      int px = kanan ? (29 - pusatPupil) : pusatPupil;
      int dx = x - px;
      int dy = y - 4;
      if (bentuk == 'W' && dx * dx + dy * dy <= 7)
        warna = CRGB(255, 0, 12);
      if (bentuk == 'W' && abs(dx) <= 1 && abs(dy) <= 1)
        warna = CRGB::Black;

      pixel(xx, y, warna);
    }
  }
}

void gambarMata(int pupil, int buka, bool kiriAktif, bool kananAktif) {
  fill_solid(leds, NUM_LEDS, CRGB::Black);
  gambarSatuMata(false, pupil, buka, kiriAktif);
  gambarSatuMata(true,  pupil, buka, kananAktif);
}

// ---------- ANIMASI 1: siklus mata (kode asli) ----------
void jalankanAnimasiMata(unsigned long waktu) {
  unsigned long t = waktu % 16000UL;
  int pupil = 0;
  int buka = 100;
  bool kiri = true;
  bool kanan = true;

  if (t < 900) {
    buka = map(t, 0, 900, 0, 100);
  } else if (t < 2600) {
    pupil = map(t, 900, 2600, 0, -4);
  } else if (t < 4300) {
    pupil = map(t, 2600, 4300, -4, 4);
  } else if (t < 5200) {
    pupil = map(t, 4300, 5200, 4, 0);
  } else if (t < 5700) {
    unsigned long b = t - 5200;
    buka = b < 180 ? map(b, 0, 180, 100, 0)
                   : map(b, 180, 500, 0, 100);
  } else if (t < 7900) {
    uint8_t fase = ((t - 5700) / 95) % 8;
    kiri = fase < 3;
    kanan = fase >= 4 && fase < 7;
    buka = (fase == 3 || fase == 7) ? 0 : 100;
  } 

More projects by rsetyo-widayanto