128x128
CalisJI 2024-08-13 16:13:25 +07:00
parent 320b7413fe
commit 6528ec2605
2 changed files with 249 additions and 75 deletions

View File

@ -9,7 +9,7 @@
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[env:nodemcu-32s2] [env:nodemcu-32s2]
platform = espressif32 platform = espressif32@6.3.2
board = nodemcu-32s2 board = nodemcu-32s2
board_build.mcu = esp32 board_build.mcu = esp32
framework = arduino framework = arduino
@ -18,3 +18,9 @@ lib_deps =
mrfaptastic/ESP32 HUB75 LED MATRIX PANEL DMA Display@^3.0.12 mrfaptastic/ESP32 HUB75 LED MATRIX PANEL DMA Display@^3.0.12
https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA.git https://github.com/mrcodetastic/ESP32-HUB75-MatrixPanel-DMA.git
adafruit/Adafruit GFX Library@^1.11.10 adafruit/Adafruit GFX Library@^1.11.10
fastled/FastLED@^3.7.1
bblanchon/ArduinoJson@^7.1.0
; build_flags = -DCORE_DEBUG_LEVEL=5
; -DBOARD_HAS_PSRAM
; -mfix-esp32-psram-cache-issue

View File

@ -4,10 +4,26 @@
#include <WiFi.h> #include <WiFi.h>
#include <WebServer.h> #include <WebServer.h>
#include <WiFiUdp.h> #include <WiFiUdp.h>
#include <HTTPClient.h> #include <FastLED.h>
#include <esp_wifi.h>
#include <ArduinoJson.h>
const char* ssid = "VSMI-Guest"; const char* ssid = "VSMI-Guest";
const char* password = "h3ll0vsmi"; const char* password = "h3ll0vsmi";
// const char* ssid = "VIETTEL_txXZQ27z";
// const char* password = "CCF5A3K9";
// Set your Static IP address
IPAddress local_IP(192, 168, 1, 243);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
// IPAddress local_IP(192, 168, 2, 243);
// IPAddress gateway(192, 168, 2, 1);
// IPAddress subnet(255, 255, 255, 0);
// IPAddress primaryDNS(8, 8, 8, 8); //optional
// IPAddress secondaryDNS(8, 8, 4, 4); //optional
#define R1_PIN 25 #define R1_PIN 25
#define G1_PIN 26 #define G1_PIN 26
#define B1_PIN 27 #define B1_PIN 27
@ -27,28 +43,33 @@ const char* password = "h3ll0vsmi";
// Configure for your panel(s) as appropriate! // Configure for your panel(s) as appropriate!
#define PANEL_WIDTH 64 #define PANEL_WIDTH 64
#define PANEL_HEIGHT 64 #define PANEL_HEIGHT 64
#define PANELS_NUMBER 1 #define PANELS_NUMBER 4
#define PANE_WIDTH PANEL_WIDTH * PANELS_NUMBER #define PANE_WIDTH PANEL_WIDTH * PANELS_NUMBER
#define PANE_HEIGHT PANEL_HEIGHT #define PANE_HEIGHT PANEL_HEIGHT
#define MAX_UDP_SIZE 1460 #define MAX_UDP_SIZE 1450
CRGB currentColor;
CRGBPalette16 palettes[] = {HeatColors_p, LavaColors_p, RainbowColors_p, RainbowStripeColors_p, CloudColors_p};
CRGBPalette16 currentPalette = palettes[0];
CRGB ColorFromCurrentPalette(uint8_t index = 0, uint8_t brightness = 255, TBlendType blendType = LINEARBLEND) {
return ColorFromPalette(currentPalette, index, brightness, blendType);
}
uint16_t time_counter = 0, cycles = 0, fps = 0;
unsigned long fps_timer;
WiFiUDP udp; WiFiUDP udp;
unsigned int localUdpPort = 5000; unsigned int localUdpPort = 5000;
const int bufferSize = PANE_WIDTH*PANE_HEIGHT*2; // Adjust based on your data size const int bufferSize = PANE_WIDTH*PANE_HEIGHT*2; // Adjust based on your data size
char incomingPacket[bufferSize]; // Buffer for incoming packets char incomingPacket[bufferSize]; // Buffer for incoming packets
uint16_t pixelData[PANE_WIDTH*PANE_HEIGHT]; // Assuming 2 bytes per RGB565 pixel
// Cấu trúc Pixel //char *incomingPacket_psram = (char *) ps_malloc(bufferSize*sizeof(char));
struct Pixel {
uint16_t color;
};
#define PIXEL_ENTRY_SIZE 5
#define NUM_PIXELS PANE_WIDTH*PANE_HEIGHT #define NUM_PIXELS PANE_WIDTH*PANE_HEIGHT
// Biến trạng thái // Biến trạng thái
int dataOffset = 0; int dataOffset = 0;
bool dataComplete = false; bool dataComplete = false;
uint16_t arr[PANE_HEIGHT*PANE_WIDTH] PROGMEM; uint16_t arr[PANE_HEIGHT*PANE_WIDTH];
MatrixPanel_I2S_DMA *dma_display = nullptr; MatrixPanel_I2S_DMA *dma_display = nullptr;
//Another way of creating config structure //Another way of creating config structure
//Custom pin mapping for all pins //Custom pin mapping for all pins
@ -61,44 +82,118 @@ HUB75_I2S_CFG mxconfig(
HUB75_I2S_CFG::FM6126A // driver chip HUB75_I2S_CFG::FM6126A // driver chip
); );
Pixel pixels[PANE_WIDTH * PANE_HEIGHT]; //Pixel pixels[NUM_PIXELS];
uint8_t tempBuffer[NUM_PIXELS * 2];
void rgb565_to_rgb888(uint16_t color, uint8_t &r, uint8_t &g, uint8_t &b) { //Use PSRAM
r = (color >> 8) & 0xF8; //uint8_t *tempBuffer = (uint8_t *)ps_malloc(sizeof(uint8_t *));
g = (color >> 3) & 0xFC;
b = (color << 3) & 0xF8;
}
uint8_t tempBuffer[PANE_WIDTH * PANE_HEIGHT * 2];
int receivedBytes = 0; // Số byte đã nhận int receivedBytes = 0; // Số byte đã nhận
bool newFrame = true; bool newFrame = true;
uint32_t rgb565_to_rgb888(uint16_t rgb565) {
// Tách các kênh màu từ giá trị RGB565
uint8_t r = (rgb565 >> 11) & 0x1F; // 5 bit cho đỏ
uint8_t g = (rgb565 >> 5) & 0x3F; // 6 bit cho xanh lục
uint8_t b = rgb565 & 0x1F; // 5 bit cho xanh dương
void resetPixels() { // Chuyển đổi các kênh màu từ 5/6 bit sang 8 bit
memset(pixels, 0, sizeof(pixels)); r = (r * 255 + 15) / 31; // Chuyển đổi từ 5 bit sang 8 bit
memset(tempBuffer, 0, sizeof(tempBuffer)); g = (g * 255 + 31) / 63; // Chuyển đổi từ 6 bit sang 8 bit
receivedBytes = 0; b = (b * 255 + 15) / 31; // Chuyển đổi từ 5 bit sang 8 bit
dataComplete = false;
// Ghép các giá trị RGB888 thành một giá trị 32 bit
return (r << 16) | (g << 8) | b;
} }
void receivePixels(char* packet, int length) { void receivePixels(char* packet, int length) {
if (newFrame) { // if (newFrame) {
newFrame = false; // newFrame = false;
//dma_display->clearScreen(); // }
}
if (receivedBytes + length > sizeof(tempBuffer)) { if (receivedBytes + length > sizeof(tempBuffer)) {
length = sizeof(tempBuffer) - receivedBytes; // Giới hạn độ dài length = sizeof(tempBuffer) - receivedBytes; // Giới hạn độ dài
} }
memcpy(tempBuffer + receivedBytes, packet, length); memcpy(tempBuffer + receivedBytes, packet, length);
receivedBytes += length; receivedBytes += length;
// Kiểm tra xem toàn bộ dữ liệu có được nhận đầy đủ chưa // Kiểm tra xem toàn bộ dữ liệu có được nhận đầy đủ chưa
if (receivedBytes == PANE_WIDTH * PANE_HEIGHT * 2) { if (receivedBytes >= NUM_PIXELS * 2) {
//dma_display->clearScreen(); //dma_display->clearScreen();
for (int y = 0; y < PANE_HEIGHT; y++) {
for (int x = 0; x < PANE_WIDTH; x++) {
if(PANE_WIDTH<=128)
{
int index = (y * PANE_WIDTH + x);
uint16_t color = (tempBuffer[index*2] << 8) | tempBuffer[index*2 + 1];
uint32_t rgb888 = rgb565_to_rgb888(color);
uint8_t r = (rgb888 >> 16) & 0xFF; // Kênh đỏ
uint8_t g = (rgb888 >> 8) & 0xFF; // Kênh xanh lục
uint8_t b = rgb888 & 0xFF; // Kênh xanh dương
//pixels[index].color = color;
//dma_display->drawPixel(x, y, color);
if(y<=31)dma_display->drawPixelRGB888(x,y,r,g,b);
else dma_display->drawPixelRGB888(x,y,r,b,g);
}
else
{
if(x<=128){
int index = (y * PANE_WIDTH + x);
uint16_t color = (tempBuffer[index*2] << 8) | tempBuffer[index*2 + 1];
uint32_t rgb888 = rgb565_to_rgb888(color);
uint8_t r = (rgb888 >> 16) & 0xFF; // Kênh đỏ
uint8_t g = (rgb888 >> 8) & 0xFF; // Kênh xanh lục
uint8_t b = rgb888 & 0xFF; // Kênh xanh dương
//pixels[index].color = color;
//dma_display->drawPixel(x, y, color);
if(y<=31)dma_display->drawPixelRGB888(x,y,r,g,b);
else dma_display->drawPixelRGB888(x,y,r,b,g);
}
else
{
int y1 = y + 1;
int x1 = x-128;
int index = (y * PANE_WIDTH + x);
uint16_t color = (tempBuffer[index*2] << 8) | tempBuffer[index*2 + 1];
uint32_t rgb888 = rgb565_to_rgb888(color);
uint8_t r = (rgb888 >> 16) & 0xFF; // Kênh đỏ
uint8_t g = (rgb888 >> 8) & 0xFF; // Kênh xanh lục
uint8_t b = rgb888 & 0xFF; // Kênh xanh dương
//pixels[index].color = color;
//dma_display->drawPixel(x, y, color);
if(y1<=31)dma_display->drawPixelRGB888(x1,y1,r,g,b);
else dma_display->drawPixelRGB888(x1,y1,r,b,g);
}
}
}
}
// Đặt lại bộ nhớ tạm và biến nhận bytes
//memset(tempBuffer, 0, sizeof(tempBuffer));
receivedBytes = 0;
newFrame = true;
}
}
/*
void receivePixels(char* packet, int length) {
if (newFrame) {
newFrame = false;
// Xóa màn hình nếu cần
// dma_display->clearScreen();
}
int BUFFER_SIZE = PANE_WIDTH*PANE_HEIGHT*2;
int remainingSpace = BUFFER_SIZE - receivedBytes;
int bytesToCopy = (length > remainingSpace) ? remainingSpace : length;
// Sao chép dữ liệu vào buffer tạm
memcpy(tempBuffer + receivedBytes, packet, bytesToCopy);
receivedBytes += bytesToCopy;
// Kiểm tra xem toàn bộ dữ liệu có được nhận đầy đủ chưa
if (receivedBytes >= BUFFER_SIZE) {
dataComplete = true; dataComplete = true;
// Xử lý dữ liệu khi đã nhận đầy đủ // Xử lý dữ liệu khi đã nhận đầy đủ
int index = 0; int index = 0;
for (int i = 0; i < receivedBytes; i += 2) { for (int i = 0; i < BUFFER_SIZE; i += 2) {
if (index < PANE_WIDTH * PANE_HEIGHT) { if (index < PANE_WIDTH * PANE_HEIGHT) {
uint16_t color = (tempBuffer[i] << 8) | tempBuffer[i + 1]; uint16_t color = (tempBuffer[i] << 8) | tempBuffer[i + 1];
pixels[index].color = color; pixels[index].color = color;
@ -106,39 +201,116 @@ void receivePixels(char* packet, int length) {
} }
} }
// Xóa bộ nhớ tạm và đặt lại biến nhận bytes
// Đặt lại bộ nhớ tạm và biến nhận bytes
memset(tempBuffer, 0, sizeof(tempBuffer));
receivedBytes = 0; receivedBytes = 0;
memset(tempBuffer, 0, BUFFER_SIZE);
newFrame = true; newFrame = true;
} }
} }
*/
// void displayPixels() {
// for (int y = 0; y < PANE_HEIGHT; y++) {
// for (int x = 0; x < PANE_WIDTH; x++) {
// int index = (y * PANE_WIDTH + x);
// uint16_t color = pixels[index].color;
// if (color != 0) {
// dma_display->drawPixel(x, y, color);
// }
// else{
// dma_display->drawPixel(x, y, 0);
// }
// pixels[index].color = 0;
// }
// }
// }
void plasma_palette()
{
// for (int x = 0; x < PANE_WIDTH; x++) {
// for (int y = 0; y < PANE_HEIGHT; y++) {
// int16_t v = 128;
// uint8_t wibble = sin8(time_counter);
// v += sin16(x * wibble * 3 + time_counter);
// v += cos16(y * (128 - wibble) + time_counter);
// v += sin16(y * x * cos8(-time_counter) / 8);
// currentColor = ColorFromPalette(currentPalette, (v >> 8)); //, brightness, currentBlendType);
// if(y<=31)dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b);
// else dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.b, currentColor.g);
// }
// }
void displayPixels() {
for (int y = 0; y < PANE_HEIGHT; y++) {
for (int x = 0; x < PANE_WIDTH; x++) { for (int x = 0; x < PANE_WIDTH; x++) {
int index = (y * PANE_WIDTH + x); if(x<=128){
uint16_t color = pixels[index].color; for (int y = 0; y < PANE_HEIGHT; y++) {
if (color != 0) { int16_t v = 128;
dma_display->drawPixel(x, y, color); uint8_t wibble = sin8(time_counter);
v += sin16(x * wibble * 3 + time_counter);
v += cos16(y * (128 - wibble) + time_counter);
v += sin16(y * x * cos8(-time_counter) / 8);
currentColor = ColorFromPalette(currentPalette, (v >> 8)); //, brightness, currentBlendType);
if(y<=31)dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b);
else dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.b, currentColor.g);
}
}
else if (x>128 && x<=256){
for (int y = 0; y < PANE_HEIGHT; y++) {
int16_t v = 128;
uint8_t wibble = sin8(time_counter);
int x1 = x-128;
int y1 = y+64;
v += sin16(x1 * wibble * 3 + time_counter);
v += cos16(y1 * (128 - wibble) + time_counter);
v += sin16(y1 * x1 * cos8(-time_counter) / 8);
currentColor = ColorFromPalette(currentPalette, (v >> 8)); //, brightness, currentBlendType);
if(y<=31)dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b);
else dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.b, currentColor.g);
}
} }
else{ else{
dma_display->drawPixel(x, y, 0); for (int y = 0; y < PANE_HEIGHT; y++) {
} int16_t v = 128;
pixels[index].color = 0; uint8_t wibble = sin8(time_counter);
int x1 = x-256;
int y1 = y+64;
v += sin16(x1 * wibble * 3 + time_counter);
v += cos16(y1 * (128 - wibble) + time_counter);
v += sin16(y1 * x1 * cos8(-time_counter) / 8);
currentColor = ColorFromPalette(currentPalette, (v >> 8)); //, brightness, currentBlendType);
if(y<=31)dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.g, currentColor.b);
else dma_display->drawPixelRGB888(x, y, currentColor.r, currentColor.b, currentColor.g);
} }
} }
} }
// void resetPixels() {
// for (int i = 0; i < PANE_WIDTH*PANE_HEIGHT; i++) { ++time_counter;
// pixels[i].color = 0; // Đặt màu về 0 hoặc màu nền khác ++cycles;
// } ++fps;
// }
if (cycles >= 1024) {
time_counter = 0;
cycles = 0;
currentPalette = palettes[random(0,sizeof(palettes)/sizeof(palettes[0]))];
}
// print FPS rate every 5 seconds
// Note: this is NOT a matrix refresh rate, it's the number of data frames being drawn to the DMA buffer per second
if (fps_timer + 5000 < millis()){
//Serial.printf_P(PSTR("Effect fps: %d\n"), fps/5);
fps_timer = millis();
fps = 0;
}
}
void setup() { void setup() {
// put your setup code here, to run once: // put your setup code here, to run once:
Serial.begin(115200); Serial.begin(115200);
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("STA Failed to configure");
}
WiFi.begin(ssid, password); WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { while (WiFi.status() != WL_CONNECTED) {
@ -151,33 +323,29 @@ void setup() {
udp.begin(localUdpPort); udp.begin(localUdpPort);
dma_display = new MatrixPanel_I2S_DMA(mxconfig); dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin(); // setup the LED matrix dma_display->begin(); // setup the LED matrix
dma_display->setBrightness8(15); //0-255 dma_display->setBrightness8(50); //0-255
dma_display->clearScreen(); dma_display->clearScreen();
currentPalette = RainbowColors_p;
} }
void loop() { void loop() {
int packetSize = udp.parsePacket(); int packetSize = udp.parsePacket();
if (packetSize) { if (packetSize) {
int len = udp.read(incomingPacket, MAX_UDP_SIZE); int len = udp.read(incomingPacket, MAX_UDP_SIZE);
if (len > 0) { if (len > 0) {
//Serial.print("Received packet of size ");
//Serial.println(len);
// appendData(incomingPacket, len);
receivePixels(incomingPacket, len); receivePixels(incomingPacket, len);
// Nếu dữ liệu đầy đủ, hiển thị }
if (dataComplete) {
displayPixels();
//Serial.print("complete");
dataComplete = false; // Reset trạng thái
// resetPixels(); // // Use PSRAM
//memset(pixelData, 0, sizeof(pixelData)); // int len = udp.read(incomingPacket_psram, MAX_UDP_SIZE);
// if (len > 0) {
// receivePixels(incomingPacket_psram, len);
// }
} }
} else {
} else { //plasma_palette();
//Serial.println("No packet received"); //Serial.println("No packet received");
} }
//plasma_palette();
// delay(200);
} }