diff --git a/src/mqtt_esp32/mqtt_esp32.ino b/src/mqtt_esp32/mqtt_esp32.ino
index e66ffe9329f946d9c0e859d7ebdee2f534673d59..4bf3e890736c7f28e1bf6abfbd795159f9b816cd 100644
--- a/src/mqtt_esp32/mqtt_esp32.ino
+++ b/src/mqtt_esp32/mqtt_esp32.ino
@@ -4,17 +4,17 @@
 
 #define MATRIX_SIZE 10   // 10x10
 #define IMG_DATA_SIZE MATRIX_SIZE * MATRIX_SIZE * 3 //DATA SIZE FOR ONE MATRIX = RGB * MATRIX_SIZE
-#define IS_TEXT 0
+#define BUFFER_SIZE 128
 
 // WiFi
 const char *ssid = "uni-ete2"; // Enter your WiFi name
 const char *password = "uni-ete2-esp32";  // Enter WiFi password
 
 // MQTT Broker
-const char *mqtt_broker = "192.168.1.103";
+const char *mqtt_broker = "192.168.1.101";
 const char *topic_send = "fromesp";
-const char *topic_img = "toesp/image";
-const char *topic_txt = "toesp/text";
+const char *topic_img = "cluster2/image";
+const char *topic_txt = "cluster2/text";
 const int mqtt_port = 1883;
 
 WiFiClient espClient;
@@ -22,9 +22,10 @@ PubSubClient client(espClient);
 
 // UART2
 HardwareSerial SerialPort(2); // use UART2
+char rcv_buffer[BUFFER_SIZE] = {0};
 
-uint8_t cluster_size_x = 2;
-uint8_t cluster_size_y = 2;
+uint8_t cluster_size_x = 1;
+uint8_t cluster_size_y = 1;
 
 void setup() 
 {
@@ -32,7 +33,7 @@ void setup()
     Serial.begin(115200);
 
     // Set UART2 serial
-    SerialPort.begin(115200, SERIAL_8N1, 16, 17); 
+    SerialPort.begin(115200, SERIAL_8N1, 16, 17); // RX pin: 16, TX pin: 17
 
     // Connecting to a WiFi network
     WiFi.begin(ssid, password);
@@ -69,6 +70,117 @@ void setup()
     client.subscribe(topic_txt);
 }
 
+// UART2 FUNCTIONS, COMM WITH HEPIALIGHT
+void sendMessageToHepialight(const char* data, uint8_t lenght)
+{
+  // SEND UART PACKET HEADER
+  SerialPort.print((char)0x77);
+  SerialPort.print((char)lenght);
+
+  // SEND DATA AND COMPUTE CRC
+  uint8_t crc = 0;
+  for(int i = 0; i < lenght; i++)
+  {
+    if(data[i] == 0x77 || data[i] == 0x10 || data[i] == 0xAA)
+    {
+      crc = crc ^ 0x10;
+      SerialPort.print((char)0x10);
+    }
+    crc = crc ^ data[i];
+    SerialPort.print((char)data[i]);
+  }
+
+  // SEND UART PACKET FOOTER
+  SerialPort.print((char)(crc ^ lenght));
+  SerialPort.print((char)0xAA);
+}
+
+void receive_uart_data(char* received_buffer)
+{
+  static bool receiving_data = false; // Indicator for data reception
+  static uint8_t buffer[BUFFER_SIZE]; // Receive buffer
+  static int buffer_index = 0; // Current buffer index
+  static int message_length = 0; // Length of the currently received message
+  static uint8_t expected_crc = 0; // Expected CRC
+  uint8_t received_crc = 0;
+  bool ctrl_byte = false;
+
+
+  while(SerialPort.available())
+  {
+    uint8_t received_byte = SerialPort.read();
+
+    switch(received_byte)
+    {
+      case 0x77:
+        // IF 0x10 just before
+        if(ctrl_byte)
+        {
+          buffer[buffer_index++] = received_byte;
+          ctrl_byte = false;
+          continue;
+        }
+
+        // UART HEADER
+        buffer_index = 0;
+        receiving_data = false;
+        break;
+      case 0xAA:
+        // IF 0x10 just before
+        if(ctrl_byte)
+        {
+          buffer[buffer_index++] = received_byte;
+          ctrl_byte = false;
+          continue;
+        }
+
+        // UART HEADER
+        receiving_data = false;
+        if(expected_crc == received_crc)
+        {
+          memcpy(received_buffer, buffer, message_length);
+          buffer[buffer_index] = 0;
+          return;
+        }
+        break;
+      case 0x10:
+        // IF 0x10 just before
+        if(!ctrl_byte)
+        {
+          ctrl_byte = true;
+          continue;
+        }
+
+        // DATA
+        buffer[buffer_index++] = received_byte;
+        ctrl_byte = false;
+        break;
+      default:
+          // DATA LEN
+          if(!receiving_data)
+          {
+            message_length = received_byte;
+            expected_crc = received_byte; // Expected CRC is initialized with the message length
+            receiving_data = true;
+            continue;
+          }
+          
+          // DATA
+          // GET MESSAGE CRC
+          if(buffer_index == message_length)
+          {
+            received_crc = received_byte;
+            continue;
+          }
+
+          // Store message bytes in the buffer
+          buffer[buffer_index++] = received_byte;
+          expected_crc ^= received_byte; // Calculate expected CRC
+        break;
+    }
+  }
+}
+
 int d2_to_flat(uint8_t x, uint8_t y, uint32_t pitch)
 {
   return (x * pitch) + y;
@@ -129,38 +241,7 @@ void send_data_to_matrix(uint8_t idx, uint8_t idy, uint8_t* data, uint32_t lengt
     }
   }
 
-  // for(int i = 0; i < length; i+=3)
-  // {
-  //   // Serial.print((char)data[i]);
-  //   // Serial.print((char)data[i+1]);
-  //   // Serial.print((char)data[i+2]);
-
-  //   // COMPUTE COLOR IN 16 BITS
-  //   uint8_t r = data[i] & 0x1F;
-  //   uint8_t g = data[i+1] & 0x3F;
-  //   uint8_t b = data[i+2] & 0x1F ;
-  //   uint16_t rgb = r << 11 | g << 5 | b;
-  //   // Serial.print(rgb);
-  //   // Serial.print(' ');
-
-  //   // SPLIT ON 8 BITS
-  //   uint8_t rgb_0 = rgb >> 8;
-  //   uint8_t rgb_1 = rgb & 0xFF;
-  //   //Serial.println(rgb_0);
-  //   // Serial.print(' ');
-  //   //Serial.println(rgb_1);
-
-  //   // SEND RGB
-  //   //SerialPort.print((char) rgb_0);
-  //   //SerialPort.print((char) rgb_1);
-  //   //send_len += 2;
-  //   raw_data[send_len++] = rgb_0;
-  //   raw_data[send_len++] = rgb_1;
-  // }
-  // // SEND MATRIX ID
-  // Serial.println(idx);
-  // Serial.println(idy);
-  Serial.println(send_len);
+  //Serial.println(send_len);
 
   // SEND UART PACKET HEADER
   SerialPort.print((char)0x77);
@@ -184,7 +265,7 @@ void send_data_to_matrix(uint8_t idx, uint8_t idy, uint8_t* data, uint32_t lengt
   SerialPort.print((char)(crc ^ send_len));
   SerialPort.print((char)0xAA);
 
-  Serial.println(crc ^ send_len);
+  //Serial.println(crc ^ send_len);
 }
 
 void callback(char *topic, byte *payload, unsigned int length) 
@@ -193,21 +274,16 @@ void callback(char *topic, byte *payload, unsigned int length)
   Serial.print("Message arrived in topic: ");
   Serial.println(topic);
 
-  // // TEMP
-  // SerialPort.print((char)0x77);
-  // SerialPort.print((char)202);
-  // for(int i = 0 ; i < 202; i++)
-  // {
-  //   SerialPort.print((char)0x61);
-  // }
-  // SerialPort.print((char)202);
-  // SerialPort.print((char)0xaa);
-
   if(strcmp(topic, topic_txt) == 0)
   {
     char data[100];
-    char header[] = "PT;1,0;MOVING;16711680;0.1;";
+    char header[] = "PT;0,0;MOVING;16711680;0.1;";
     memcpy(data, header, strlen(header) + 1);
+
+    // MATRIX ID
+    data[3] = '0' + cluster_size_x - 1;
+    data[5] = '0';
+
     strncat(data, (char*)payload, length);
     uint32_t len = strlen(data);
 
@@ -246,17 +322,33 @@ void callback(char *topic, byte *payload, unsigned int length)
   {
     for(int y_mat = cluster_size_y - 1; y_mat >= 0; y_mat--)
     {
-      //Serial.println("FOR LOOP");
       // SEND UART PACKET
       send_data_to_matrix(x_mat, y_mat, raw_data, IMG_DATA_SIZE);
-
-      // MOVE FORWARD IN DATA
-      //raw_data += IMG_DATA_SIZE;
     }
   }
 }
 
-void loop() {
-  // put your main code here, to run repeatedly:
+void loop() 
+{
   client.loop();
+  receive_uart_data(rcv_buffer);  // READ UART BUFFER
+
+  // CHECK PRESENCE FROM HEPIALIGHT
+  if(strcmp(rcv_buffer, "ESP") == 0)
+  {
+    Serial.println(rcv_buffer);
+    rcv_buffer[0] = 0;  // CLEAR BUFFER
+    sendMessageToHepialight("OK", 2); // SEND OK
+  }
+
+  // SET MATRIX SIZE
+  if(strncmp(rcv_buffer, "MATSIZE", 7) == 0)
+  {
+    Serial.println(rcv_buffer);
+    cluster_size_x = (rcv_buffer[8] + 1) - '0';
+    cluster_size_y = (rcv_buffer[10] + 1) - '0';
+    Serial.println(cluster_size_x);
+    Serial.println(cluster_size_y);
+    rcv_buffer[0] = 0;  // CLEAR BUFFER  
+  }
 }