Help! esp32 LED matrix double point problem

Hello. I desperately need help.

I want to control a huidu D16 LED Matrix 32x32 with ESP32.

I created a code using GPT.
It lights a dot from 0,0 to 31,31 and then turns it off. I thought I could map the matrix by referencing the dot's continuous movement.

The problem lies here.
Both dots move simultaneously.
I've attached a video. (There was a mistake while filming, so it's rotated 90 degrees clockwise. Please note.)

Of course, I also purchased a controller from huidu, and that controller clearly displays the characters on the LEDs.
The LED Matrix itself isn't left-right.

I've been struggling with GPT for a week, but I can't seem to find an answer.

I need your advice.

#include <Arduino.h>
#include "soc/gpio_struct.h"
#include "soc/gpio_reg.h"

// ===== HUB75 핀맵 =====
#define PIN_R1   25
#define PIN_G1   26
#define PIN_B1   27
#define PIN_R2   14
#define PIN_G2   12
#define PIN_B2   13

#define PIN_A    18
#define PIN_B    5
#define PIN_C    19
#define PIN_D    16
#define PIN_CLK  4
#define PIN_LAT  22
#define PIN_OE   21

#define MATRIX_WIDTH  32
#define MATRIX_HEIGHT 32

// ===== GPIO 펄스 제어 =====
inline void clk_pulse() {
  GPIO.out_w1ts = (1UL << PIN_CLK);
  GPIO.out_w1tc = (1UL << PIN_CLK);
}
inline void lat_pulse() {
  GPIO.out_w1ts = (1UL << PIN_LAT);
  delayMicroseconds(1);
  GPIO.out_w1tc = (1UL << PIN_LAT);
}
inline void oe_on()  { GPIO.out_w1tc = (1UL << PIN_OE); }
inline void oe_off() { GPIO.out_w1ts = (1UL << PIN_OE); }

// ===== 행 주소 출력 =====
inline void set_row(uint8_t row) {
  if (row & 0x01) GPIO.out_w1ts = (1UL << PIN_A); else GPIO.out_w1tc = (1UL << PIN_A);
  if (row & 0x02) GPIO.out_w1ts = (1UL << PIN_B); else GPIO.out_w1tc = (1UL << PIN_B);
  if (row & 0x04) GPIO.out_w1ts = (1UL << PIN_C); else GPIO.out_w1tc = (1UL << PIN_C);
  if (row & 0x08) GPIO.out_w1ts = (1UL << PIN_D); else GPIO.out_w1tc = (1UL << PIN_D);
}

// ===== 전역 버퍼 (0=off, 1=on) =====
uint8_t framebuffer[MATRIX_HEIGHT][MATRIX_WIDTH] = {0};

// ===== 픽셀 설정 =====
void setPixel(uint8_t x, uint8_t y, bool on) {
  if (x >= MATRIX_WIDTH || y >= MATRIX_HEIGHT) return;
  framebuffer[y][x] = on ? 1 : 0;
}

void clearShiftRegister() {
  // 모든 데이터 라인 0으로 세팅
  GPIO.out_w1tc = (1UL << PIN_R1);
  GPIO.out_w1tc = (1UL << PIN_G1);
  GPIO.out_w1tc = (1UL << PIN_B1);
  GPIO.out_w1tc = (1UL << PIN_R2);
  GPIO.out_w1tc = (1UL << PIN_G2);
  GPIO.out_w1tc = (1UL << PIN_B2);

  for (int i=0; i<32; i++){
    set_row(i);
    for(int j=0; i<16; i++){
      clk_pulse();
    }
    lat_pulse();
    oe_on();
    delayMicroseconds(50);
    oe_off();
  }
}

// ===== 한 줄 그리기 =====
void drawRow(uint8_t row) {
  for (int col = 0; col < MATRIX_WIDTH; col++) {
    bool r1=false, g1=false, b1=false;
    bool r2=false, g2=false, b2=false;

    int y1 = row;
    int y2 = row + 16;

    if (y1 < 32 && framebuffer[y1][col]) { r1=g1=b1=true; }
    if (y2 < 32 && framebuffer[y2][col]) { r2=g2=b2=true; }

    if(r1) GPIO.out_w1ts = (1UL << PIN_R1); else GPIO.out_w1tc = (1UL << PIN_R1);
    if(g1) GPIO.out_w1ts = (1UL << PIN_G1); else GPIO.out_w1tc = (1UL << PIN_G1);
    if(b1) GPIO.out_w1ts = (1UL << PIN_B1); else GPIO.out_w1tc = (1UL << PIN_B1);

    if(r2) GPIO.out_w1ts = (1UL << PIN_R2); else GPIO.out_w1tc = (1UL << PIN_R2);
    if(g2) GPIO.out_w1ts = (1UL << PIN_G2); else GPIO.out_w1tc = (1UL << PIN_G2);
    if(b2) GPIO.out_w1ts = (1UL << PIN_B2); else GPIO.out_w1tc = (1UL << PIN_B2);

    clk_pulse();
  }
  
  lat_pulse();
  set_row(row);

  oe_on();
  delayMicroseconds(50);
  oe_off();
}

// ===== 전체 프레임 그리기 =====
void drawFrame() {
  for (int row = 0; row < 16; row++) {
    drawRow(row);
  }
}

// ===== 초기화 =====
void setup() {
  pinMode(PIN_R1, OUTPUT); pinMode(PIN_G1, OUTPUT); pinMode(PIN_B1, OUTPUT);
  pinMode(PIN_R2, OUTPUT); pinMode(PIN_G2, OUTPUT); pinMode(PIN_B2, OUTPUT);
  pinMode(PIN_A, OUTPUT); pinMode(PIN_B, OUTPUT); pinMode(PIN_C, OUTPUT); pinMode(PIN_D, OUTPUT);
  pinMode(PIN_CLK, OUTPUT); pinMode(PIN_LAT, OUTPUT); pinMode(PIN_OE, OUTPUT);

  GPIO.out_w1ts = (1UL << PIN_OE);
   
  Serial.begin(115200);

  Serial.println("=== Mapping Test Start ===");
}

// ===== 메인 루프 =====
void loop() {
  static int x = 0, y = 0;
  static unsigned long lastChange = 0;

  // 현재 픽셀만 ON
  memset(framebuffer, 0, sizeof(framebuffer));
  setPixel(x, y, true);

  // 계속 화면 refresh
  drawFrame();

  // 2초마다 다음 좌표로 이동
  if (millis() - lastChange > 37) {
    lastChange = millis();
    x++;
    if (x >= MATRIX_WIDTH) {
      x = 0;
      y++;
      if (y >= MATRIX_HEIGHT) y = 0;
    }
    Serial.printf("Now lighting (%d, %d)\n", x, y);
  }
}

Same for y.

Maybe this; you're reading outside the boundaries of the matrix
The index for your matrix in the X directions runs from 0..31, not from 0..32; same for the in the Y direction.

If you are asking my advice - use a library:

If you want to fix your code, it is not so simple. There are a lot of different types of hub75 panels that looking very similar, but works by different way.
Could you please show a clear picture of the matrix rear side?


IC chips

FM6124 Several
TC7258HN Several
RUC7258D one
nameless chip one

I used that Library. but don't works

According to the number of the chips, the panel seems to has 1/8 scan factor, and your code is for 1/16 scan matrix.

You have a much better chance of success with a library than with this code.
Have you tried reporting your issues on the library's GitHub?