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.

376 lignes
9.8KB

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