Just a very quick post for a small weather display based on an ESP32 and an ili9341 2.2" TFT display.
The main reason for posting is that the code for calculating the location of the wind direction indicator on the compass rose may come in handy for someone.
This uses various sensors provided by my Home Assistant instance.
ESPHome YAML:
esphome:
name: wind
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
spi:
clk_pin: GPIO18
mosi_pin: GPIO23
miso_pin: GPIO19
ota:
password: "8aebd6eb0427929de523046d6773d66e"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Wind Fallback Hotspot"
password: "sh1mZkRvphaJ"
captive_portal:
text_sensor:
- platform: homeassistant
name: "Current Temp"
entity_id: sensor.weather_station_temperature
id: temp
- platform: homeassistant
name: "Current Wind Dir"
entity_id: sensor.wind_direction
id: wind_dir
- platform: homeassistant
name: "Current Wind Speed"
entity_id: sensor.wind_speed
id: wind_speed
- platform: homeassistant
name: "Named Wind Dir"
entity_id: sensor.named_wind_direction
id: named_dir
- platform: homeassistant
name: "Rain since 12am"
entity_id: sensor.rain_accumulation
id: total_rain
- platform: homeassistant
name: "Rain since 12am"
entity_id: sensor.atmospheric_pressure_msl
id: pressure
font:
- file: "fonts/calibri.ttf"
id: calibri_20
size: 20
- file: "fonts/calibri.ttf"
id: calibri_25
size: 25
- file: "fonts/calibri.ttf"
id: calibri_40
size: 40
time:
- platform: homeassistant
id: my_time
display:
- platform: ili9341
rotation: 0
model: TFT 2.4
dc_pin: GPIO21
cs_pin: GPIO22
led_pin: GPIO12
reset_pin: GPIO17
lambda: |-
// Colours - used for visiual indication of wind strength
auto red = Color(255, 0, 0);
auto green = Color(0, 255, 0);
auto light_blue = Color(135, 237, 232);
auto orange = Color(255, 170, 43);
auto white = Color(255, 255, 255);
auto purple = Color(97, 15, 219);
// Convert wind direction to int
int dir = atoi(id(wind_dir).state.c_str());
// Convert wind speed to float
float speed = atof(id(wind_speed).state.c_str());
// Calculate xy position to plot wind indicator
int x = 120 + (90 * (cos((dir-90)*PI/180)));
int y = 160 + (90 * (sin((dir-90)*PI/180)));
// Weather data
it.strftime(5, 10, id(calibri_25), TextAlign::TOP_LEFT, "%H:%M", id(my_time).now());
it.printf(235, 10, id(calibri_25), TextAlign::TOP_RIGHT, "%s °C", id(temp).state.c_str());
it.printf(5, 310, id(calibri_20), TextAlign::BOTTOM_LEFT, "%s mm", id(total_rain).state.c_str());
it.printf(235, 310, id(calibri_20), TextAlign::BOTTOM_RIGHT, "%s hPa", id(pressure).state.c_str());
// Compass rose
it.circle(120, 160, 90);
it.print(120, 60, id(calibri_20), red, TextAlign::BOTTOM_CENTER, "N");
it.print(120, 260, id(calibri_20), red, TextAlign::TOP_CENTER, "S");
it.print(20, 160, id(calibri_20), red, TextAlign::CENTER_RIGHT, "W");
it.print(220, 160, id(calibri_20), red, TextAlign::CENTER_LEFT, "E");
// Wind pointer
if (speed<=11) { it.filled_circle(x, y, 7, light_blue); }
else {
if (speed>11 && speed<=30) { it.filled_circle(x, y, 7, green); }
else {
if (speed>30 && speed<=60) { it.filled_circle(x, y, 7, orange); }
else {
if (speed>60) { it.filled_circle(x, y, 7, red); }
} } }
// Wind details
it.printf(120, 140, id(calibri_25), TextAlign::BOTTOM_CENTER, "%s", id(named_dir).state.c_str());
if (speed<10) { it.printf(120, 185, id(calibri_40), TextAlign::BOTTOM_CENTER, "%2.1f", speed); }
else { it.printf(120, 185, id(calibri_40), TextAlign::BOTTOM_CENTER, "%2.0f", round(speed));
}
it.print(120, 185, id(calibri_20), TextAlign::TOP_CENTER, "km/h");