diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 2b03fb4..0b66cb4 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -2,11 +2,11 @@ "configurations": [ { "name": "ESP-IDF", - "compilerPath": "C:/esp/espressif/tools/xtensa-esp32-elf/esp-12.2.0_20230208/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc.exe", + "compilerPath": "C:/esp/tools/xtensa-esp32-elf/esp-12.2.0_20230208/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc.exe", "compileCommands": "${workspaceFolder}/build/compile_commands.json", "includePath": [ "${workspaceFolder}/**", - "C:/esp/esp-idf/components/**" + "C:/ESP/frameworks/v5.1.6/esp-idf/components/**" ], "defines": [ "ESP_PLATFORM", diff --git a/main/display.c b/main/display.c index 9f5ae2f..faa3238 100644 --- a/main/display.c +++ b/main/display.c @@ -5,52 +5,29 @@ #define DISP_ADDR 0x70 #define I2C_PORT I2C_NUM_0 -// Exemplo de tabela 16 bits para 0–9 (tens de afinar os bits para o teu módulo) -static const uint16_t segtbl16[10] = { - 0b0000000000111111, // 0 - 0b0000000000000110, // 1 - 0b0000000001011011, // 2 - 0b0000000001001111, // 3 - 0b0000000001100110, // 4 - 0b0000000001101101, // 5 - 0b0000000001111101, // 6 - 0b0000000000000111, // 7 - 0b0000000001111111, // 8 - 0b0000000001101111 // 9 -}; - -static const uint16_t alpha_map[] = { - ['A'] = 0b0000000001110111, - ['b'] = 0b0000000001111100, - ['C'] = 0b0000000000111001, - ['d'] = 0b0000000001011110, - ['E'] = 0b0000000001111001, - ['F'] = 0b0000000001110001, - ['H'] = 0b0000000001110110, - ['L'] = 0b0000000000111000, - ['P'] = 0b0000000001110011, - ['r'] = 0b0000000001010000, - ['U'] = 0b0000000000111110, -}; +const char *TAG = "DISPLAY"; +// ------------------------------ +// DISPLAY INIT +// ------------------------------ void display_init(void) { - // Oscillator ON - uint8_t cmd1 = 0x21; + uint8_t cmd1 = 0x21; // oscillator ON i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd1, 1, 20 / portTICK_PERIOD_MS); - // Display ON, no blink - uint8_t cmd2 = 0x81; + uint8_t cmd2 = 0x81; // display ON, blink OFF i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd2, 1, 20 / portTICK_PERIOD_MS); - // Brilho máximo - uint8_t cmd3 = 0xEF; + uint8_t cmd3 = 0xEF; // brightness i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd3, 1, 20 / portTICK_PERIOD_MS); display_clear(); } +// ------------------------------ +// CLEAR DISPLAY +// ------------------------------ void display_clear(void) { uint8_t buf[17] = {0}; @@ -58,22 +35,117 @@ void display_clear(void) i2c_master_write_to_device(I2C_PORT, DISP_ADDR, buf, sizeof(buf), 20 / portTICK_PERIOD_MS); } -void display_digit(int pos, uint8_t val) +// -------------------------------------------------------- +// RAW WRITE — 14 segmentos (cada dígito = 16 bits) +// -------------------------------------------------------- +void display_raw(int pos, uint16_t mask) { if (pos < 0 || pos > 3) return; - if (val > 9) val = 0; - - uint16_t pattern = segtbl16[val]; uint8_t buf[3]; - buf[0] = pos * 2; // endereço base do dígito - buf[1] = pattern & 0xFF; // byte baixo (bits 0–7) - buf[2] = (pattern >> 8) & 0xFF; // byte alto (bits 8–15) + buf[0] = pos * 2; + buf[1] = mask & 0xFF; + buf[2] = (mask >> 8) & 0xFF; - i2c_master_write_to_device(I2C_PORT, DISP_ADDR, buf, 3, - 20 / portTICK_PERIOD_MS); + i2c_master_write_to_device(I2C_PORT, DISP_ADDR, buf, 3, 20 / portTICK_PERIOD_MS); } +// -------------------------------------------------------- +// Tabela alfanumérica 14 segmentos +// (corrigido: H com os 2 segmentos horizontais g1/g2) +// -------------------------------------------------------- +static uint16_t charset(char c) +{ + switch (c) + { + case '0': return 0b0000000000111111; + case '1': return 0b0000000000000110; + case '2': return 0b0000000001011011; + case '3': return 0b0000000001001111; + case '4': return 0b0000000001100110; + case '5': return 0b0000000001101101; + case '6': return 0b0000000001111101; + case '7': return 0b0000000000000111; + case '8': return 0b0000000001111111; + case '9': return 0b0000000001101111; + + // Letras principais + case 'A': case 'a': return 0b0000000001110111; + case 'B': case 'b': return 0b0001000011111100; + case 'C': case 'c': return 0b0000000000111001; + case 'D': case 'd': return 0b0001000011011110; + case 'E': case 'e': return 0b0000000001111001; + case 'F': case 'f': return 0b0000000001110001; + + // CORRIGIDO → H com g1 + g2 + case 'H': case 'h': return + (1<<5) | // f + (1<<4) | // e + (1<<1) | // b + (1<<2) | // c + (1<<6) | // g1 + (1<<7); // g2 + + case 'I': case 'i': return 0b0001000000000000 | 0b0000000000000110; + case 'L': case 'l': return 0b0000000000111000; + case 'O': case 'o': return 0b0001000010011100; + case 'P': case 'p': return 0b0000000001110011; + case 'S': case 's': return 0b0000000001101101; + case 'U': case 'u': return 0b0000000000011100; + + case '-': return 0b0000000001000000; + case ' ': return 0; + + default: + return 0; + } +} + +// -------------------------------------------------------- +// display_char() +// -------------------------------------------------------- +void display_char(int pos, char c) +{ + uint16_t mask = charset(c); + display_raw(pos, mask); +} + +// -------------------------------------------------------- +// display_text() (4 caracteres) +// -------------------------------------------------------- +void display_text(const char *txt) +{ + for (int i = 0; i < 4; i++) + { + char c = txt[i]; + if (c == 0) c = ' '; + display_char(i, c); + } +} + +// -------------------------------------------------------- +// display_number() +// Mantida para compatibilidade com 7-segment +// -------------------------------------------------------- +void display_digit(int pos, uint8_t val) +{ + static const uint8_t seg7[10] = { + 0b00111111, + 0b00000110, + 0b01011011, + 0b01001111, + 0b01100110, + 0b01101101, + 0b01111101, + 0b00000111, + 0b01111111, + 0b01101111 + }; + + if (val > 9) val = 0; + + display_raw(pos, seg7[val]); +} void display_number(int num) { @@ -85,16 +157,13 @@ void display_number(int num) display_digit(1, (num / 100) % 10); display_digit(0, (num / 1000) % 10); } - -void display_set_time(int h, int m) +void display_set_time(int horas, int minutos) { - if (h < 0) h = 0; - if (h > 23) h = h % 24; + if (horas < 0) horas = 0; + if (horas > 99) horas = 99; + if (minutos < 0) minutos = 0; + if (minutos > 99) minutos = 99; - if (m < 0) m = 0; - if (m > 59) m = m % 60; - - int value = h * 100 + m; // HHMM - - display_number(value); + int num = horas * 100 + minutos; + display_number(num); } diff --git a/main/i2c_helper.c b/main/i2c_helper.c index a51c823..b4259ce 100644 --- a/main/i2c_helper.c +++ b/main/i2c_helper.c @@ -12,7 +12,7 @@ void i2c_init(void) .scl_io_num = SCL_PIN, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, - .master.clk_speed = 100000 + .master.clk_speed = 400000 }; i2c_param_config(I2C_PORT, &cfg); diff --git a/main/include/display.h b/main/include/display.h index 1bdd71c..1d5dc31 100644 --- a/main/include/display.h +++ b/main/include/display.h @@ -1,8 +1,10 @@ #pragma once -#include void display_init(void); void display_clear(void); -void display_digit(int pos, uint8_t value); +void display_raw(int pos, uint16_t mask); +void display_char(int pos, char c); +void display_text(const char *txt); +void display_digit(int pos, uint8_t val); void display_number(int num); -void display_set_time(int h, int m); +void display_set_time(int horas, int minutos); diff --git a/main/main.c b/main/main.c index 8d39e61..9408525 100644 --- a/main/main.c +++ b/main/main.c @@ -168,10 +168,11 @@ void app_main(void) { //i2c scan - i2c_init(); // <- o helper entra aqui - display_init(); // <- inicializa o HT16K33 +i2c_init(); // vem do i2c_helper.c +display_init(); +display_text("INIT"); - display_number(0000); + // -------- Wi-Fi --------