diff --git a/platformio.ini b/platformio.ini index 67728ab..dac9771 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,4 +13,12 @@ platform = espressif32 board = nodemcu-32s board_build.mcu = esp32 framework = arduino -monitor_speed = 115200 +monitor_speed = 230400 +lib_deps = + mrfaptastic/ESP32 HUB75 LED MATRIX PANEL DMA Display@^3.0.12 + https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA.git + adafruit/Adafruit GFX Library@^1.11.10 + fastled/FastLED@^3.7.1 + mbed-seeed/BluetoothSerial@0.0.0+sha.f56002898ee8 + me-no-dev/AsyncTCP@^1.1.1 + bblanchon/ArduinoJson@^7.1.0 diff --git a/src/main.cpp b/src/main.cpp index 795bd2e..a6be575 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,51 +1,434 @@ #include +#include +#include +// #include +// #include +#pragma region Matrix Config +#define R1_PIN 25 +#define G1_PIN 26 +#define B1_PIN 27 +#define R2_PIN 14 +#define G2_PIN 12 +#define B2_PIN 13 +#define A_PIN 23 +#define B_PIN 22 // Changed from library default +#define C_PIN 5 +#define D_PIN 17 +#define E_PIN 32 // required for 1/32 scan panels, like 64x64px. Any available pin would do, i.e. IO32 +#define LAT_PIN 4 +#define OE_PIN 15 +#define CLK_PIN 16 +// Configure for your panel(s) as appropriate! +#define PANEL_WIDTH 64 +#define PANEL_HEIGHT 64 +#define PANELS_NUMBER 4 -const int bufferSize = 1024; // Kích thước bộ đệm tùy chỉnh +#define PANE_WIDTH PANEL_WIDTH *PANELS_NUMBER +#define PANE_HEIGHT PANEL_HEIGHT +#define NUM_PIXELS PANE_WIDTH *PANE_HEIGHT +MatrixPanel_I2S_DMA *dma_display = nullptr; +// Another way of creating config structure +// Custom pin mapping for all pins +HUB75_I2S_CFG::i2s_pins _pins = {R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, LAT_PIN, OE_PIN, CLK_PIN}; +HUB75_I2S_CFG mxconfig( + PANEL_WIDTH, // width + PANEL_HEIGHT, // height + PANELS_NUMBER, // chain length + _pins, // pin mapping + HUB75_I2S_CFG::FM6126A // driver chip +); +#pragma endregion +const int bufferSize = 8192; // Kích thước bộ đệm tùy chỉnh uint8_t buffer[bufferSize]; int bufferIndex = 0; int numRows = 0; int numCols = 0; +const int DATA_SIZE = 8192; // Số lượng phần tử trong mảng data +uint16_t data[DATA_SIZE]; // Mảng để lưu trữ dữ liệu RGB565 const int floatSize = sizeof(float); -void setup() { - Serial.begin(115200); // Đảm bảo baud rate khớp với baud rate của Python +static int x_moi = 0; +static int y_moi = 0; +int num_moi = 0; +bool reached = false; +bool gen_moi = false; +const char *htmlPage = R"=====( + + + + + + Led Strip Controller + + + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + + + + + +
+
+ + + + +)====="; + +uint16_t rgbToUint16(uint8_t r, uint8_t g, uint8_t b, bool mode) +{ + if (mode) + { + uint16_t red = (r >> 3) & 0x1F; // Chuyển từ 8 bit xuống 5 bit + uint16_t green = (g >> 2) & 0x3F; // Chuyển từ 8 bit xuống 6 bit + uint16_t blue = (b >> 3) & 0x1F; // Chuyển từ 8 bit xuống 5 bit + + return (red << 11) | (green << 5) | blue; + } + else + { + uint16_t red = (r >> 3) & 0x1F; // Chuyển từ 8 bit xuống 5 bit + uint16_t green = (b >> 2) & 0x3F; // Chuyển từ 8 bit xuống 6 bit + uint16_t blue = (g >> 3) & 0x1F; // Chuyển từ 8 bit xuống 5 bit + + return (red << 11) | (green << 5) | blue; + } +} +void draw_true_color(int x, int y, int r, int g, int b) +{ + if (y <= 31) + { + dma_display->drawPixelRGB888(x, y, r, g, b); + } + else + { + dma_display->drawPixelRGB888(x, y, r, b, g); + } +} +// Hàm kiểm tra xem điểm (x, y) có đủ xa điểm (x_ref, y_ref) không +bool isFarEnough(int x, int x_ref, int min_distance) +{ + int dx = x - x_ref; + return (dx * dx) >= (min_distance * min_distance); } -void loop() { - while (Serial.available() > 0) { +// Hàm tạo điểm ngẫu nhiên không gần với điểm đã cho +void drawRandomPoint(int x_ref, int y_ref, int min_distance, bool generated) +{ + // int x, y; + bool point_found = false; + if (generated) + { + for (int i = x_moi - 1; i <= x_moi + 1; i++) + { + for (int j = y_moi - 1; j <= y_moi + 1; j++) + { + draw_true_color(i, j, 0, 0, 255); + } + } + } + else + { + while (!point_found) + { + x_moi = random(PANE_WIDTH); + y_moi = y_ref; + // Kiểm tra khoảng cách giữa điểm ngẫu nhiên và điểm đã cho + if (isFarEnough(x_moi, x_ref, min_distance) && x_moi >= 32 && x_moi < 220) + { + point_found = true; + } + } + for (int i = x_moi - 1; i < x_moi + 1; i++) + { + for (int j = y_moi - 1; j < y_moi + 1; j++) + { + draw_true_color(i, j, 0, 0, 255); + } + } + } + + Serial.printf("x moi: %d", x_moi); + Serial.printf("Y moi: %d", y_moi); + Serial.println(); +} +int *drawStickMan(int x, int y) +{ + int range[4]; + // Vẽ đầu + dma_display->drawCircle(x, y, 2, rgbToUint16(255, 0, 0, false)); // Đầu stick man + + // Vẽ thân + dma_display->drawLine(x, y + 3, x, y + 7, rgbToUint16(255, 0, 0, false)); // Thân stick man + + // Vẽ tay + dma_display->drawLine(x - 3, y + 4, x + 3, y + 4, rgbToUint16(255, 0, 0, false)); // Tay trái và tay phải + range[0] = x - 3; + range[1] = x + 3; + // Vẽ chân + dma_display->drawLine(x, y + 7, x - 3, y + 10, rgbToUint16(255, 0, 0, false)); // Chân trái + dma_display->drawLine(x, y + 7, x + 3, y + 10, rgbToUint16(255, 0, 0, false)); // Chân phải + + range[2] = y - 2; + range[3] = y + 10; + + return range; +} +void setup() +{ + Serial.begin(115200 * 2); // Đảm bảo baud rate khớp với baud rate của Python + dma_display = new MatrixPanel_I2S_DMA(mxconfig); + dma_display->begin(); // setup the LED matrix + dma_display->setBrightness8(50); // 0-255 + dma_display->clearScreen(); + // SerialBT.begin("ESP32Test"); + //setup_routing(); +} + +void Display_Point(int x, int y, int r, int g, int b) +{ + for (uint16_t i = 0; i < PANE_WIDTH; i++) + { + for (uint16_t j = 0; j < PANE_HEIGHT; j++) + { + + if (i >= x - 1 && i <= x + 1 && j >= y - 1 && j <= y + 1) + { + if (j <= 32) + { + dma_display->drawPixelRGB888(i, j, r, g, b); + } + else + { + dma_display->drawPixelRGB888(i, j, r, b, g); + } + } + else + dma_display->drawPixelRGB888(i, j, 0, 0, 0); + } + } +} +void printData() +{ + Serial.println("Printing data array..."); + + for (int i = 0; i < DATA_SIZE; i++) + { + // In giá trị RGB565 dưới dạng hex + if (i % 16 == 0) + { // In dòng mới sau mỗi 16 phần tử để dễ đọc + Serial.println(); + } + Serial.print("0x"); + Serial.print(data[i], HEX); + Serial.print(" "); + } + Serial.println(); + Serial.println("Data printing completed."); +} + +void loop() +{ + //server.handleClient(); +#pragma region Serial processing + while (Serial.available() > 0) + { uint8_t byteReceived = Serial.read(); - - if (bufferIndex < bufferSize) { + if (bufferIndex < bufferSize) + { buffer[bufferIndex++] = byteReceived; - } else { + } + else + { // Xử lý tình huống quá tải Serial.println("Buffer overflow"); bufferIndex = 0; // Reset buffer index in case of overflow } } - if (bufferIndex >= 2 * sizeof(int)) { + if (bufferIndex >= 2 * sizeof(int)) + { // Đã nhận đủ kích thước dữ liệu memcpy(&numRows, buffer, sizeof(int)); memcpy(&numCols, buffer + sizeof(int), sizeof(int)); int expectedSize = numRows * numCols * floatSize; - if (bufferIndex >= (2 * sizeof(int) + expectedSize)) { - Serial.println("Data received:"); + if (bufferIndex >= (2 * sizeof(int) + expectedSize)) + { + dma_display->clearScreen(); float data[numRows][numCols]; - for (int row = 0; row < numRows; ++row) { - for (int col = 0; col < numCols; ++col) { + for (int row = 0; row < numRows; ++row) + { + for (int col = 0; col < numCols; ++col) + { int index = (2 * sizeof(int)) + (row * numCols + col) * floatSize; float value; memcpy(&value, &buffer[index], floatSize); data[row][col] = value; - Serial.print(value, 4); // In với 4 chữ số thập phân - Serial.print(" "); } - Serial.println(); + int x = int(data[row][0]); + int y = int(data[row][1]); + + // measure x dimension + int min_x = x - 1 - ((num_moi * 3) / 3); + int max_x = x + 1 + ((num_moi * 3) / 3); + int min_y = y - 1; + int max_y = y + 1; + + int *_range; + _range = drawStickMan(x, y); + + + // for (int i = min_x; i <= max_x; i++) + // { + // for (int j = y - 1; j <= y + 1; j++) + // { + + // if (j <= 32) + // dma_display->drawPixelRGB888(i, j, 214, 24, 192); + // else + // dma_display->drawPixelRGB888(i, j, 214, 192, 24); + // // reach moi + // if (gen_moi == false) + // { + // drawRandomPoint(x, y, 5 + (num_moi * 3), false); + // gen_moi = true; + // } + // if (min_x <= x_moi + 1 && max_x > x_moi - 1 && min_y <= y_moi + 1 && max_y >= y_moi - 1) + // { + // reached = true; + // num_moi += 1; + // gen_moi = false; + // } + // } + // } + // if (reached) + // { + // min_x = x - 1 - ((num_moi * 3) / 3); + // max_x = x + 1 + ((num_moi * 3) / 3); + // for (int i = min_x; i <= max_x; i++) + // { + // for (int j = y - 1; j <= y + 1; j++) + // { + // if (j <= 32) + // dma_display->drawPixelRGB888(i, j, 214, 24, 192); + // else + // dma_display->drawPixelRGB888(i, j, 214, 192, 24); + // } + // } + // reached = false; + // } + + // if (gen_moi) + // { + // drawRandomPoint(x, y, 5 + (num_moi * 3), gen_moi); + // } } - // Reset chỉ số chỉ mục sau khi xử lý bufferIndex = 0; + // Serial.printf("%d - %d",int(data[0][0]),int(data[0][1])); + // Display_Point(int(data[0][0]),int(data[0][1]),214,24,192); + // Display_Point(data,numRows,numCols,214,24,192); } } +#pragma endregion + + // readDataFromSerial(); }