#include "driver/i2c.h" #include "esp_log.h" #include "display.h" #define DISP_ADDR 0x70 #define I2C_PORT I2C_NUM_0 const char *TAG = "DISPLAY"; // ------------------------------ // DISPLAY INIT // ------------------------------ void display_init(void) { uint8_t cmd1 = 0x21; // oscillator ON i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd1, 1, 20 / portTICK_PERIOD_MS); uint8_t cmd2 = 0x81; // display ON, blink OFF i2c_master_write_to_device(I2C_PORT, DISP_ADDR, &cmd2, 1, 20 / portTICK_PERIOD_MS); 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}; buf[0] = 0x00; i2c_master_write_to_device(I2C_PORT, DISP_ADDR, buf, sizeof(buf), 20 / portTICK_PERIOD_MS); } // -------------------------------------------------------- // RAW WRITE — 14 segmentos (cada dígito = 16 bits) // -------------------------------------------------------- void display_raw(int pos, uint16_t mask) { if (pos < 0 || pos > 3) return; uint8_t buf[3]; 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); } // -------------------------------------------------------- // 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) { if (num < 0) num = 0; if (num > 9999) num = 9999; display_digit(3, num % 10); display_digit(2, (num / 10) % 10); display_digit(1, (num / 100) % 10); display_digit(0, (num / 1000) % 10); } void display_set_time(int horas, int minutos) { if (horas < 0) horas = 0; if (horas > 99) horas = 99; if (minutos < 0) minutos = 0; if (minutos > 99) minutos = 99; int num = horas * 100 + minutos; display_number(num); }