TFT eSPI OpenWeathe

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
vojta_1
Příspěvky: 37
Registrován: 14 úno 2020, 23:20
Reputation: 0

TFT eSPI OpenWeathe

Příspěvek od vojta_1 » 06 kvě 2021, 14:39

Zdravím, postavil jsem si meteorologickou stanici na displeji 2,8 TFT ILI9341 a ESP8266 ze stránek https://github.com/Bodmer/OpenWeather , výhoda je v tom že jede na OpenWeather client tím pádem api klíč je prozatím zadarmo po celí rok, ale mám problém s kterým bych potřeboval pomoc, v originálu jsou hodiny bez sekund , já sekundy dodal ,ale stojí, rozjedou se zrovna když se aktualizuje počasí a pak se zas zastaví a hodiny jedou, nevím jestli je problém v Time.h a nebo hlavním kódu, zkoušel jsem jsem všechno možné a nic
Dále jsem chtěl vedle hodin wifi rssi jako graf, nemám na to zkoušel jsem do kódu všechno možné a zase nic.
Vzhled stanice jsem trochu pozměnil vypadá to dobře, zatím dík za každou radu.
Tady je celý kod:





Kód: Vybrat vše

#include <SD.h>

//  Example from OpenWeather library: https://github.com/Bodmer/OpenWeather
//  Adapted by Bodmer to use the TFT_eSPI library:  https://github.com/Bodmer/TFT_eSPI

//  This sketch is compatible with the ESP8266 and ESP32

//                           >>>  IMPORTANT  <<<
//         Modify setup in All_Settings.h tab to configure your location etc

//                >>>  EVEN MORE IMPORTANT TO PREVENT CRASHES <<<
//>>>>>>  For ESP8266 set SPIFFS to at least 2Mbytes before uploading files  <<<<<<

//  ESP8266/ESP32 pin connections to the TFT are defined in the TFT_eSPI library.

//  Original by Daniel Eichhorn, see license at end of file.

//#define SERIAL_MESSAGES // For serial output weather reports
//#define SCREEN_SERVER   // For dumping screen shots from TFT
//#define RANDOM_LOCATION // Test only, selects random weather location every refresh
//#define FORMAT_SPIFFS   // Wipe SPIFFS and all files!

// This sketch uses font files created from the Noto family of fonts as bitmaps
// generated from these fonts may be freely distributed:
// https://www.google.com/get/noto/

// A processing sketch to create new fonts can be found in the Tools folder of TFT_eSPI
// https://github.com/Bodmer/TFT_eSPI/tree/master/Tools/Create_Smooth_Font/Create_font
// New fonts can be generated to include language specific characters. The Noto family
// of fonts has an extensive character set coverage.

// Json streaming parser (do not use IDE library manager version) to use is here:
// https://github.com/Bodmer/JSON_Decoder

#define AA_FONT_SMALL "fonts/NotoSansBold15" // 15 point sans serif bold
#define AA_FONT_LARGE "fonts/NotoSansBold36" // 36 point sans serif bold
/***************************************************************************************
**                         Načtěte knihovny a nastavení
***************************************************************************************/
#include <Arduino.h>

#include <SPI.h>
#include <TFT_eSPI.h> // https://github.com/Bodmer/TFT_eSPI

// Additional functions
#include "GfxUi.h"          // Attached to this sketch
#include "SPIFFS_Support.h" // Attached to this sketch

#ifdef ESP8266
  #include <ESP8266WiFi.h>
#else
  #include <WiFi.h>
#endif


// check All_Settings.h for adapting to your needs
#include "All_Settings.h"

#include <JSON_Decoder.h> // https://github.com/Bodmer/JSON_Decoder

#include <OpenWeather.h>  // Latest here: https://github.com/Bodmer/OpenWeather

#include "NTP_Time.h"     // Attached to this sketch, see that tab for library needs

/***************************************************************************************
**                      Definujte globály a instance třídy
***************************************************************************************/

TFT_eSPI tft = TFT_eSPI();             // Invoke custom library

OW_Weather ow;      // Weather forecast library instance

OW_current *current; // Pointers to structs that temporarily holds weather data
OW_hourly  *hourly;  // Not used
OW_daily   *daily;

boolean booted = true;

GfxUi ui = GfxUi(&tft); // Jpeg and bmpDraw functions TODO: pull outside of a class

long lastDownloadUpdate = millis();

/***************************************************************************************
**                          Deklarovat prototypy
***************************************************************************************/
void updateData();
void drawProgress(uint8_t percentage, String text);
void drawTime();
void drawCurrentWeather();
void drawForecast();
void drawForecastDetail(uint16_t x, uint16_t y, uint8_t dayIndex);
const char* getMeteoconIcon(uint16_t id, bool today);
void drawAstronomy();
void drawSeparator(uint16_t y);
void fillSegment(int x, int y, int start_angle, int sub_angle, int r, unsigned int colour);
String strDate(time_t unixTime);
String strTime(time_t unixTime);
void printWeather(void);
int leftOffset(String text, String sub);
int rightOffset(String text, String sub);
int splitIndex(String text);

/***************************************************************************************
**                         Nastavení
***************************************************************************************/
void setup() {
  Serial.begin(250000);

  tft.begin();
  tft.fillScreen(TFT_BLACK);

  SPIFFS.begin();
  listFiles();

  // Enable if you want to erase SPIFFS, this takes some time!
  // then disable and reload sketch to avoid reformatting on every boot!
  #ifdef FORMAT_SPIFFS
    tft.setTextDatum(BC_DATUM); // Bottom Centre datum
    tft.drawString("Formatting SPIFFS, so wait!", 120, 195); SPIFFS.format();
  #endif

  // Draw splash screen
  if (SPIFFS.exists("/splash/OpenWeather.jpg")   == true) ui.drawJpeg("/splash/OpenWeather.jpg",   0, 40);

  delay(2000);

  // Clear bottom section of screen
  tft.fillRect(0, 206, 240, 320 - 206, TFT_BLACK);

  tft.loadFont(AA_FONT_SMALL);
  tft.setTextDatum(BC_DATUM); // Bottom Centre datum
  tft.setTextColor(TFT_LIGHTGREY, TFT_BLACK);

  tft.drawString("Meteorologicka stanice", 120, 260);
  tft.drawString("Vojta", 120, 280);

  tft.setTextColor(TFT_YELLOW, TFT_BLACK);

  delay(2000);

  tft.fillRect(0, 206, 240, 320 - 206, TFT_BLACK);

  tft.drawString("Pripojeni k WiFi ...", 120, 240);
  tft.setTextPadding(240); // Pad next drawString() text to full width to over-write old text

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println();

  tft.setTextDatum(BC_DATUM);
  tft.setTextPadding(240); // Pad next drawString() text to full width to over-write old text
  tft.drawString(" ", 120, 220);  // Clear line above using set padding width
  tft.drawString("Nacitani udaju o pocasi...", 120, 240);

  // Fetch the time
  udp.begin(localPort);
  syncTime();

  tft.unloadFont();

  ow.partialDataSet(true); // Collect a subset of the data available
}

/***************************************************************************************
**                          Loop
***************************************************************************************/
void loop() {

  // Check if we should update weather information
  if (booted || (millis() - lastDownloadUpdate > 1000UL * UPDATE_INTERVAL_SECS))
  {
    updateData();
    lastDownloadUpdate = millis();
  }

  // If minute has changed then request new time from NTP server
  if (booted || minute() != lastMinute)
  {
    // Update displayed time first as we may have to wait for a response
    drawTime();
    lastMinute = minute();

    // Request and synchronise the local clock
    syncTime();

    #ifdef SCREEN_SERVER
      screenServer();
    #endif
  }

  booted = false;
}

/***************************************************************************************
**                   Načtěte údaje o počasí a aktualizujte obrazovku   
***************************************************************************************/
// Update the Internet based information and update screen
void updateData() {
  // booted = true;  // Test only
  // booted = false; // Test only

  tft.loadFont(AA_FONT_SMALL);

  if (booted) drawProgress(20, "Aktualizace casu ...");
  else fillSegment(22, 22, 0, (int) (20 * 3.6), 16, TFT_NAVY);

  if (booted) drawProgress(50, "Aktualizace podminek...");
  else fillSegment(22, 22, 0, (int) (50 * 3.6), 16, TFT_NAVY);

  // Create the structures that hold the retrieved weather
  current = new OW_current;
  daily =   new OW_daily;
  hourly =  new OW_hourly;

#ifdef RANDOM_LOCATION // Randomly choose a place on Earth to test icons etc
  String latitude = "";
  latitude = (random(180) - 90);
  String longitude = "";
  longitude = (random(360) - 180);
  Serial.print("Lat = "); Serial.print(latitude);
  Serial.print(", CZ = "); Serial.println(longitude);
#endif

  //On the ESP8266 (only) the library by default uses BearSSL, another option is to use AXTLS
  //For problems with ESP8266 stability, use AXTLS by adding a false parameter thus       vvvvv
  //ow.getForecast(current, hourly, daily, api_key, latitude, longitude, units, language, false);

  bool parsed = ow.getForecast(current, hourly, daily, api_key, latitude, longitude, units, language);

  if (parsed) Serial.println("Data points received");
  else Serial.println("Failed to get data points");

  Serial.print("Free heap = "); Serial.println(ESP.getFreeHeap(), DEC);

  printWeather(); // For debug, turn on output with #define SERIAL_MESSAGES

  if (booted)
  {
    drawProgress(100, "Hotovo ...");
    delay(2000);
    tft.fillScreen(TFT_BLACK);
  }
  else
  {
    fillSegment(22, 22, 0, 360, 16, TFT_NAVY);
    fillSegment(22, 22, 0, 360, 22, TFT_BLACK);
  }

  if (parsed)
  {
    drawCurrentWeather();
    drawForecast();
    drawAstronomy();

    tft.unloadFont();

    // Update the temperature here so we don't need to keep
    // loading and unloading font which takes time
    tft.loadFont(AA_FONT_LARGE);
    tft.setTextDatum(TR_DATUM);
    tft.setTextColor(TFT_YELLOW, TFT_BLACK);

    // Font ASCII code 0xB0 is a degree symbol, but o used instead in small font
    tft.setTextPadding(tft.textWidth(" -88")); // Max width of values

    String weatherText = "";
    weatherText = (int16_t) current->temp;  // Make it integer temperature
    tft.drawString(weatherText, 215, 95); //  + "°" symbol is big... use o in small font
  }
  else
  {
    Serial.println("Failed to get weather");
  }

  // Delete to free up space
  delete current;
  delete hourly;
  delete daily;

  tft.unloadFont();
}

/***************************************************************************************
**                          Aktualizujte ukazatel průběhu
***************************************************************************************/
void drawProgress(uint8_t percentage, String text) {
  tft.setTextDatum(BC_DATUM);
  tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  tft.setTextPadding(240);
  tft.drawString(text, 120, 260);

  ui.drawProgressBar(10, 269, 240 - 20, 15, percentage, TFT_WHITE, TFT_BLUE);

  tft.setTextPadding(0);
}

/***************************************************************************************
**                          Nakreslete číslice hodin
***************************************************************************************/
void drawTime() {
  tft.loadFont(AA_FONT_LARGE);

  // Convert UTC to local time, returns zone code in tz1_Code, e.g "GMT"
  time_t local_time = TIMEZONE.toLocal(now(), &tz1_Code);

  String timeNow = "";

  if (hour(local_time) < 10) timeNow += "0";
  timeNow += hour(local_time);
  timeNow += ":";
  if (minute(local_time) < 10) timeNow += "0";
  timeNow += minute(local_time) ;
  timeNow += ":";
  if (second(local_time) < 10) timeNow += "0";
  timeNow += second(local_time) ;
  
  
  tft.setTextDatum(BC_DATUM);
  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  tft.setTextPadding(tft.textWidth(" 44:44 "));  // String width + margin
  tft.drawString(timeNow, 120, 53);

  drawSeparator(51);

  tft.setTextPadding(0);

  tft.unloadFont();
}

/***************************************************************************************
**                          Nakreslete aktuální počasí
***************************************************************************************/
void drawCurrentWeather() {
  String date = "Havirov   " + strDate(current->dt);
  String weatherText = "None";

  tft.setTextDatum(BC_DATUM);
  tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  tft.setTextPadding(tft.textWidth(" Updated: Mmm 44 44:44 "));  // String width + margin
  tft.drawString(date, 120, 16);

  String weatherIcon = "";

  String currentSummary = current->main;
  currentSummary.toLowerCase();

  weatherIcon = getMeteoconIcon(current->id, true);

  //uint32_t dt = millis();
  ui.drawBmp("/icon/" + weatherIcon + ".bmp", 0, 53);
  //Serial.print("Icon draw time = "); Serial.println(millis()-dt);

  // Weather Text
  if (language == "en")
    weatherText = current->main;
  else
    weatherText = current->description;

  tft.setTextDatum(BR_DATUM);
  tft.setTextColor(TFT_ORANGE, TFT_BLACK);

  int splitPoint = 0;
  int xpos = 235;
  splitPoint =  splitIndex(weatherText);

  tft.setTextPadding(xpos - 100);  // xpos - icon width
  if (splitPoint) tft.drawString(weatherText.substring(0, splitPoint), xpos, 69);
  else tft.drawString(" ", xpos, 69);
  tft.drawString(weatherText.substring(splitPoint), xpos, 86);

  tft.setTextColor(TFT_YELLOW, TFT_BLACK);
  tft.setTextDatum(TR_DATUM);
  tft.setTextPadding(0);
  if (units == "metric") tft.drawString("°C", 237, 95);
  else  tft.drawString("°F", 237, 95);

  //V aktualizaci Data () byly přidány velké číslice teploty, aby se sem uložilo vyměnitelné písmo
 
  tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  weatherText = (uint16_t)current->wind_speed;

  if (units == "metric") weatherText += " m/s";
  else weatherText += " mph";

  tft.setTextDatum(TC_DATUM);
  tft.setTextPadding(tft.textWidth("888 m/s")); // Max string length?
  tft.drawString(weatherText, 124, 63);

  if (units == "imperial")
  {
    weatherText = current->pressure * 0.02953;
    weatherText += " in";
  }
  else
  {
    weatherText = (uint16_t)current->pressure;
    weatherText += " hPa";
  }

  tft.setTextDatum(TR_DATUM);
  tft.setTextPadding(tft.textWidth(" 8888hPa")); // Max string length?
  tft.drawString(weatherText, 230, 136);

  int windAngle = (current->wind_deg + 22.5) / 45;
  if (windAngle > 7) windAngle = 0;
  String wind[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW" };
  ui.drawBmp("/wind/" + wind[windAngle] + ".bmp", 101, 86);

  drawSeparator(153);

  tft.setTextDatum(TL_DATUM); // Reset datum to normal
  tft.setTextPadding(0);      // Reset padding width to none
}

/***************************************************************************************
**                          Nakreslete 4 sloupce prognózy
***************************************************************************************/
// draws the three forecast columns
void drawForecast() {
  int8_t dayIndex = 1;

  drawForecastDetail(  8, 171, dayIndex++);
  drawForecastDetail( 66, 171, dayIndex++); // was 95
  drawForecastDetail(124, 171, dayIndex++); // was 180
  drawForecastDetail(182, 171, dayIndex  ); // was 180
  drawSeparator(171 + 69);
}

/***************************************************************************************
**                          Nakreslete 1 sloupec prognózy na x, y
***************************************************************************************/
// helper for the forecast columns
void drawForecastDetail(uint16_t x, uint16_t y, uint8_t dayIndex) {

  if (dayIndex >= MAX_DAYS) return;

  String day  = shortDOW[weekday(TIMEZONE.toLocal(daily->dt[dayIndex], &tz1_Code))];
  day.toUpperCase();

  tft.setTextDatum(BC_DATUM);

  tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  tft.setTextPadding(tft.textWidth("WWW"));
  tft.drawString(day, x + 25, y);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextPadding(tft.textWidth("-88   -88"));
  String highTemp = String(daily->temp_max[dayIndex], 0);
  String lowTemp  = String(daily->temp_min[dayIndex], 0);
  tft.drawString(highTemp + "|" + lowTemp, x + 25, y + 17);

  String weatherIcon = getMeteoconIcon(daily->id[dayIndex], false);

  ui.drawBmp("/icon50/" + weatherIcon + ".bmp", x, y + 18);

  tft.setTextPadding(0); // Reset padding width to none
}

/***************************************************************************************
**             Nakreslete východ / západ slunce, měsíc, oblačnost a vlhkost
***************************************************************************************/
void drawAstronomy() {

  tft.setTextDatum(BC_DATUM);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextPadding(tft.textWidth(" Last qtr "));

  time_t local_time = TIMEZONE.toLocal(current->dt, &tz1_Code);
  uint16_t y = year(local_time);
  uint8_t  m = month(local_time);
  uint8_t  d = day(local_time);
  uint8_t  h = hour(local_time);
  int      ip;
  uint8_t icon = moon_phase(y, m, d, h, &ip);

  tft.drawString(moonPhase[ip], 120, 319);
  ui.drawBmp("/moon/moonphase_L" + String(icon) + ".bmp", 120 - 30, 318 - 16 - 60);

  tft.setTextDatum(BC_DATUM);
  tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  tft.setTextPadding(0); // Reset padding width to none
  tft.drawString(sunStr, 40, 270);

  tft.setTextDatum(BR_DATUM);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextPadding(tft.textWidth(" 88:88 "));

  String rising = strTime(current->sunrise) + " ";
  int dt = rightOffset(rising, ":"); // Draw relative to colon to them aligned
  tft.drawString(rising, 40 + dt, 290);

  String setting = strTime(current->sunset) + " ";
  dt = rightOffset(setting, ":");
  tft.drawString(setting, 40 + dt, 305);

  tft.setTextDatum(BC_DATUM);
  tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  tft.drawString(cloudStr, 195, 260);

  String cloudCover = "";
  cloudCover += current->clouds;
  cloudCover += "%";

  tft.setTextDatum(BR_DATUM);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextPadding(tft.textWidth(" 100%"));
  tft.drawString(cloudCover, 210, 277);

  tft.setTextDatum(BC_DATUM);
  tft.setTextColor(TFT_ORANGE, TFT_BLACK);
  tft.drawString(humidityStr, 195, 300 - 2);

  String humidity = "";
  humidity += current->humidity;
  humidity += "%";

  tft.setTextDatum(BR_DATUM);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextPadding(tft.textWidth("100%"));
  tft.drawString(humidity, 210, 315);

  tft.setTextPadding(0); // Reset padding width to none
}

/***************************************************************************************
**               Získejte název souboru ikony z indexového čísla
***************************************************************************************/
const char* getMeteoconIcon(uint16_t id, bool today)
{
  if ( today && id/100 == 8 && (current->dt < current->sunrise || current->dt > current->sunset)) id += 1000; 

  if (id/100 == 2) return "thunderstorm";
  if (id/100 == 3) return "drizzle";
  if (id/100 == 4) return "unknown";
  if (id == 500) return "lightRain";
  else if (id == 511) return "sleet";
  else if (id/100 == 5) return "rain";
  if (id >= 611 && id <= 616) return "sleet";
  else if (id/100 == 6) return "snow";
  if (id/100 == 7) return "fog";
  if (id == 800) return "clear-day";
  if (id == 801) return "partly-cloudy-day";
  if (id == 802) return "cloudy";
  if (id == 803) return "cloudy";
  if (id == 804) return "cloudy";
  if (id == 1800) return "clear-night";
  if (id == 1801) return "partly-cloudy-night";
  if (id == 1802) return "cloudy";
  if (id == 1803) return "cloudy";
  if (id == 1804) return "cloudy";

  return "unknown";
}

/***************************************************************************************
**                 Nakreslete oddělovací čáru části obrazovky
***************************************************************************************/
// if you don't want separators, comment out the tft-line
void drawSeparator(uint16_t y) {
  tft.drawFastHLine(10, y, 240 - 2 * 10, 0x4228);
}

/***************************************************************************************
**                Určete místo, kde se má čára rozdělit
***************************************************************************************/
// determine the "space" split point in a long string
int splitIndex(String text)
{
  uint16_t index = 0;
  while ( (text.indexOf(' ', index) >= 0) && ( index <= text.length() / 2 ) ) {
    index = text.indexOf(' ', index) + 1;
  }
  if (index) index--;
  return index;
}

/***************************************************************************************
**                      Odsazení na pravé straně znaku
***************************************************************************************/
// Vypočítá deltu souřadnic od konce textu Řetězec po začátek podřetězce obsaženého v tomto textu
// Lze použít k vertikálnímu zarovnání textu, takže například dvojtečka „:“ v časové hodnotě je vždy
// vykreslení ve stejném bodě na obrazovce bez ohledu na různé proporcionální šířky znaků,
// lze také použít k zarovnání desetinných míst pro úhledné formátování 
int rightOffset(String text, String sub)
{
  int index = text.indexOf(sub);
  return tft.textWidth(text.substring(index));
}

/***************************************************************************************
**                          Posunutí levé strany k znaku
***************************************************************************************/
// Vypočítá deltu souřadnic od začátku textu String po začátek podřetězce obsaženého v tomto textu
// Lze použít ke svislému zarovnání textu doleva, například dvojtečka „:“ v časové hodnotě je vždy
// vykreslení ve stejném bodě na obrazovce bez ohledu na různé proporcionální šířky znaků,
// lze také použít k zarovnání desetinných míst pro úhledné formátování 

int leftOffset(String text, String sub)
{
  int index = text.indexOf(sub);
  return tft.textWidth(text.substring(0, index));
}

/***************************************************************************************
**                          Nakreslete kruhový segment
***************************************************************************************/
// Nakreslete segment kruhu, vycentrovaný na x, y s definovaným počátečním_úhlem a podřízeným pod_úhlem
// Úhly jsou definovány ve směru hodinových ručiček s 0 nahoře
// Segment má poloměr r a je vykreslen v definované barvě
// Lze použít pro výsečové grafy atd., V tomto náčrtu se používá pro směr větru 

#define DEG2RAD 0.0174532925 // Degrees to Radians conversion factor
#define INC 2 // Minimum segment subtended angle and plotting angle increment (in degrees)
void fillSegment(int x, int y, int start_angle, int sub_angle, int r, unsigned int colour)
{
  // Calculate first pair of coordinates for segment start
  float sx = cos((start_angle - 90) * DEG2RAD);
  float sy = sin((start_angle - 90) * DEG2RAD);
  uint16_t x1 = sx * r + x;
  uint16_t y1 = sy * r + y;

  // Draw colour blocks every INC degrees
  for (int i = start_angle; i < start_angle + sub_angle; i += INC) {

    // Calculate pair of coordinates for segment end
    int x2 = cos((i + 1 - 90) * DEG2RAD) * r + x;
    int y2 = sin((i + 1 - 90) * DEG2RAD) * r + y;

    tft.fillTriangle(x1, y1, x2, y2, x, y, colour);

    // Copy segment end to segment start for next segment
    x1 = x2;
    y1 = y2;
  }
}

/***************************************************************************************
**                Vytiskněte informace o počasí na sériový monitor
***************************************************************************************/
void printWeather(void)
{
#ifdef SERIAL_MESSAGES
  Serial.println("Weather from OpenWeather\n");

  Serial.println("############### Current weather ###############\n");
  Serial.print("dt (time)          : "); Serial.println(strDate(current->dt));
  Serial.print("sunrise            : "); Serial.println(strDate(current->sunrise));
  Serial.print("sunset             : "); Serial.println(strDate(current->sunset));
  Serial.print("main               : "); Serial.println(current->main);
  Serial.print("tepl               : "); Serial.println(current->temp);
  Serial.print("vlhkost           : "); Serial.println(current->humidity);
  Serial.print("tlak           : "); Serial.println(current->pressure);
  Serial.print("vítr_speed         : "); Serial.println(current->wind_speed);
  Serial.print("vítr_deg           : "); Serial.println(current->wind_deg);
  Serial.print("mraky             : "); Serial.println(current->clouds);
  Serial.print("id                 : "); Serial.println(current->id);
  Serial.println();

  Serial.println("###############  Daily weather  ###############\n");
  Serial.println();

  for (int i = 0; i < 5; i++)
  {
    Serial.print("dt (time)          : "); Serial.println(strDate(daily->dt[i]));
    Serial.print("id                 : "); Serial.println(daily->id[i]);
    Serial.print("tepl_max           : "); Serial.println(daily->temp_max[i]);
    Serial.print("tepl_min           : "); Serial.println(daily->temp_min[i]);
    Serial.println();
  }

#endif
}
/***************************************************************************************
**             Převést čas Unixu na časový řetězec „místní datum“ „12:34“
***************************************************************************************/
String strTime(time_t unixTime)
{
  time_t local_time = TIMEZONE.toLocal(unixTime, &tz1_Code);

  String localTime = "";

  if (hour(local_time) < 10) localTime += "0";
  localTime += hour(local_time);
  localTime += ":";
  if (minute(local_time) < 10) localTime += "0";
  localTime += minute(local_time);

  return localTime;
}

/***************************************************************************************
 Převést čas Unixu na místní datum + řetězec času „16. října 17:18“, končí novým řádkem  
***************************************************************************************/
String strDate(time_t unixTime)
{
  time_t local_time = TIMEZONE.toLocal(unixTime, &tz1_Code);

  String localDate = "";
  
  localDate += day(local_time);
  localDate += ". ";
  localDate += monthStr(month(local_time));
  localDate += "  "; 
  localDate += dayStr(weekday(local_time));
  localDate += "";
  
  return localDate;
}

Přílohy
meteorologickou stanici1 .jpg
meteorologickou stanici1 .jpg (35.88 KiB) Zobrazeno 10747 x
TFT_eSPI_OpenWeather.zip
(695.45 KiB) Staženo 153 x

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: TFT eSPI OpenWeathe

Příspěvek od pavel1tu » 06 kvě 2021, 15:57

No, chová se to podle kodu.

Pokud chceš čas updatovat po 1s, budeš si to muset nastavit, aby se updatoval po 1 s.
Zatím se tam čas dle mne updatuje po 1min.

PS: jak to jen bylo řečeno ve filmy Rozpuštěný a vypuštěný .... ""Hledej šmudlo"
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: TFT eSPI OpenWeathe

Příspěvek od kiRRow » 06 kvě 2021, 16:02

Kód: Vybrat vše

if (booted || minute() != lastMinute) // tady ti to kontroluje jestli se to spouští, nebo se změnila minuta
  {
    // Update displayed time first as we may have to wait for a response
    drawTime(); // tady ti to vykresluje čas
    lastMinute = minute(); // tady se aktualizuje promenná s minutou

    // Request and synchronise the local clock
    syncTime(); // synchronizace času

    #ifdef SCREEN_SERVER
      screenServer(); // vykreslení - podmíněno definicí SCREEN_SERVER, což nemáš ...
    #endif
  }
V podstatě musíš udělat to, že nebudeš kontrolovat minuty, ale vteřiny. Aby se ti pak každou vteřinu nesychronizoval čas, tak syncTime spustíš jen pod podmínkou že sekundy jsou 0. Pak se ti každou vteřinu vykreslí nový čas, ale synchronizace nastane jen v XX:XX:00 čili každou minutu.
edit : teda pokud není třeba spouštět ten syncTime pokaždé, pak není třeba ho obalovat podmínkou

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: TFT eSPI OpenWeathe

Příspěvek od pavel1tu » 06 kvě 2021, 17:19

kiRRow píše:
06 kvě 2021, 16:02
V podstatě musíš udělat to, že nebudeš kontrolovat minuty, ale vteřiny. Aby se ti pak každou vteřinu nesychronizoval čas, tak syncTime spustíš jen pod podmínkou že sekundy jsou 0. Pak se ti každou vteřinu vykreslí nový čas, ale synchronizace nastane jen v XX:XX:00 čili každou minutu.
edit : teda pokud není třeba spouštět ten syncTime pokaždé, pak není třeba ho obalovat podmínkou
Pokud někdo umí v OpenSource projektu jako první přepsat jméno autora za svoje,měl by zvládnout i to ostatní.

Je to taková - slušnost - ponechat odkaz na autora zdroje a pokud dělám nějaké úpravy, nepíšu se jako autor, ale jako ten co to upravoval.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

vojta_1
Příspěvky: 37
Registrován: 14 úno 2020, 23:20
Reputation: 0

Re: TFT eSPI OpenWeathe

Příspěvek od vojta_1 » 06 kvě 2021, 17:47

Dík, už to jede akorát při každé nové sekundě mi zároveň bliknou cele hodiny, na to příjdem ... :roll:

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: TFT eSPI OpenWeathe

Příspěvek od pavel1tu » 06 kvě 2021, 20:09

vojta_1 píše:
06 kvě 2021, 17:47
Dík, už to jede akorát při každé nové sekundě mi zároveň bliknou cele hodiny, na to příjdem ... :roll:
Předělej to aby se měnily jen ty sekundy a ne celý čas, ne ?
- po minutě nech vykreslit celý čas
- po vteřině (nová podmínka + nová funkce) jen vteřiny

nebo
- ve funkci vykreslení času když budou sekundy "0" udělej klasicky
tft.drawString(timeNow, 120, 53);
- jenak vykresli jen sekundy, pozici X budeš muset otestovat aby se to trefilo
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
gilhad
Příspěvky: 778
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: TFT eSPI OpenWeathe

Příspěvek od gilhad » 06 kvě 2021, 21:39

pavel1tu píše:
06 kvě 2021, 15:57
PS: jak to jen bylo řečeno ve filmy Rozpuštěný a vypuštěný .... ""Hledej šmudlo"
Nerad bych se mylil, ale jsem si celkem jist, ze to rikala Vilma ve "Vrazda v salonnim coupe"

commar
Příspěvky: 31
Registrován: 26 úno 2019, 15:20
Reputation: 0

Re: TFT eSPI OpenWeathe

Příspěvek od commar » 07 kvě 2021, 14:11

Ahoj,
já si postavil toto: https://github.com/ThingPulse/esp8266-w ... tion-color
a jedou tam i sekundy, tak se inspiruj tam.

vojta_1
Příspěvky: 37
Registrován: 14 úno 2020, 23:20
Reputation: 0

Re: TFT eSPI OpenWeathe

Příspěvek od vojta_1 » 07 kvě 2021, 15:49

Jo to jsem měl taky, ale je tam malo informací,ale dobré, to mě napadlo jako první,ale jede to na jiném kodu tam s editaci nemám problem, ten to kodu moc neznám trrochu rozlišne příkazy atd,zatím jsem to nerozjel podívam se na to večer,musím dodělat auto.

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: TFT eSPI OpenWeathe

Příspěvek od pavel1tu » 07 kvě 2021, 15:49

gilhad píše:
06 kvě 2021, 21:39
Nerad bych se mylil, ale jsem si celkem jist, ze to rikala Vilma ve "Vrazda v salonnim coupe"
Tak jsi mne docela dostal, teď opravdu nevím ...
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 15 hostů