Repo for ESP32 Weather Station Development
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

348 linhas
9.1KB

  1. /*
  2. * display.c
  3. *
  4. * Created on: 19 Apr 2020
  5. * Author: Chris
  6. */
  7. #include "display.h"
  8. #include "tftspi.h"
  9. #include "tft.h"
  10. #define SPI_BUS TFT_VSPI_HOST
  11. typedef struct {
  12. int datetimeW;
  13. int datetimeA;
  14. int dateTimeLeft;
  15. int datetimeBaseline;
  16. int innenW;
  17. int aussenW;
  18. int locA;
  19. int tempW;
  20. int degCW;
  21. int tempA;
  22. int humW;
  23. int percentW;
  24. int humA;
  25. int pressW;
  26. int pressA;
  27. int hpaW;
  28. int datetimebarH;
  29. int margin;
  30. int borderVMargin;
  31. int innenBaseline;
  32. int aussenBaseline;
  33. int pressBaseline;
  34. int humBaseline;
  35. int tempBaseline;
  36. int unitMaxW;
  37. int unitW;
  38. int ioW;
  39. int unitLeft;
  40. int innenLeft;
  41. int aussenLeft;
  42. } layout_t;
  43. static layout_t layout;
  44. layout_t create_layout()
  45. {
  46. layout_t layout;
  47. int screenW = tft_width;
  48. int screenH = tft_height;
  49. layout.datetimebarH = 20; // Can be calculated too
  50. layout.margin = 5;
  51. layout.borderVMargin = 10;
  52. TFT_setFont(SMALL_FONT, NULL);
  53. layout.datetimebarH = 20;
  54. layout.datetimeW = TFT_getStringWidth("25.12.2031 08:31:11");
  55. layout.datetimeA = TFT_getfontheight();
  56. layout.dateTimeLeft = (screenW - layout.datetimeW) / 2;
  57. layout.datetimeBaseline = (layout.datetimebarH - layout.datetimeA) / 2;
  58. TFT_setFont(UBUNTU16_FONT, NULL);
  59. layout.innenW = TFT_getStringWidth("Innen");
  60. layout.aussenW = TFT_getStringWidth("Aussen");
  61. layout.locA = TFT_getfontheight();
  62. TFT_setFont(DEJAVU18_FONT, NULL);
  63. layout.tempW = TFT_getStringWidth("-35.2");
  64. layout.degCW = TFT_getStringWidth(" C");
  65. layout.tempA = TFT_getfontheight();
  66. TFT_setFont(UBUNTU16_FONT, NULL);
  67. layout.humW = TFT_getStringWidth("25.2");
  68. layout.percentW = TFT_getStringWidth("%");
  69. layout.humA = TFT_getfontheight();
  70. layout.pressW = TFT_getStringWidth("1281");
  71. layout.pressA = TFT_getfontheight();
  72. layout.hpaW = TFT_getStringWidth("hPa");
  73. layout.innenBaseline = layout.datetimebarH + layout.borderVMargin;
  74. layout.aussenBaseline = layout.innenBaseline;
  75. layout.pressBaseline = screenH - layout.borderVMargin - layout.pressA;
  76. layout.humBaseline = layout.pressBaseline - layout.pressA - layout.margin;
  77. layout.tempBaseline = (layout.humBaseline - layout.humA + layout.innenBaseline) / 2
  78. + 0.5*layout.tempA - 1;
  79. int unitMaxW = layout.degCW;
  80. if (layout.percentW > unitMaxW) unitMaxW = layout.percentW;
  81. if (layout.hpaW > unitMaxW) unitMaxW = layout.hpaW;
  82. layout.unitW = 2*layout.margin + unitMaxW;
  83. layout.ioW = (screenW - layout.unitW) / 2;
  84. layout.unitLeft = screenW - layout.unitW + layout.margin;
  85. layout.innenLeft = layout.margin;
  86. layout.aussenLeft = layout.innenLeft + layout.ioW;
  87. ESP_LOGI("main", "innen: %d x %d, aussen: %d x %d", layout.innenW,
  88. layout.locA, layout.aussenW, layout.locA);
  89. ESP_LOGI("main", "temps: %d x %d, unit: %d x %d", layout.tempW,
  90. layout.tempA, layout.degCW, layout.tempA);
  91. ESP_LOGI("main", "hum: %d x %d, unit: %d x %d", layout.humW, layout.humA,
  92. layout.percentW, layout.humA);
  93. ESP_LOGI("main", "press: %d x %d, unit: %d x %d", layout.pressW, layout.pressA,
  94. layout.hpaW, layout.pressA);
  95. ESP_LOGI("main", "Baselines - innen: %d, aussen: %d, press: %d, hum: %d, temp: %d",
  96. layout.innenBaseline, layout.aussenBaseline,
  97. layout.pressBaseline, layout.humBaseline, layout.tempBaseline);
  98. ESP_LOGI("main", "Width - units: %d, i/o: %d", layout.unitW, layout.ioW);
  99. ESP_LOGI("main", "Left - units: %d", layout.unitLeft);
  100. return layout;
  101. }
  102. uint8_t interpolation(int32_t arg) {
  103. int32_t i32_val = arg * 256 / 1000;
  104. uint8_t u8_val = (uint8_t)i32_val;
  105. return u8_val;
  106. }
  107. color_t temp_color(int32_t temp_raw) {
  108. color_t col = { 0 };
  109. if (temp_raw >= 3500)
  110. col.r = 255;
  111. else if (temp_raw < 3500 && temp_raw > 2500) {
  112. int32_t diff = 3500 - temp_raw;
  113. col.r = 255;
  114. col.g = interpolation(diff);
  115. }
  116. else if (temp_raw == 2500) {
  117. col.r = 255;
  118. col.g = 255;
  119. }
  120. else if (temp_raw < 2500 && temp_raw > 1500) {
  121. int32_t diff = temp_raw - 1500;
  122. col.r = interpolation(diff);
  123. col.g = 255;
  124. }
  125. else if (temp_raw == 1500)
  126. col.g = 255;
  127. else if (temp_raw < 1500 && temp_raw > 500) {
  128. int32_t diff = 1500 - temp_raw;
  129. col.g = 255;
  130. col.b = interpolation(diff);
  131. }
  132. else if (temp_raw == 500) {
  133. col.g = 255;
  134. col.b = 255;
  135. }
  136. else if (temp_raw < 500 && temp_raw > -500) {
  137. int32_t diff = temp_raw + 500;
  138. col.g = interpolation(diff);
  139. col.b = 255;
  140. }
  141. else if (temp_raw == -500)
  142. col.b = 255;
  143. else if (temp_raw < -500 && temp_raw > -1500) {
  144. int32_t diff = -500 - temp_raw;
  145. col.r = interpolation(diff);
  146. col.b = 255;
  147. }
  148. else if (temp_raw <= -1500) {
  149. col.r = 255;
  150. col.b = 255;
  151. }
  152. return col;
  153. }
  154. void print_temp1(int32_t temp_raw)
  155. {
  156. // Calc temperature pre and post comma values
  157. int32_t temp_pre = temp_raw / 100;
  158. int32_t temp_post = (abs(temp_raw) % 100) / 10;
  159. char temp_str[12];
  160. sprintf(temp_str, "% 2.2d,%.1d", temp_pre, temp_post);
  161. TFT_setFont(DEJAVU18_FONT, NULL);
  162. tft_fg = temp_color(temp_raw);
  163. TFT_print(temp_str, layout.innenLeft, layout.tempBaseline);
  164. }
  165. void print_temp2(int32_t temp_raw)
  166. {
  167. // Calc temperature pre and post comma values
  168. int32_t temp_pre = temp_raw / 100;
  169. int32_t temp_post = (abs(temp_raw) % 100) / 10;
  170. char temp_str[12];
  171. sprintf(temp_str, "% 2.2d,%.1d", temp_pre, temp_post);
  172. TFT_setFont(DEJAVU18_FONT, NULL);
  173. tft_fg = temp_color(temp_raw);
  174. TFT_print(temp_str, layout.aussenLeft, layout.tempBaseline);
  175. }
  176. void print_press1(uint32_t pressure_raw)
  177. {
  178. // Calc pressure values
  179. uint32_t press = pressure_raw / 100;
  180. char press_str[12];
  181. sprintf(press_str, "%d", press);
  182. TFT_setFont(UBUNTU16_FONT, NULL);
  183. tft_fg = TFT_WHITE;
  184. TFT_print(press_str, layout.innenLeft, layout.pressBaseline);
  185. }
  186. void print_press2(uint32_t pressure_raw)
  187. {
  188. // Calc pressure values
  189. uint32_t press = pressure_raw / 100;
  190. char press_str[12];
  191. sprintf(press_str, "%d", press);
  192. TFT_setFont(UBUNTU16_FONT, NULL);
  193. tft_fg = TFT_WHITE;
  194. TFT_print(press_str, layout.aussenLeft, layout.pressBaseline);
  195. }
  196. void print_humid1(uint32_t humidity_raw)
  197. {
  198. // Calc humidity pre and post comma values
  199. uint32_t humid_pre = humidity_raw / 1024;
  200. uint32_t humid_post = (humidity_raw - humid_pre*1024) * 10 / 1024;
  201. char humid_str[12];
  202. sprintf(humid_str, "%2.2d,%.1d", humid_pre, humid_post);
  203. TFT_setFont(UBUNTU16_FONT, NULL);
  204. tft_fg = TFT_WHITE;
  205. TFT_print(humid_str, layout.innenLeft, layout.humBaseline);
  206. }
  207. void print_humid2(uint32_t humidity_raw)
  208. {
  209. // Calc humidity pre and post comma values
  210. uint32_t humid_pre = humidity_raw / 1024;
  211. uint32_t humid_post = (humidity_raw - humid_pre*1024) * 10 / 1024;
  212. char humid_str[12];
  213. sprintf(humid_str, "%2.2d,%.1d", humid_pre, humid_post);
  214. TFT_setFont(UBUNTU16_FONT, NULL);
  215. tft_fg = TFT_WHITE;
  216. TFT_print(humid_str, layout.aussenLeft, layout.humBaseline);
  217. }
  218. void print_time(time_str_t time)
  219. {
  220. TFT_setFont(SMALL_FONT, NULL);
  221. char datetime_str[129];
  222. sprintf(datetime_str, "%s %s", time.date_str, time.time_str);
  223. TFT_print(datetime_str, layout.dateTimeLeft, layout.datetimeBaseline);
  224. }
  225. void display_data(int32_t temp_raw, uint32_t pressure_raw, uint32_t humidity_raw,
  226. int32_t temp2_raw, uint32_t pressure2_raw, uint32_t humidity2_raw,
  227. time_str_t time)
  228. {
  229. // HEADER
  230. tft_fg = TFT_WHITE;
  231. TFT_drawFastHLine(0, 20, 160, TFT_WHITE);
  232. // IN OUT LABEL
  233. TFT_setFont(UBUNTU16_FONT, NULL);
  234. TFT_print("Innen", layout.innenLeft, layout.innenBaseline);
  235. TFT_print("Aussen", layout.aussenLeft, layout.aussenBaseline);
  236. // VALUES
  237. print_temp1(temp_raw);
  238. print_temp2(temp2_raw);
  239. print_humid1(humidity_raw);
  240. print_humid2(humidity2_raw);
  241. print_press1(pressure_raw);
  242. print_press2(pressure2_raw);
  243. print_time(time);
  244. // UNIT LABELS
  245. TFT_setFont(DEJAVU18_FONT, NULL);
  246. tft_fg = TFT_WHITE;
  247. TFT_print(" C", layout.unitLeft, layout.tempBaseline);
  248. TFT_drawCircle(layout.unitLeft+3, layout.tempBaseline+3, 3, TFT_WHITE);
  249. TFT_setFont(UBUNTU16_FONT, NULL);
  250. TFT_print("%", layout.unitLeft, layout.humBaseline);
  251. TFT_print("hPa", layout.unitLeft, layout.pressBaseline);
  252. }
  253. void update_data(int32_t temp_raw, uint32_t pressure_raw, uint32_t humidity_raw,
  254. int32_t temp2_raw, uint32_t pressure2_raw, uint32_t humidity2_raw,
  255. time_str_t time)
  256. {
  257. // VALUES
  258. print_temp1(temp_raw);
  259. print_temp2(temp2_raw);
  260. print_humid1(humidity_raw);
  261. print_humid2(humidity2_raw);
  262. print_press1(pressure_raw);
  263. print_press2(pressure2_raw);
  264. print_time(time);
  265. }
  266. esp_err_t init_display()
  267. {
  268. tft_max_rdclock = 4000000;
  269. TFT_PinsInit();
  270. spi_lobo_device_handle_t spi;
  271. spi_lobo_bus_config_t buscfg={
  272. .miso_io_num=PIN_NUM_MISO,
  273. .mosi_io_num=PIN_NUM_MOSI,
  274. .sclk_io_num=PIN_NUM_CLK,
  275. .quadwp_io_num=-1,
  276. .quadhd_io_num=-1,
  277. .max_transfer_sz = 6*1024,
  278. };
  279. spi_lobo_device_interface_config_t devcfg={
  280. .clock_speed_hz=8000000,
  281. .mode=0,
  282. .spics_io_num=-1,
  283. .spics_ext_io_num=PIN_NUM_CS,
  284. .flags=LB_SPI_DEVICE_HALFDUPLEX,
  285. };
  286. esp_err_t ret;
  287. ret=spi_lobo_bus_add_device(SPI_BUS, &buscfg, &devcfg, &spi);
  288. if (ret != ESP_OK)
  289. {
  290. return ret;
  291. }
  292. tft_disp_spi = spi;
  293. TFT_display_init();
  294. tft_max_rdclock = find_rd_speed();
  295. spi_lobo_set_speed(spi, DEFAULT_SPI_CLOCK);
  296. tft_font_rotate = 0;
  297. tft_text_wrap = 0;
  298. tft_font_transparent = 0;
  299. tft_font_forceFixed = 0;
  300. tft_gray_scale = 0;
  301. TFT_setGammaCurve(DEFAULT_GAMMA_CURVE);
  302. TFT_setRotation(LANDSCAPE_FLIP);
  303. TFT_setFont(DEFAULT_FONT, NULL);
  304. TFT_resetclipwin();
  305. tft_image_debug = 0;
  306. layout = create_layout();
  307. return ESP_OK;
  308. }