Arduino Polska Forum

Pełna wersja: LCD 2x16 wyświetlanie danych z API
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Stron: 1 2
Witajcie,
potrzebuję Waszej pomocy przy swoim pierwszym projekcie z Wemos d1 mini. Napisałem kod internetowego zegarka, który oprócz czasu wyświetla też aktualne dane o zachorowaniach na COVID-19 w kraju oraz moim województwie. Zatrzymałem się jednak w pewnym punkcie i ciężko mi ruszyć dalej, żeby w pełni zakończyć projekt.

- dane w drugiej linii wyświetlają się poprawnie, ale poprzez zagłębienie w funkcje if i millis tekst mruga wraz z sekundami zegara, macie jakiś pomysł jak to rozwiązać? Pojawił się też problem synchronizacji danych z API, jeśli dodam delay co 5 min zegar również się zatrzymuje.

- chciałbym do zegara dodać buzzer, który będzie informował o zmianie danych pobranych z API. nie wiem jednak jak ugryźć temat, aby przekazać esp informacje ze dane w api się zmieniły


Z góry dziękuję Wam za pomoc.

Kod:
/*
*Wiring:
*5v -> 5v
*Gnd -> Gnd
*SCA -> SCA
*SCL -> SCL
*
*/

unsigned long prevMillis = 0;
unsigned long curMillis;

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiUdp.h>
#include <String.h>
#include <Wire.h>
#include <ArduinoJson.h>
#include <WiFiClientSecure.h>
#include <SSD1306.h>
#include <SSD1306Wire.h>
#include <NTPClient.h>
#include <Time.h>
#include <TimeLib.h>
#include <Timezone.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); //or try 0x3f

// Define NTP properties
#define NTP_OFFSET 60 * 60         // In seconds
#define NTP_INTERVAL 60 * 1000     // In miliseconds
#define NTP_ADDRESS "pool.ntp.org" // change this to whatever pool is closest (see ntp.org)

// Set up the NTP UDP client
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL);

const char *ssid = "XXXX"; // insert your own ssid such as BTHub4-9X99
const char *password = "XXXX"; // and your wifi password

String date; //create the string for the date which will be printed on the lcd screen below
String t;    // create the string for the time

const char *months[] = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"};


void clearLCDLine(int line)
{
    lcd.setCursor(0, line);
    for (int n = 0; n < 16; n++) // For 2x16 LCD write - 16
    {
        lcd.print(" ");
    }
}

void setup()
{
    Serial.begin(115200); // most ESP-01's use 115200 but this could vary. Included for serial monitor debugging
    timeClient.begin();   // Start the NTP UDP client

    ///////////////////// The section below is to connect the esp8266 to your wifi

    int cursorPosition = 0;
    lcd.begin();
    lcd.backlight();
    Wire.begin();
    lcd.print("Polacz");

    lcd.setCursor(0, 0);
    lcd.print("Polacz");
    lcd.setCursor(0, 1);
    lcd.print(ssid);

    // Connect to wifi
    Serial.println("");
    Serial.print("Laczenie z ");
    Serial.print(ssid);

    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.print("Polaczono z WiFi ");
    Serial.print(WiFi.localIP());
    Serial.println("");

    delay(1000);
    ///////////////////////|end wifi connection set up
}

void loop()
{
    //////////////////////// The first part of the loop is for the internet clock

    if (WiFi.status() == WL_CONNECTED) //Check WiFi connection status
    {
        HTTPClient http;
        http.begin("http://api.apify.com/v2/key-value-stores/3Po6TV7wTht4vIEid/records/LATEST?disableRedirect=true");
        int httpCode = http.GET();

        date = ""; // clear the variables
        t = "";

        // update the NTP client and get the UNIX UTC timestamp
        timeClient.update();
        unsigned long epochTime = timeClient.getEpochTime();

        // convert received time stamp to time_t object
        time_t local, utc;
        utc = epochTime;

        // Then convert the UTC UNIX timestamp to local time
        //TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2};  //UTC - 5 hours - change this as needed
        // TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -60};   //UTC - 6 hours - change this as needed
        // Timezone usEastern(usEDT, usEST);
        // local = usEastern.toLocal(utc);

        TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 60}; //Central European Summer Time
        TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 0};   //Central European Standard Time
        Timezone CE(CEST, CET);
        local = CE.toLocal(utc);

        // now format the Time variables into strings with proper names for month, day etc
        date += day(local);
        date += "/";
        date += months[month(local) - 1];
        date += "/";
        date += year(local);

        // format the time to 12-hour format with AM/PM and add seconds. t (time) is made up of the variables below which are then printed as a string
        t += hour(local);
        t += ":";
        if (minute(local) < 10) // add a zero if minute is under 10
            t += "0";
        t += minute(local);
        // t += ":";
//        if (second(local) < 10)    hide seconds for my lcd
//            t += "0";
//        t += second(local);
        //t += ampm[isPM(local)];

        // Display the date and time
        Serial.println("");
        Serial.print("Local date: ");
        Serial.print(date);
        Serial.println("");
        Serial.print("Local time: ");
        Serial.print(t);

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(t);
        lcd.setCursor(6, 0);
        lcd.print(date);

        curMillis = millis();
        if ((curMillis - prevMillis) >= 5500)
        {
            {

                if (httpCode > 0)
                {

                    const size_t capacity = JSON_ARRAY_SIZE(16) + 16 * JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 1080;

                    DynamicJsonDocument doc(capacity);

                    deserializeJson(doc, http.getString());

                    JsonArray infectedByRegion = doc["infectedByRegion"];

                    // Parameters
                    int infected = doc["infected"];
                    int deceased = doc["deceased"];

                    JsonObject infectedByRegion_14 = infectedByRegion[14];
                    //const char *infectedByRegion_14_region = infectedByRegion_14["region"];       // "wielkopolskie"
                    int infectedByRegion_14_infectedCount = infectedByRegion_14["infectedCount"];
                    int infectedByRegion_14_deceasedCount = infectedByRegion_14["deceasedCount"];

                    //PRINT
                    curMillis = millis();
                    if ((curMillis - prevMillis) >= 10000)
                    {
                        lcd.setCursor(0, 1);
                        lcd.print("Polska COVID-19");
                    }

                    if ((curMillis - prevMillis) >= 19500)
                    {
                        clearLCDLine(1);
                    }

                    if ((curMillis - prevMillis) >= 20000)
                    {
                        lcd.setCursor(0, 1);
                        lcd.print("Chorych:");
                        lcd.setCursor(9, 1);
                        lcd.print(infected, DEC);
                    }

                    if ((curMillis - prevMillis) >= 29500)
                    {
                        clearLCDLine(1);
                    }

                    if ((curMillis - prevMillis) >= 30000)
                    {
                        lcd.setCursor(0, 1);
                        lcd.print("Zgonow:");
                        lcd.setCursor(8, 1);
                        lcd.print(deceased, DEC);
                    }

                    if ((curMillis - prevMillis) >= 39500)
                    {
                        clearLCDLine(1);
                    }

                    if ((curMillis - prevMillis) >= 40000)
                    {
                        lcd.setCursor(0, 1);
                        lcd.print("WIELKOPOLSKIE");
                    }

                    if ((curMillis - prevMillis) >= 49500)
                    {
                        clearLCDLine(1);
                    }

                    if ((curMillis - prevMillis) >= 50000)
                    {
                        lcd.setCursor(0, 1);
                        lcd.print("Chorych:");
                        lcd.setCursor(9, 1);
                        lcd.print(infectedByRegion_14_infectedCount, DEC);
                    }

                    if ((curMillis - prevMillis) >= 59500)
                    {
                        clearLCDLine(1);
                    }

                    if ((curMillis - prevMillis) >= 60000)
                    {
                        lcd.setCursor(0, 1);
                        lcd.print("Zgonow:");
                        lcd.setCursor(8, 1);
                        lcd.print(infectedByRegion_14_deceasedCount, DEC);
                    }

                    if ((curMillis - prevMillis) >= 69500)
                    {
                        prevMillis = millis();
                    }
                }
                http.end(); //Close connection
                           
                // Delay
                //delay(300000); how to delay ask to json
            }
        }
    }

    else // this part is a step to attempt to connect to wifi again if disconnected
    {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Polacz");

        //display.display();
        WiFi.begin(ssid, password);
        //display.drawString(0, 24, "Connected.");

        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("Polacz.");

        delay(1000);
    }

    delay(1000); //Send a request to update every 10 sec (= 10,000 ms)
} //end void loop
Mruga bo czyscisz ekran, Funkcja "lcd.clear();" nie jest wskazana gdy chcemy bez mrugania....
(13-04-2020, 11:04)Miszka napisał(a): [ -> ]...nie wiem jednak jak ugryźć temat, aby przekazać esp informacje ze dane w api się zmieniły...

Porównuj stare dane z nowymi i jeśli są inne, to znaczy że się zmieniły.
Jak zapisać stare dane. Zmienna jaką mam zadeklarowaną jest cały czas aktualizowana przez API.
if(zmienna != zmienna){
   
    zmienione dane

}else{

  zmienna bez zmian

}


To jest oczywiście błędne rozwiązanie. Prawidłowe na następnej stronie.
Robson
Czyli powinienem stworzyć np zmienna oldInfected i jeśli oldInfected != infected to załączy się buzzer. Na LCD wyświetlane oczywiście zmienna infected. A co przypisać do oldInfected?
a po co tworzyć zmienna?

jak tylko chcesz porównać czy są zmiany to wystarczy Infected != infected


Jak sa zmiany to włacz buzer i zmień na LCD... A jak nie ma zmian to nie trzeba zmieniać na LCD...
(13-04-2020, 18:38)Jarewa0606 napisał(a): [ -> ]Mruga bo czyscisz ekran,  Funkcja "lcd.clear();" nie jest wskazana  gdy chcemy bez mrugania....
Zastąpienie funkcji LCD.clear drukowaniem pustych miejsc nie rozwiązuje problemu. Masz jakiś pomysł? Może powinienem odseparować drukowanie godziny i tekstu, czyli dwóch linii wyświetlacza.
(13-04-2020, 21:14)Jarewa0606 napisał(a): [ -> ]a po co tworzyć zmienna?

jak tylko chcesz porównać czy są zmiany to wystarczy  Infected != infected


Jak sa zmiany to włacz buzer i zmień na LCD... A jak nie ma zmian to nie trzeba zmieniać na LCD...


Wychodzi brak znajomości podstaw C. Dziękuję Ci za pomoc ?y
Jedynie sensownym rązwiazaniem by nie czyscić ekranu jest formatowanie danych....
Stron: 1 2