#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "string.h"
#define TXD_PIN (GPIO_NUM_4)
#define RXD_PIN (GPIO_NUM_5)
#define RX_BUF_SIZE 1024
void init(void);
int sendData(const char*, const char*);
int comparar(const void*, const void*);
void ordenarArreglo(int*, int);
int eliminarDuplicados(int*, int);
void update_LEDs(uint8_t);
void tx_task(void*);
void rx_task(void*);
void app_main(void)
{
init();
xTaskCreate(rx_task, "uart_rx_task", 1024*4, NULL, 10, NULL);
}
void init(void) {
const uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
uart_driver_install(UART_NUM_1, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
uart_param_config(UART_NUM_1, &uart_config);
uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = (1ULL << GPIO_NUM_16) |
(1ULL << GPIO_NUM_17) |
(1ULL << GPIO_NUM_18) |
(1ULL << GPIO_NUM_19) |
(1ULL << GPIO_NUM_21) |
(1ULL << GPIO_NUM_22) |
(1ULL << GPIO_NUM_23) |
(1ULL << GPIO_NUM_25);
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
}
int sendData(const char* logName, const char* data)
{
const int len = strlen(data);
const int txBytes = uart_write_bytes(UART_NUM_1, data, len);
ESP_LOGI(logName, "Wrote %d bytes", txBytes);
return txBytes;
}
void update_LEDs(uint8_t value)
{
gpio_set_level(GPIO_NUM_25, (value >> 7) & 1);
gpio_set_level(GPIO_NUM_23, (value >> 6) & 1);
gpio_set_level(GPIO_NUM_22, (value >> 5) & 1);
gpio_set_level(GPIO_NUM_21, (value >> 4) & 1);
gpio_set_level(GPIO_NUM_19, (value >> 3) & 1);
gpio_set_level(GPIO_NUM_18, (value >> 2) & 1);
gpio_set_level(GPIO_NUM_17, (value >> 1) & 1);
gpio_set_level(GPIO_NUM_16, value & 1);
}
void rx_task(void *arg)
{
static const char *RX_TASK_TAG = "RX_TASK";
esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO);
uint8_t data[RX_BUF_SIZE];
int w[256], n = 0;
while (1) {
ESP_LOGI(RX_TASK_TAG, "Waiting for N");
int rxBytes = uart_read_bytes(UART_NUM_1, data, 1, portMAX_DELAY);
if (rxBytes > 0 && data[0] > 0) {
n = data[0];
ESP_LOGI(RX_TASK_TAG, "Received N = %d", n);
ESP_LOGI(RX_TASK_TAG, "Waiting for %d elements", n);
rxBytes = uart_read_bytes(UART_NUM_1, w, n, portMAX_DELAY);
if (rxBytes == n) {
ESP_LOGI(RX_TASK_TAG, "Received %d elements", n);
ordenarArreglo(w, n);
n = eliminarDuplicados(w, n);
for (int i = n; i < 256; i++) {
w[i] = -1;
}
for (int i = 0; i < n; i++) {
if (w[i] != -1) {
update_LEDs(w[i]);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
}
}
}
}
int comparar(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
void ordenarArreglo(int *arr, int n) {
qsort(arr, n, sizeof(int), comparar);
}
int eliminarDuplicados(int *arr, int n) {
if (n == 0) return 0;
int j = 0;
for (int i = 1; i < n; i++) {
if (arr[j] != arr[i]) {
j++;
arr[j] = arr[i];
}
}
return j + 1;
}