I found an interesting code for LilyGO TTGO T5-4.7" and I would love if someone explained the code to me

So I found this code: GitHub - GraxCode/lilygo_t5_4.7_crypto: A crypto price widget for the LilyGO T5. It works just fine for my e-paper but I don´t know how it works. I would love if someone could explain the code to me so I can learn from it and build something like this myself in the future. Maybe the best way to help me would be to comment the code line by line.

#ifndef BOARD_HAS_PSRAM
#error "Please enable PSRAM !!!"
#endif
#define WIFI_OFF WIFI_MODE_NULL
#define WIFI_STA WIFI_MODE_STA

#define WHITE 0xFF
#define LGREY 0xBB
#define GREY 0x88
#define DGREY 0x44
#define BLACK 0x00

#include <Arduino.h>
#include <esp_task_wdt.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "epd_driver.h"
#include "esp_adc_cal.h"
#include <Wire.h>
#include <SPI.h>
#include <ArduinoJson.h>
#include <HTTPClient.h>
#include <WiFi.h>
#include <SPI.h>
#include <time.h>

#include "roboto8.h"
#include "roboto10.h"
#include "roboto12.h"
#include "roboto18.h"
#include "roboto18r.h"
#include "roboto24r.h"

#define BATT_PIN 36
enum alignment
{
    LEFT,
    RIGHT,
    CENTER
};

const char *ssid = "YOUR_SSID";
const char *password = "YOUR_PASSWRD";

/*
 * Keep this at 4. The long currency name is used for the api, so check the spelling.
 */
const int AMOUNT_CURR = 4;
const String currency_short[] = {"BTC", "ETH", "LTC", "XMR"};
const String currency_names[] = {"Bitcoin", "Ethereum", "Litecoin", "Monero"};

int currency_index;

uint8_t *framebuffer;
int vref = 1100;

int wifi_signal;

uint8_t start_wifi()
{
    Serial.println("Connecting to: " + String(ssid));
    IPAddress dns(8, 8, 8, 8);
    WiFi.disconnect();
    WiFi.mode(WIFI_STA); // switch off AP
    WiFi.setAutoConnect(true);
    WiFi.setAutoReconnect(true);
    WiFi.begin(ssid, password);
    if (WiFi.waitForConnectResult() != WL_CONNECTED)
    {
        Serial.println("STA: Failed!");
        WiFi.disconnect(false);
        delay(500);
        WiFi.begin(ssid, password);
    }
    if (WiFi.status() == WL_CONNECTED)
    {
        wifi_signal = WiFi.RSSI(); // Get Wifi Signal strength now, because the WiFi will be turned off to save power!
        Serial.println("WiFi connected as " + WiFi.localIP().toString());
    }
    else
        Serial.println("WiFi connection failed: " + String(WiFi.status()));
    return WiFi.status();
}

void stop_wifi()
{
    WiFi.disconnect();
    WiFi.mode(WIFI_OFF);
}

float c_price = -1.0f;
float c_price_btc = -1.0f;
float c_price_24h = 0.0f;
float c_price_1h = 0.0f;

int c_rank = 0;

double c_cap = -1.0;
double c_vol = -1.0;

/**
 * Read https://api.coinstats.app API data into fields
 **/
bool decode_web_data(WiFiClient &json)
{
    DynamicJsonDocument doc(4 * 1024);
    DeserializationError error = deserializeJson(doc, json);
    if (error)
    {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(error.c_str());
        return false;
    }

    JsonObject coin = doc["coin"];
    c_price = coin["price"].as<float>();
    c_price_btc = coin["priceBtc"].as<float>();
    c_rank = coin["rank"].as<int>();
    c_cap = coin["marketCap"].as<double>();
    c_vol = coin["volume"].as<double>();

    c_price_24h = coin["priceChange1d"].as<float>();
    c_price_1h = coin["priceChange1h"].as<float>();
    return true;
}

/**
 * https://api.coinstats.app certificate chain.
 **/
const char *root_ca = "-----BEGIN CERTIFICATE-----\r\nMIIFZzCCBE+gAwIBAgIQDTlrDyYrb/AxYW1KAPrBujANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIgQ0EgMUIxDzANBgNVBAMTBkFtYXpvbjAeFw0yMTAyMjgwMDAwMDBaFw0yMjAzMjkyMzU5NTlaMBgxFjAUBgNVBAMTDWNvaW5zdGF0cy5hcHAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6z+21LImyDsItMYKeGKIFUNFHdb4zys40Pn7Ge2MeZYYiV4zNC2bZXM35WFeYYMG6i6PSvk3+q3zQlJzdjAknAs7CnHicYECMqrnE57uIQynQhouCe6XAj+i4w4ze5NvZFj47Tpq24/jUBkljIt/6BlQMi90t4FBn1OFD7pddPV/hrgxRBeM3MWCydIiUF9yHuubhGqVBOKubQHWYXkaWFzzF8vswTfZ/nsZUzG1beAVrbHbRkKmjY+tlBVDmexox/GuYg71vO0e5TXQUP9Z0UhfBitq7YzjOjcel70jry2Q66ce3BaGmZXCcV1Wj8HqwrJvapL9JeUSXmxzmMH3VAgMBAAGjggJ9MIICeTAfBgNVHSMEGDAWgBRZpGYGUqB7lZI8o5QHJ5Z0W/k90DAdBgNVHQ4EFgQUXhZsTg172MLYrVNuKrC51fOakW0wKQYDVR0RBCIwIIINY29pbnN0YXRzLmFwcIIPKi5jb2luc3RhdHMuYXBwMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zY2ExYi5hbWF6b250cnVzdC5jb20vc2NhMWIuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDovL29jc3Auc2NhMWIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8vY3J0LnNjYTFiLmFtYXpvbnRydXN0LmNvbS9zY2ExYi5jcnQwDAYDVR0TAQH/BAIwADCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB2ACl5vvCeOTkh8FZzn2Old+W+V32cYAr4+U1dJlwlXceEAAABd+ZZXDQAAAQDAEcwRQIhAJ81JDwark4rNE554mChYn+UxT9FcXPKHCEfHpMEtK3OAiBPWDJ8kXekttFVZOtOtEcHfx8E4ZaoD6nz/TNwfluVvwB2ACJFRQdZVSRWlj+hL/H3bYbgIyZjrcBLf13Gg1xu4g8CAAABd+ZZXIQAAAQDAEcwRQIhAICPYbJ1FqYG10jBi6m0gLub7iP8Y78psDvY4IOleOU1AiBVXEnDsCGxPzTc0cEaXTTX5LaJUsPIDCUXAyVt6QL/KDANBgkqhkiG9w0BAQsFAAOCAQEAawPBNUkrC9BCbtQLCC9ZDpKPTphU6d7MkMTRtazi2Vi/lzYSw3zCDV1Y8O1iv5OeyTmf8AidUr7B3OYlVbhWzlenY7ox9asbfRjI/s72ZuvdV08M7oybAOFxLjQ/UgXKAHNeEExsNv/NEhxROxEvWmLoPKaxr9BAknEN0o9owkdiugbo7E5gJiGtW3hG8ysYvhQ4f2XgwVzRS9xK6rEnM6p+cmPdjM7OPK2oPV8fcBwE/b6VotbA8UfjLJGH9eLJ2Kmrx/l1rQegIn+0pS6e822KXzxFYchKeEkYXqrkWEMwWaqh1yI1yitkTLg0Lf7LZl1PEpxoByVHb9oIJovxIg==\r\n-----END CERTIFICATE-----\r\n-----BEGIN CERTIFICATE-----\r\nMIIESTCCAzGgAwIBAgITBntQXCplJ7wevi2i0ZmY7bibLDANBgkqhkiG9w0BAQsFADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1MTAyMTIyMjQzNFoXDTQwMTAyMTIyMjQzNFowRjELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENBIDFCMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCThZn3c68asg3Wuw6MLAd5tES6BIoSMzoKcG5blPVo+sDORrMd4f2AbnZcMzPa43j4wNxhplty6aUKk4T1qe9BOwKFjwK6zmxxLVYo7bHViXsPlJ6qOMpFge5blDP+18x+B26A0piiQOuPkfyDyeR4xQghfj66Yo19V+emU3nazfvpFA+ROz6WoVmB5x+F2pV8xeKNR7u6azDdU5YVX1TawprmxRC1+WsAYmz6qP+z8ArDITC2FMVy2fw0IjKOtEXc/VfmtTFch5+AfGYMGMqqvJ6LcXiAhqG5TI+Dr0RtM88k+8XUBCeQ8IGKuANaL7TiItKZYxK1MMuTJtV9IblAgMBAAGjggE7MIIBNzASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUWaRmBlKge5WSPKOUByeWdFv5PdAwHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NybC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IBAQAfsaEKwn17DjAbi/Die0etn+PEgfY/I6s8NLWkxGAOUfW2o+vVowNARRVjaIGdrhAfeWHkZI6q2pI0x/IJYmymmcWaZaW/2R7DvQDtxCkFkVaxUeHvENm6IyqVhf6Q5oN12kDSrJozzx7I7tHjhBK7V5XoTyS4NU4EhSyzGgj2x6axDd1hHRjblEpJ80LoiXlmUDzputBXyO5mkcrplcVvlIJiWmKjrDn2zzKxDX5nwvkskpIjYlJcrQu4iCX1/YwZ1yNqF9LryjlilphHCACiHbhIRnGfN8j8KLDVmWyTYMk8V+6j0LI4+4zFh2upqGMQHL3VFVFWBek6vCDWhB/b\r\n-----END CERTIFICATE-----\r\n-----BEGIN CERTIFICATE-----\r\nMIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5\r\n-----END CERTIFICATE-----";

bool read_web_data()
{
    HTTPClient http;
    String cur = currency_names[currency_index];
    cur.toLowerCase();
    String uri = "/public/v1/coins/" + cur + "?currency=EUR";
    http.begin("https://api.coinstats.app" + uri, root_ca);
    int httpCode = http.GET();
    bool success = false;
    if (httpCode == HTTP_CODE_OK)
    {
        if (decode_web_data(http.getStream()))
            success = true;
        else
            Serial.println("Web data decoding failed");
    }
    else
    {
        Serial.printf("Connection to API failed, error: %s\r\n", http.errorToString(httpCode).c_str());
    }
    http.end();
    return success;
}

void draw_str(const GFXfont font, const String txt, int x, int y, alignment align)
{
    const char *string = (char *)txt.c_str();
    int x1, y1;
    int w, h;
    int xx = x, yy = y;
    get_text_bounds(&font, string, &xx, &yy, &x1, &y1, &w, &h, NULL);
    if (align == RIGHT)
        x = x - w;
    if (align == CENTER)
        x = x - w / 2;
    int cursor_y = y + h;
    writeln(&font, string, &x, &cursor_y, framebuffer);
}

void start_deep_sleep()
{
    epd_poweroff_all();
    esp_sleep_enable_timer_wakeup(1000L * 60000L * 5L); // sleep 5 min (API limit)

    Serial.println("Starting deep-sleep period...");

    esp_deep_sleep_start();
}

void draw_framebuf(bool clear_buf)
{
    epd_draw_grayscale_image(epd_full_screen(), framebuffer);
    if (clear_buf)
    {
        memset(framebuffer, 0xFF, EPD_WIDTH * EPD_HEIGHT / 2);
    }
}

void correct_adc_ref_volt()
{
    esp_adc_cal_characteristics_t adc_chars;
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adc_chars);
    if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF)
    {
        Serial.printf("eFuse Vref:%u mV\r\n", adc_chars.vref);
        vref = adc_chars.vref;
    }
}
void setup()
{
    Serial.begin(115200);

    correct_adc_ref_volt();
    epd_init();

    framebuffer = (uint8_t *)ps_calloc(sizeof(uint8_t), EPD_WIDTH * EPD_HEIGHT / 2);
    if (!framebuffer)
    {
        Serial.println("alloc memory failed.");
        while (1)
            ;
    }
    memset(framebuffer, 0xFF, EPD_WIDTH * EPD_HEIGHT / 2);

    epd_poweron();
    epd_clear();

    uint16_t v = analogRead(BATT_PIN);
    float battery_voltage = ((float)v / 4095.0) * 2.0 * 3.3 * (vref / 1000.0);
    String voltage = String(battery_voltage) + "V";
    Serial.println(voltage);

    int x_pos = (int)(EPD_WIDTH * 0.02f);
    int y_pos = (int)(EPD_HEIGHT * 0.96f);

    draw_str(Roboto8, (char *)voltage.c_str(), x_pos, y_pos, LEFT);

    x_pos = (int)(EPD_WIDTH * 0.98f);

    draw_str(Roboto8, "https://github.com/GraxCode - v1.0", x_pos, y_pos, RIGHT);

    x_pos = (int)(EPD_WIDTH * 0.5f);
    y_pos = (int)(EPD_HEIGHT * 0.45f);
    draw_str(Roboto24R, "Connecting to " + String(ssid), x_pos, y_pos, CENTER);

    draw_framebuf(true);
    if (start_wifi() != WL_CONNECTED)
    {
        epd_clear();
        draw_str(Roboto24R, "WLAN failed. Check credentials.", x_pos, y_pos, CENTER);
    }
    else
    {
        epd_clear();
        for (currency_index = 0; currency_index < AMOUNT_CURR; currency_index++)
        {
            int y_off = (currency_index / float(AMOUNT_CURR)) * EPD_HEIGHT;
            int y_off_end = ((currency_index + 1) / float(AMOUNT_CURR)) * EPD_HEIGHT;

            epd_draw_line(0, y_off_end, EPD_WIDTH, y_off_end, BLACK, framebuffer);

            x_pos = (int)(EPD_WIDTH * 0.02f);
            y_pos = (int)(EPD_HEIGHT * 0.04f);

            draw_str(Roboto24R, (char *)currency_names[currency_index].c_str(), x_pos, y_off + y_pos, LEFT);
            y_pos = (int)(EPD_HEIGHT * 0.15f);
            draw_str(Roboto18R, (char *)currency_short[currency_index].c_str(), x_pos, y_off + y_pos, LEFT);
            if (!read_web_data())
            {
                x_pos = (int)(EPD_WIDTH * 0.5f);
                y_pos = (int)(EPD_HEIGHT * 0.1f);
                draw_str(Roboto18R, "Wifi read failed", x_pos, (y_off + y_off_end) / 2, CENTER);
            }
            else
            {
                x_pos = (int)(EPD_WIDTH * 0.30f);
                y_pos = (int)(EPD_HEIGHT * 0.05f);
                draw_str(Roboto18R, String(c_price, 2) + " €", x_pos, y_off + y_pos, LEFT);
                y_pos = (int)(EPD_HEIGHT * 0.125f);
                draw_str(Roboto12, "= " + String(c_price_btc, 8) + " BTC", x_pos, y_off + y_pos, LEFT);
                y_pos = (int)(EPD_HEIGHT * 0.2f);
                draw_str(Roboto8, "RANK #" + String(c_rank), x_pos, y_off + y_pos, LEFT);

                x_pos = (int)(EPD_WIDTH * 0.59f);
                y_pos = (int)(EPD_HEIGHT * 0.05f);
                draw_str(abs(c_price_24h) > 10 ? Roboto18R : Roboto18, String(c_price_24h, 2) + "%", x_pos, y_off + y_pos, LEFT);
                y_pos = (int)(EPD_HEIGHT * 0.11f);
                draw_str(Roboto12, "24h CHANGE", x_pos, y_off + y_pos, LEFT);
                y_pos = (int)(EPD_HEIGHT * 0.2f);
                draw_str(Roboto8, String(c_cap / 1000000.0f, 2) + " M CAP", x_pos, y_off + y_pos, LEFT);

                x_pos = (int)(EPD_WIDTH * 0.94f);
                y_pos = (int)(EPD_HEIGHT * 0.05f);
                draw_str(abs(c_price_1h) > 5 ? Roboto18R : Roboto18, String(c_price_1h, 2) + "%", x_pos, y_off + y_pos, RIGHT);
                y_pos = (int)(EPD_HEIGHT * 0.11f);
                draw_str(Roboto12, "1h CHANGE", x_pos, y_off + y_pos, RIGHT);
                y_pos = (int)(EPD_HEIGHT * 0.2f);
                draw_str(Roboto8, String(c_vol / 1000000.0f, 2) + " M VOL", x_pos, y_off + y_pos, RIGHT);

                // min to 100%, put in range 0 - 255
                int intensity = (int)(255.0f - (min(abs(c_price_1h) + 2.0f, 10.0f) / 10.0f) * 255.0f);
                int left_x = (int)(EPD_WIDTH * 0.96f);
                int right_x = (int)(EPD_WIDTH * 0.99f);
                int mid_x = (left_x + right_x) / 2;

                int low_y_up = y_off + (int)(EPD_HEIGHT * 0.08f);
                int high_y_up = y_off + (int)(EPD_HEIGHT * 0.04f);
                int low_y_down = y_off + (int)(EPD_HEIGHT * (0.25f - 0.08f));
                int high_y_down = y_off + (int)(EPD_HEIGHT * (0.25f - 0.04f));

                if (c_price_1h > 0)
                {
                    epd_fill_triangle(left_x, low_y_up, right_x, low_y_up, mid_x, high_y_up, intensity, framebuffer);
                }
                else
                {
                    epd_fill_triangle(left_x, low_y_down, right_x, low_y_down, mid_x, high_y_down, intensity, framebuffer);
                }
                epd_draw_triangle(left_x, low_y_up, right_x, low_y_up, mid_x, high_y_up, BLACK, framebuffer);
                epd_draw_triangle(left_x, low_y_down, right_x, low_y_down, mid_x, high_y_down, BLACK, framebuffer);
            }
            draw_framebuf(true);
        }
    }
    stop_wifi();
    start_deep_sleep();
}

void loop()
{
}

Perhaps if you told us which parts you don't understand, otherwise don't expect anyone to add comments to over 300 lines of code

I understand that you don´t want to write 300 comments and that´s totally reasonable, but if you could please comment as much as possible for me to learn from it that would be awesome. Thanks

Again, which parts don't you understand, or maybe, which parts do you understand ?

Perhaps if you explained what the code did it would help everyone, including you

I understand that there are #includes, which are libraries. Then the "SSID" and "password" which I just change to my WiFi settings. The rest is a mystery to me. Like i understand a few commands of the rest but I don´t get the whole picture if you know what I mean. I get that the code takes data of crypto prices from some websites through ArduinoJson but that´s unfortunately all.

// Read data from the web server
bool read_web_data()
{
    HTTPClient HTTP;
    // currency_names: {"Bitcoin", "Ethereum", "Litecoin", "Monero"};
    String cur = currency_names[currency_index];
    cur.toLowerCase();  // Force to lowercase
    String uri = "/public/v1/coins/" + cur + "?currency=EUR";
    // Get a quote (in euros) for the specified cryptocurrency  
   // "https://api.coinstats.app/public/v1/coins/bitcoin?currency=EUR"
    // Pass a list of root certificates so the identity of the server
    // can be validated.
    http.begin("https://api.coinstats.app" + uri, root_ca);
    int httpCode = http.GET();
    bool success = false;
    if (httpCode == HTTP_CODE_OK)
    {
        if (decode_web_data(http.getStream()))
            success = true;
        else
            Serial.println("Web data decoding failed");
    }
    else
    {
        Serial.printf("Connection to API failed, error: %s\r\n", http.errorToString(httpCode).c_str());
    }
    http.end();
    return success;
}