Repo for ESP32 Weather Station Development
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

348 lignes
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. }