/* * display.c * * Created on: 19 Apr 2020 * Author: Chris */ #include "display.h" #include "tftspi.h" #include "tft.h" #define SPI_BUS TFT_VSPI_HOST typedef struct { int datetimeW; int datetimeA; int dateTimeLeft; int datetimeBaseline; int innenW; int aussenW; int locA; int tempW; int degCW; int tempA; int humW; int percentW; int humA; int pressW; int pressA; int hpaW; int datetimebarH; int margin; int borderVMargin; int innenBaseline; int aussenBaseline; int pressBaseline; int humBaseline; int tempBaseline; int unitMaxW; int unitW; int ioW; int unitLeft; int innenLeft; int aussenLeft; } layout_t; static layout_t layout; layout_t create_layout() { layout_t layout; int screenW = tft_width; int screenH = tft_height; layout.datetimebarH = 20; // Can be calculated too layout.margin = 5; layout.borderVMargin = 10; TFT_setFont(UBUNTU16_FONT, NULL); layout.datetimebarH = 20; layout.datetimeW = TFT_getStringWidth("25.12.2031 08:31"); layout.datetimeA = TFT_getfontheight(); layout.dateTimeLeft = (screenW - layout.datetimeW) / 2; layout.datetimeBaseline = (layout.datetimebarH - layout.datetimeA) / 2; layout.innenW = TFT_getStringWidth("Innen"); layout.aussenW = TFT_getStringWidth("Aussen"); layout.locA = TFT_getfontheight(); TFT_setFont(DEJAVU18_FONT, NULL); layout.tempW = TFT_getStringWidth("-35.2"); layout.degCW = TFT_getStringWidth(" C"); layout.tempA = TFT_getfontheight(); TFT_setFont(UBUNTU16_FONT, NULL); layout.humW = TFT_getStringWidth("25.2"); layout.percentW = TFT_getStringWidth("%"); layout.humA = TFT_getfontheight(); layout.pressW = TFT_getStringWidth("1281"); layout.pressA = TFT_getfontheight(); layout.hpaW = TFT_getStringWidth("hPa"); layout.innenBaseline = layout.datetimebarH + layout.borderVMargin; layout.aussenBaseline = layout.innenBaseline; layout.pressBaseline = screenH - layout.borderVMargin - layout.pressA; layout.humBaseline = layout.pressBaseline - layout.pressA - layout.margin; layout.tempBaseline = (layout.humBaseline - layout.humA + layout.innenBaseline) / 2 + 0.5*layout.tempA - 1; int unitMaxW = layout.degCW; if (layout.percentW > unitMaxW) unitMaxW = layout.percentW; if (layout.hpaW > unitMaxW) unitMaxW = layout.hpaW; layout.unitW = 2*layout.margin + unitMaxW; layout.ioW = (screenW - layout.unitW) / 2; layout.unitLeft = screenW - layout.unitW + layout.margin; layout.innenLeft = layout.margin; layout.aussenLeft = layout.innenLeft + layout.ioW; ESP_LOGI("main", "innen: %d x %d, aussen: %d x %d", layout.innenW, layout.locA, layout.aussenW, layout.locA); ESP_LOGI("main", "temps: %d x %d, unit: %d x %d", layout.tempW, layout.tempA, layout.degCW, layout.tempA); ESP_LOGI("main", "hum: %d x %d, unit: %d x %d", layout.humW, layout.humA, layout.percentW, layout.humA); ESP_LOGI("main", "press: %d x %d, unit: %d x %d", layout.pressW, layout.pressA, layout.hpaW, layout.pressA); ESP_LOGI("main", "Baselines - innen: %d, aussen: %d, press: %d, hum: %d, temp: %d", layout.innenBaseline, layout.aussenBaseline, layout.pressBaseline, layout.humBaseline, layout.tempBaseline); ESP_LOGI("main", "Width - units: %d, i/o: %d", layout.unitW, layout.ioW); ESP_LOGI("main", "Left - units: %d", layout.unitLeft); return layout; } uint8_t interpolation(int32_t arg) { int32_t i32_val = arg * 256 / 1000; uint8_t u8_val = (uint8_t)i32_val; return u8_val; } color_t temp_color(int32_t temp_raw) { color_t col = { 0 }; if (temp_raw >= 3500) col.r = 255; else if (temp_raw < 3500 && temp_raw > 2500) { int32_t diff = 3500 - temp_raw; col.r = 255; col.g = interpolation(diff); } else if (temp_raw == 2500) { col.r = 255; col.g = 255; } else if (temp_raw < 2500 && temp_raw > 1500) { int32_t diff = temp_raw - 1500; col.r = interpolation(diff); col.g = 255; } else if (temp_raw == 1500) col.g = 255; else if (temp_raw < 1500 && temp_raw > 500) { int32_t diff = 1500 - temp_raw; col.g = 255; col.b = interpolation(diff); } else if (temp_raw == 500) { col.g = 255; col.b = 255; } else if (temp_raw < 500 && temp_raw > -500) { int32_t diff = temp_raw + 500; col.g = interpolation(diff); col.b = 255; } else if (temp_raw == -500) col.b = 255; else if (temp_raw < -500 && temp_raw > -1500) { int32_t diff = -500 - temp_raw; col.r = interpolation(diff); col.b = 255; } else if (temp_raw <= -1500) { col.r = 255; col.b = 255; } return col; } void print_temp1(int32_t temp_raw) { // Calc temperature pre and post comma values int32_t temp_pre = temp_raw / 100; int32_t temp_post = (abs(temp_raw) % 100) / 10; char temp_str[12]; sprintf(temp_str, "% 2.2d,%.1d", temp_pre, temp_post); TFT_setFont(DEJAVU18_FONT, NULL); tft_fg = temp_color(temp_raw); TFT_print(temp_str, layout.innenLeft, layout.tempBaseline); } void print_temp2(int32_t temp_raw) { // Calc temperature pre and post comma values int32_t temp_pre = temp_raw / 100; int32_t temp_post = (abs(temp_raw) % 100) / 10; char temp_str[12]; sprintf(temp_str, "% 2.2d,%.1d", temp_pre, temp_post); TFT_setFont(DEJAVU18_FONT, NULL); tft_fg = temp_color(temp_raw); TFT_print(temp_str, layout.aussenLeft, layout.tempBaseline); } void print_press1(uint32_t pressure_raw) { // Calc pressure values uint32_t press = pressure_raw / 100; char press_str[12]; sprintf(press_str, "%d", press); TFT_setFont(UBUNTU16_FONT, NULL); tft_fg = TFT_WHITE; TFT_print(press_str, layout.innenLeft, layout.pressBaseline); } void print_press2(uint32_t pressure_raw) { // Calc pressure values uint32_t press = pressure_raw / 100; char press_str[12]; sprintf(press_str, "%d", press); TFT_setFont(UBUNTU16_FONT, NULL); tft_fg = TFT_WHITE; TFT_print(press_str, layout.aussenLeft, layout.pressBaseline); } void print_humid1(uint32_t humidity_raw) { // Calc humidity pre and post comma values uint32_t humid_pre = humidity_raw / 1024; uint32_t humid_post = (humidity_raw - humid_pre*1024) * 10 / 1024; char humid_str[12]; sprintf(humid_str, "%2.2d,%.1d", humid_pre, humid_post); TFT_setFont(UBUNTU16_FONT, NULL); tft_fg = TFT_WHITE; TFT_print(humid_str, layout.innenLeft, layout.humBaseline); } void print_humid2(uint32_t humidity_raw) { // Calc humidity pre and post comma values uint32_t humid_pre = humidity_raw / 1024; uint32_t humid_post = (humidity_raw - humid_pre*1024) * 10 / 1024; char humid_str[12]; sprintf(humid_str, "%2.2d,%.1d", humid_pre, humid_post); TFT_setFont(UBUNTU16_FONT, NULL); tft_fg = TFT_WHITE; TFT_print(humid_str, layout.aussenLeft, layout.humBaseline); } int32_t last_temp_raw = 0; uint32_t last_pressure_raw = 0; uint32_t last_humidity_raw = 0; int32_t last_temp2_raw = 0; uint32_t last_pressure2_raw = 0; uint32_t last_humidity2_raw = 0; void update_data(int32_t temp_raw, uint32_t pressure_raw, uint32_t humidity_raw, int32_t temp2_raw, uint32_t pressure2_raw, uint32_t humidity2_raw) { if (temp_raw != last_temp_raw) { print_temp1(temp_raw); last_temp_raw = temp_raw; } if (temp2_raw != last_temp2_raw) { print_temp2(temp2_raw); last_temp2_raw = temp2_raw; } if (pressure_raw != last_pressure_raw) { print_press1(pressure_raw); last_pressure_raw = pressure_raw; } if (pressure2_raw != last_pressure2_raw) { print_press2(pressure2_raw); last_pressure2_raw = pressure2_raw; } if (humidity_raw != last_humidity_raw) { print_humid1(humidity_raw); last_humidity_raw = humidity_raw; } if (humidity2_raw != last_humidity2_raw) { print_humid2(humidity2_raw); last_humidity2_raw = humidity2_raw; } last_pressure_raw = pressure_raw; last_humidity_raw = humidity_raw; last_temp2_raw = temp2_raw; last_pressure2_raw = pressure2_raw; last_humidity2_raw = humidity2_raw; } void display_data(int32_t temp_raw, uint32_t pressure_raw, uint32_t humidity_raw, int32_t temp2_raw, uint32_t pressure2_raw, uint32_t humidity2_raw) { // HEADER TFT_setFont(UBUNTU16_FONT, NULL); tft_fg = TFT_WHITE; TFT_print("25.12.2031 08:31", layout.dateTimeLeft, layout.datetimeBaseline); TFT_drawFastHLine(0, 20, 160, TFT_WHITE); // IN OUT LABEL TFT_print("Innen", layout.innenLeft, layout.innenBaseline); TFT_print("Aussen", layout.aussenLeft, layout.aussenBaseline); // VALUES print_temp1(temp_raw); print_temp2(temp2_raw); print_humid1(humidity_raw); print_humid2(humidity2_raw); print_press1(pressure_raw); print_press2(pressure2_raw); // UNIT LABELS TFT_setFont(DEJAVU18_FONT, NULL); tft_fg = TFT_WHITE; TFT_print(" C", layout.unitLeft, layout.tempBaseline); TFT_drawCircle(layout.unitLeft+3, layout.tempBaseline+3, 3, TFT_WHITE); TFT_setFont(UBUNTU16_FONT, NULL); TFT_print("%", layout.unitLeft, layout.humBaseline); TFT_print("hPa", layout.unitLeft, layout.pressBaseline); last_temp_raw = temp_raw; last_pressure_raw = pressure_raw; last_humidity_raw = humidity_raw; last_temp2_raw = temp2_raw; last_pressure2_raw = pressure2_raw; last_humidity2_raw = humidity2_raw; } esp_err_t init_display() { tft_max_rdclock = 4000000; TFT_PinsInit(); spi_lobo_device_handle_t spi; spi_lobo_bus_config_t buscfg={ .miso_io_num=PIN_NUM_MISO, .mosi_io_num=PIN_NUM_MOSI, .sclk_io_num=PIN_NUM_CLK, .quadwp_io_num=-1, .quadhd_io_num=-1, .max_transfer_sz = 6*1024, }; spi_lobo_device_interface_config_t devcfg={ .clock_speed_hz=8000000, .mode=0, .spics_io_num=-1, .spics_ext_io_num=PIN_NUM_CS, .flags=LB_SPI_DEVICE_HALFDUPLEX, }; esp_err_t ret; ret=spi_lobo_bus_add_device(SPI_BUS, &buscfg, &devcfg, &spi); if (ret != ESP_OK) { return ret; } tft_disp_spi = spi; TFT_display_init(); tft_max_rdclock = find_rd_speed(); spi_lobo_set_speed(spi, DEFAULT_SPI_CLOCK); tft_font_rotate = 0; tft_text_wrap = 0; tft_font_transparent = 0; tft_font_forceFixed = 0; tft_gray_scale = 0; TFT_setGammaCurve(DEFAULT_GAMMA_CURVE); TFT_setRotation(LANDSCAPE_FLIP); TFT_setFont(DEFAULT_FONT, NULL); TFT_resetclipwin(); tft_image_debug = 0; layout = create_layout(); return ESP_OK; }