Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия | ||
products:laboratory_iot_c:exp70 [2024/12/17 18:06] – [Эксперимент 70. Графический интерфейс метеостанции] labuser30 | products:laboratory_iot_c:exp70 [2024/12/17 18:21] (текущий) – [Программный код эксперимента] labuser30 | ||
---|---|---|---|
Строка 23: | Строка 23: | ||
==== Программный код эксперимента ==== | ==== Программный код эксперимента ==== | ||
- | < | + | < |
- | from machine import Pin, SPI | + | #include <SPI.h> |
- | from tft import TFT_GREEN | + | #include < |
- | import font | + | #include " |
- | import network | + | #include < |
- | import gc | + | |
- | import time | + | #define PIN_CS |
- | import socket | + | #define PIN_DC |
+ | #define PIN_RST 5 | ||
+ | |||
+ | Adafruit_ST7735 tft = Adafruit_ST7735(PIN_CS, | ||
+ | LittleFS_ImageReader reader; | ||
- | _init() | + | void setup() { |
- | gc.collect() | + | |
+ | tft.initR(INITR_BLACKTAB); | ||
+ | tft.setRotation(2); | ||
- | dc | + | String json_string |
- | cs = Pin(2, Pin.OUT) | + | |
- | rst = Pin(5, Pin.OUT) | + | deserializeJson(json_doc, json_string); |
+ | String w_city = json_doc[" | ||
+ | int w_temp = json_doc[" | ||
+ | int w_temp_feels = json_doc[" | ||
+ | int w_humidity = json_doc[" | ||
+ | float w_wind = json_doc[" | ||
+ | String w_pod = json_doc[" | ||
+ | int w_code = int(json_doc[" | ||
- | spi = SPI(1, baudrate=40000000, polarity=0, phase=0) | + | String w_pic; |
- | tft = TFT_GREEN(128, 160, spi, dc, cs, rst, rotate=0) | + | if (w_code <= 233) w_pic = " |
- | tft.initr(tft.BGR) # tft.initr(tft.RGB) #Если вместо синего цвета отображается красный, | + | else if ((w_code >= 300 && w_code <= 520) || w_code |
+ | else if (w_code >= 521 && w_code <= 600) w_pic = " | ||
+ | else if (w_code >= 601 && w_code <= 622) w_pic = " | ||
+ | else if (w_code >= 623 && w_code <= 751) w_pic = " | ||
+ | else if (w_code == 800) w_pic = " | ||
+ | else if (w_code >= 801 && w_code <=802) w_pic = " | ||
+ | else if (w_code == 803) w_pic = " | ||
+ | else if (w_code == 804) w_pic = " | ||
+ | String w_pic_temp; | ||
+ | if (w_temp > 0) w_pic_temp = " | ||
+ | else w_pic_temp = " | ||
+ | |||
+ | unsigned int font_color = tft.color565(33, | ||
+ | unsigned int font_color2 = tft.color565(8, | ||
- | data = {' | + | tft.fillScreen(ST77XX_WHITE); |
- | wCity = data[' | + | tft.setTextColor(font_color); |
- | wTemp = round(data[' | + | |
- | wTempFeels = data[' | + | |
- | wHumidity = data[' | + | |
- | wWind = data[' | + | |
- | pod = data[' | + | reader.drawBMP("/ |
+ | reader.drawBMP("/ | ||
- | wCode = int(data[' | + | tft.setTextSize(4); |
+ | tft.setCursor(30, | ||
+ | tft.print(w_temp); | ||
- | if wCode <= 233: | + | tft.setTextColor(font_color2); |
- | wPic = ' | + | |
- | elif (wCode >= 300 and wCode <= 520) or wCode == 522: | + | |
- | wPic = ' | + | |
- | elif wCode in (521, 600): | + | |
- | wPic = ' | + | |
- | elif wCode >= 601 and wCode <= 622: | + | |
- | wPic = ' | + | |
- | elif wCode >= 623 and wCode <= 751: | + | } |
- | wPic = ' | + | |
- | elif wCode == 800: | + | |
- | wPic = ' | + | |
- | elif wCode in (801, 802): | + | |
- | wPic = ' | + | |
- | elif wCode == 803: | + | |
- | wPic = ' | + | |
- | elif wCode == 804: | + | |
- | wPic = ' | + | |
- | if (wTemp > 0): | + | void loop() { |
- | | + | } |
- | else: | + | |
- | wTempPic = ' | + | |
- | FontColor = tft.rgbcolor(33, | ||
- | FontColor2 = tft.rgbcolor(8, | ||
- | |||
- | |||
- | tft.clear(tft.rgbcolor(255, | ||
- | |||
- | |||
- | tft.text(1, | ||
- | |||
- | tft.draw_bmp(34, | ||
- | tft.draw_bmp(5, | ||
- | |||
- | tft.text(30, | ||
- | |||
- | tft.text(5, | ||
- | tft.text(5, | ||
- | tft.text(5, | ||
</ | </ | ||
Строка 104: | Строка 104: | ||
Первым делом извлекаем из структуры нужные нам данные. А именно: | Первым делом извлекаем из структуры нужные нам данные. А именно: | ||
- | Название города записываем в переменную | + | Название города записываем в переменную |
- | < | + | < |
- | wCity = data['data'][0]['city_name'] | + | |
</ | </ | ||
- | Текущую температуру записываем в переменную | + | Текущую температуру записываем в переменную |
- | < | + | < |
- | wTemp = round(data['data'][0]['temp']) | + | int w_temp |
</ | </ | ||
- | Ощущение температуры записываем в переменную | + | Ощущение температуры записываем в переменную |
- | < | + | < |
- | wTempFeels | + | int w_temp_feels |
</ | </ | ||
- | Влажность в % записываем в переменную | + | Влажность в % записываем в переменную |
- | < | + | < |
- | wHumidity | + | int w_humidity |
</ | </ | ||
- | Скорость ветра в метрах в секунду записываем в переменную | + | Скорость ветра в метрах в секунду записываем в переменную |
- | < | + | < |
- | wWind = data['data'][0]['wind_spd'] | + | float w_wind |
</ | </ | ||
- | Текущее время суток записываем в переменную | + | Текущее время суток записываем в переменную |
- | < | + | < |
- | pod = data['data'][0]['pod'] | + | |
</ | </ | ||
- | Сервис weatherbit.io среди прочих данных о погоде сообщает код текущей погоды. Это коды, которые используются именно этим сервисом. По ним можно понять какую иконку погоды нужно отобразить. [[https:// | + | Сервис weatherbit.io среди прочих данных о погоде сообщает код текущей погоды. Это коды, которые используются именно этим сервисом. По ним можно понять какую иконку погоды нужно отобразить. [[https:// |
- | < | + | < |
- | wCode = int(data['data'][0]['weather']['code']) | + | int w_code |
</ | </ | ||
- | Сервис поддерживает очень большое количество иконок у нас столько нет. У нас всего 18 погодных иконок— 9 дневных и 9 ночных. Поэтому нам нужно настроить соответствие кодов из сервиса нашим иконкам. Например несколько видов дождя, которые обозначаются разными кодами, | + | Сервис поддерживает очень большое количество иконок у нас столько нет. У нас всего 18 погодных иконок — 9 дневных и 9 ночных. Поэтому нам нужно настроить соответствие кодов из сервиса нашим иконкам. Например несколько видов дождя, которые обозначаются разными кодами, |
- | < | + | < |
- | if wCode <= 233: | + | |
- | wPic = '11' | + | |
- | elif (wCode >= 300 and wCode <= 520) or wCode == 522: | + | else if ((w_code |
- | wPic = '09' | + | |
- | elif wCode in (521, 600): | + | else if (w_code |
- | wPic = '10' | + | else if (w_code |
- | elif wCode >= 601 and wCode <= 622: | + | else if (w_code |
- | wPic = '13' | + | else if (w_code >= 801 && w_code <=802) w_pic = "02"; |
- | elif wCode >= 623 and wCode <= 751: | + | else if (w_code |
- | wPic = '50' | + | else if (w_code |
- | elif wCode == 800: | + | |
- | wPic = '01' | + | |
- | elif wCode in (801, 802): | + | |
- | wPic = '02' | + | |
- | elif wCode == 803: | + | |
- | wPic = '03' | + | |
- | elif wCode == 804: | + | |
- | wPic = '04' | + | |
</ | </ | ||
Для отображения иконки термометра на дисплее нужно определить положительная сейчас температура или отрицательная. Если температура ниже нуля, то будем отображать " | Для отображения иконки термометра на дисплее нужно определить положительная сейчас температура или отрицательная. Если температура ниже нуля, то будем отображать " | ||
- | < | + | < |
- | if (wTemp > 0): | + | |
- | wTempPic | + | |
- | else: | + | else w_pic_temp |
- | wTempPic | + | |
</ | </ | ||
Определяем цвета для шрифтов. Один из них будет использоваться для отображения названия города и температуры, | Определяем цвета для шрифтов. Один из них будет использоваться для отображения названия города и температуры, | ||
- | < | + | < |
- | FontColor | + | |
- | FontColor2 | + | |
</ | </ | ||
Закрашиваем весь дисплей белым | Закрашиваем весь дисплей белым | ||
- | < | + | < |
- | tft.clear(tft.rgbcolor(255, | + | tft.fillScreen(ST77XX_WHITE); |
</ | </ | ||
- | |||
Выводим на дисплей название города | Выводим на дисплей название города | ||
- | < | + | < |
- | tft.text(1,1,wCity, font.terminalfont, | + | tft.setTextColor(font_color); |
+ | tft.setTextSize(2); | ||
+ | tft.setCursor(5, 1); | ||
+ | tft.print(w_city); | ||
</ | </ | ||
Рисуем иконки: | Рисуем иконки: | ||
- | < | + | < |
- | tft.draw_bmp(34, | + | |
- | tft.draw_bmp(5,70,'/w/' | + | |
</ | </ | ||
Выводим текущую температуру | Выводим текущую температуру | ||
- | < | + | < |
- | tft.text(30,75, str(wTemp), font.terminalfont, | + | tft.setTextSize(4); |
+ | tft.setCursor(30, 75); | ||
+ | tft.print(w_temp); | ||
</ | </ | ||
Выводим дополнительные данные: | Выводим дополнительные данные: | ||
- | < | + | < |
- | tft.text(5,120," | + | tft.setTextColor(font_color2); |
- | tft.text(5,128," | + | tft.setTextSize(1); |
- | tft.text(5,136,"Wind: " + str(wWind) + " | + | tft.setCursor(5, 120); |
+ | tft.print(" | ||
+ | tft.setCursor(5, 130); | ||
+ | tft.print(" | ||
+ | tft.setCursor(5, 140); | ||
+ | tft.print("Wind: " + String(w_wind) + " | ||
</ | </ |