diff --git a/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_FINAL/ESP8266_GOOGLEMAP_GPS_ILI9488_FINAL.ino b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_FINAL/ESP8266_GOOGLEMAP_GPS_ILI9488_FINAL.ino new file mode 100644 index 0000000..230b10e --- /dev/null +++ b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_FINAL/ESP8266_GOOGLEMAP_GPS_ILI9488_FINAL.ino @@ -0,0 +1,408 @@ +#define WIFI_SSID "" +#define PASSWORD "" + +#include "SPI.h" +#include +#include +#include +#include +#include +#include +#include "List_SPIFFS.h" + +// Include SPIFFS +#define FS_NO_GLOBALS +#include + +// Include WiFi and http client +#ifdef ESP8266 + #include + #include +#else + #include "SPIFFS.h" // Required for ESP32 only + #include + #include +#endif + + +#define BUTTONSIZE 50 +#define PButtonFrame_X 20 +#define PButtonFrame_Y 240 +#define NButtonFrame_X 90 +#define NButtonFrame_Y 240 + +TFT_eSPI tft = TFT_eSPI(); // Invoke custom library +BearSSL::CertStore certStore; +BearSSL::WiFiClientSecure *client; + +const char * host = "maps.googleapis.com"; +const String defaultPath = "/maps/api/staticmap?center="; +const String API_KEY = ""; +const char * mapFile = "/map.jpg"; + +const long buttonInterval = 500; +const int maxZoomLevel = 21; +const int minZoomLevel = 1; + +static const int RXPin = 5, TXPin = 16; +static const uint32_t GPSBaud = 9600; + +const int offset = -8; // Pacific Standard Time +time_t prevDisplay = 0; +TinyGPSPlus gps; +SoftwareSerial ss(RXPin, TXPin); + +char timeBuffer[16]; +char dateBuffer[16]; +char zoomBuffer[10]; + +String prevCoarseLatitude, prevCoarseLongitude; +String latitude = ""; +String longitude = ""; +int zoomLevel = 17; + +long previousMillis = 0; +bool buttonAvailable = false; + +bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap) +{ + if ( y >= tft.height() ) return 0; + tft.pushImage(x, y, w, h, bitmap); + return 1; +} + +void setup() +{ + Serial.begin(115200); + ss.begin(GPSBaud); + + Serial.println("\n\n"); + + // Initialise SPIFFS + if (!SPIFFS.begin()) { + Serial.println("SPIFFS initialisation failed!"); + while (1) yield(); // Stay here twiddling thumbs waiting + } + Serial.println("\r\nInitialisation done."); + + // Initialise the TFT + tft.begin(); + tft.fillScreen(TFT_BLACK); + tft.setRotation(3); + uint16_t calData[5] = {277, 3614, 317, 3509, 1}; + tft.setTouch(calData); + initScreen(); + + TJpgDec.setJpgScale(1); + TJpgDec.setSwapBytes(true); + TJpgDec.setCallback(tft_output); + + WiFi.begin(WIFI_SSID, PASSWORD); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(); + + if(!hasCerts){ + return; + } + + listSPIFFS(); + menuScreen(); +} + +void loop() +{ + buttonEvent(); + GPSEvent(); +} + +bool hasCerts(){ + setClock(); // Required for X.509 validation + + int numCerts = certStore.initCertStore(SPIFFS, PSTR("/certs.idx"), PSTR("/certs.ar")); + Serial.printf("Number of CA certs read: %d\n", numCerts); + if (numCerts == 0) { + Serial.printf("No certs found. Did you run certs-from-mozilla.py and upload the SPIFFS directory before running?\n"); + return false; // Can't connect to anything w/o certs! + } + + client = new BearSSL::WiFiClientSecure(); + return true; +} + +// Set time via NTP, as required for x.509 validation +void setClock() { + configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov"); + + Serial.print("Waiting for NTP time sync: "); + time_t now = time(nullptr); + while (now < 8 * 3600 * 2) { + delay(500); + Serial.print("."); + now = time(nullptr); + } + Serial.println(""); + struct tm timeinfo; + gmtime_r(&now, &timeinfo); + Serial.print("Current time: "); + Serial.print(asctime(&timeinfo)); +} + +bool getStaticMapImage(const char *host, const char *path, String fileName){ + if(WiFi.status() != WL_CONNECTED){ + return false; + } + + int contentLength = 0; + int httpCode; + + + // Integrate the cert store with this connection + client->setCertStore(&certStore); + client->connect(host, 443); //HTTPS + + Serial.printf("Trying: %s:443...", host); + + if(!client->connected()){ + client->stop(); + Serial.printf("*** Can't connect. ***\n-------\n"); + return false; + } + + Serial.println("HTTPS Connected!"); + client->write("GET "); + client->write(path); + client->write(" HTTP/1.0\r\nHost: "); + client->write(host); + client->write("\r\nUser-Agent: ESP8266\r\n"); + client->write("\r\n"); + + while(client->connected()){ + String header = client-> readStringUntil('\n'); + if(header.startsWith(F("HTTP/1."))){ + httpCode = header.substring(9, 12).toInt(); + if(httpCode != 200){ + client->stop(); + return false; + } + } + + if(header.startsWith(F("Content-Length: "))){ + contentLength = header.substring(15).toInt(); + } + + if(header == F("\r")){ + break; + } + + } + + if(!(contentLength > 0)){ + client->stop(); + return false; + } + + fs::File f = SPIFFS.open(fileName, "w"); + if(!f){ + Serial.println(F("FILE OPEN FAILED")); + client->stop(); + return false; + } + + int remaining = contentLength; + int received; + uint8_t buff[512] = {0}; + + while(client->available() && remaining > 0){ + received = client->readBytes(buff, ((remaining > sizeof(buff)) ? sizeof(buff) : remaining)); + f.write(buff, received); + + if(remaining > 0){ + remaining -= received; + } + yield(); + } + + f.close(); + client->stop(); + Serial.println("DOWNLOAD END"); + return (remaining == 0 ? true : false); +} + +String getPath(){ + String newPath = defaultPath; + newPath += latitude; + newPath += ","; + newPath += longitude; + newPath += "&zoom="; + newPath += String(zoomLevel); + newPath += "&size=320x320"; + newPath += "&maptype=roadmap"; + newPath += "markers=color:red%7C"; + newPath += latitude; + newPath += ","; + newPath += longitude; + newPath += "&format=jpg-baseline"; + newPath += API_KEY; +} + +void GPSEvent() +{ + while (ss.available() > 0){ + bool isMapNeedUpdate = false; + + if (gps.encode(ss.read())){ + + int Year = gps.date.year(); + byte Month = gps.date.month(); + byte Day = gps.date.day(); + byte Hour = gps.time.hour(); + byte Minute = gps.time.minute(); + byte Second = gps.time.second(); + + setTime(Hour, Minute, Second, Day, Month, Year); + adjustTime(offset * SECS_PER_HOUR); + + if(gps.location.isValid()){ + tft.setTextDatum(TL_DATUM); + tft.setTextSize(1); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + + latitude = String(gps.location.lat(), 6); + tft.drawString(latitude, 0, 120, 4); + String coarseLatitude = String(gps.location.lat(), 3); + + if(coarseLatitude != prevCoarseLatitude){ + isMapNeedUpdate = true; + } + prevCoarseLatitude = coarseLatitude; + + longitude = String(gps.location.lng(), 6); + tft.drawString(longitude, 0, 150, 4); + String coarseLongitude = String(gps.location.lng(), 3); + + if(coarseLongitude != prevCoarseLongitude){ + isMapNeedUpdate = true; + } + prevCoarseLongitude = coarseLongitude; + + } + } + + if(timeStatus() != timeNotSet){ + if(now() != prevDisplay){ + prevDisplay = now(); + dateTimeDisplay(); + + if(isMapNeedUpdate){ + if(getStaticMapImage(host, getPath().c_str(), mapFile)){ + TJpgDec.drawFsJpg(160, 0, mapFile); + } + } + } + } + } + + if (millis() > 5000 && gps.charsProcessed() < 10) + { + Serial.println(F("No GPS detected: check wiring.")); + errorScreen(); + while(true); + } +} + +void initScreen(){ + tft.fillScreen(TFT_WHITE); + tft.setTextSize(1); + tft.setTextColor(TFT_RED, TFT_WHITE); + tft.setTextDatum(TC_DATUM); + tft.drawString("Waiting for GPS...", 240, 140, 4); +} + +void errorScreen(){ + tft.fillScreen(TFT_RED); + tft.setTextSize(1); + tft.setTextColor(TFT_WHITE, TFT_RED); + tft.setTextDatum(TC_DATUM); + tft.drawString("No GPS detected: Check Wiring!", 240, 140, 4); +} + +void dateTimeDisplay(){ + sprintf(timeBuffer, "%02u:%02u:%02u", hour(), minute(), second()); + tft.setTextSize(1); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.drawString(timeBuffer, 0, 30, 4); + + sprintf(dateBuffer, "%02u/%02u/%04u", month(), day(), year()); + tft.drawString(dateBuffer, 0, 60, 4); +} + +void menuScreen(){ + tft.fillScreen(TFT_BLACK); + plusBtn(); + negativeBtn(); + showingZoomLevel(); + TJpgDec.drawFsJpg(160, 0, mapFile); //previous saved image +} + +void plusBtn(){ + tft.fillRect(PButtonFrame_X, PButtonFrame_Y, BUTTONSIZE, BUTTONSIZE, TFT_GREEN); + tft.setTextColor(TFT_WHITE); + tft.setTextSize(2); + tft.setTextDatum(MC_DATUM); + tft.drawString("+", PButtonFrame_X + (BUTTONSIZE / 2) + 1, PButtonFrame_Y + (BUTTONSIZE / 2)); +} + +void negativeBtn(){ + tft.fillRect(NButtonFrame_X, NButtonFrame_Y, BUTTONSIZE, BUTTONSIZE, TFT_RED); + tft.setTextColor(TFT_WHITE); + tft.setTextSize(2); + tft.setTextDatum(MC_DATUM); + tft.drawString("-", NButtonFrame_X + (BUTTONSIZE / 2) + 1, NButtonFrame_Y + (BUTTONSIZE / 2)); +} + +void showingZoomLevel(){ + sprintf(zoomBuffer, "Zoom : %02d", zoomLevel); + + tft.setTextDatum(TL_DATUM); + tft.setTextSize(2); + tft.drawString(zoomBuffer, 20, 200); +} + +void buttonEvent(){ + uint16_t x, y; + unsigned long currentMillis = millis(); + if(currentMillis - previousMillis > buttonInterval){ + previousMillis = currentMillis; + buttonAvailable = false; + } + + if(tft.getTouch(&x, &y) && !buttonAvailable){ + if((x > PButtonFrame_X) && (x < (PButtonFrame_X + BUTTONSIZE))){ + if((y > PButtonFrame_Y) && (x < (PButtonFrame_Y + BUTTONSIZE))){ + buttonAvailable = true; + + zoomLevel++; + if(zoomLevel > maxZoomLevel){ + zoomLevel = maxZoomLevel; + } + } + } + + if((x > NButtonFrame_X) && (x < (NButtonFrame_X + BUTTONSIZE))){ + if((y > NButtonFrame_Y) && (x < (NButtonFrame_Y + BUTTONSIZE))){ + buttonAvailable = true; + + zoomLevel--; + if(zoomLevel < minZoomLevel){ + zoomLevel = minZoomLevel; + } + } + } + + showingZoomLevel(); + } +} diff --git a/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_FINAL/List_SPIFFS.h b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_FINAL/List_SPIFFS.h new file mode 100644 index 0000000..9ef1392 --- /dev/null +++ b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_FINAL/List_SPIFFS.h @@ -0,0 +1,87 @@ +/*************************************************************************************** +** Function name: listSPIFFS +** Description: Listing SPIFFS files +***************************************************************************************/ +#ifdef ESP8266 +void listSPIFFS(void) { + Serial.println(F("\r\nListing SPIFFS files:")); + + fs::Dir dir = SPIFFS.openDir("/"); // Root directory + + static const char line[] PROGMEM = "================================================="; + Serial.println(FPSTR(line)); + Serial.println(F(" File name Size")); + Serial.println(FPSTR(line)); + + while (dir.next()) { + String fileName = dir.fileName(); + Serial.print(fileName); + int spaces = 33 - fileName.length(); // Tabulate nicely + if (spaces < 1) spaces = 1; + while (spaces--) Serial.print(" "); + + fs::File f = dir.openFile("r"); + String fileSize = (String) f.size(); + spaces = 10 - fileSize.length(); // Tabulate nicely + if (spaces < 1) spaces = 1; + while (spaces--) Serial.print(" "); + Serial.println(fileSize + " bytes"); + } + + Serial.println(FPSTR(line)); + Serial.println(); + delay(1000); +} + +//==================================================================================== + +#elif defined ESP32 + +void listSPIFFS(void) { + Serial.println(F("\r\nListing SPIFFS files:")); + static const char line[] PROGMEM = "================================================="; + + Serial.println(FPSTR(line)); + Serial.println(F(" File name Size")); + Serial.println(FPSTR(line)); + + fs::File root = SPIFFS.open("/"); + if (!root) { + Serial.println(F("Failed to open directory")); + return; + } + if (!root.isDirectory()) { + Serial.println(F("Not a directory")); + return; + } + + fs::File file = root.openNextFile(); + while (file) { + + if (file.isDirectory()) { + Serial.print("DIR : "); + String fileName = file.name(); + Serial.print(fileName); + } else { + String fileName = file.name(); + Serial.print(" " + fileName); + // File path can be 31 characters maximum in SPIFFS + int spaces = 33 - fileName.length(); // Tabulate nicely + if (spaces < 1) spaces = 1; + while (spaces--) Serial.print(" "); + String fileSize = (String) file.size(); + spaces = 10 - fileSize.length(); // Tabulate nicely + if (spaces < 1) spaces = 1; + while (spaces--) Serial.print(" "); + Serial.println(fileSize + " bytes"); + } + + file = root.openNextFile(); + } + + Serial.println(FPSTR(line)); + Serial.println(); + delay(1000); +} + +#endif diff --git a/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_TOUCHCONTROLLER/ESP8266_GOOGLEMAP_GPS_ILI9488_TOUCHCONTROLLER.ino b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_TOUCHCONTROLLER/ESP8266_GOOGLEMAP_GPS_ILI9488_TOUCHCONTROLLER.ino new file mode 100644 index 0000000..4ead39e --- /dev/null +++ b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_TOUCHCONTROLLER/ESP8266_GOOGLEMAP_GPS_ILI9488_TOUCHCONTROLLER.ino @@ -0,0 +1,79 @@ +#include "FS.h" +#include +#include +TFT_eSPI tft = TFT_eSPI(); + +#define CALIBRATION_FILE "/calibrationData" + +void setup(void) { + uint16_t calibrationData[5]; + uint8_t calDataOK = 0; + + Serial.begin(115200); + Serial.println("starting"); + + tft.init(); + + tft.setRotation(3); + tft.fillScreen((0xFFFF)); + + tft.setCursor(20, 0, 2); + tft.setTextColor(TFT_BLACK, TFT_WHITE); tft.setTextSize(1); + tft.println("calibration run"); + + // check file system + if (!SPIFFS.begin()) { + Serial.println("formating file system"); + + SPIFFS.format(); + SPIFFS.begin(); + } + + SPIFFS.format(); //Always start calibration + + // check if calibration file exists + if (SPIFFS.exists(CALIBRATION_FILE)) { + File f = SPIFFS.open(CALIBRATION_FILE, "r"); + if (f) { + if (f.readBytes((char *)calibrationData, 14) == 14) + calDataOK = 1; + f.close(); + } + } + if (calDataOK) { + // calibration data valid + tft.setTouch(calibrationData); + } else { + // data not valid. recalibrate + tft.calibrateTouch(calibrationData, TFT_WHITE, TFT_RED, 15); + // store data + File f = SPIFFS.open(CALIBRATION_FILE, "w"); + if (f) { + f.write((const unsigned char *)calibrationData, 14); + f.close(); + } + + for(int i=0; i<5; i++){ + Serial.printf("%d,%d\n", i, calibrationData[i]); + } + } + + tft.fillScreen((0xFFFF)); + +} + +void loop() { + uint16_t x, y; + static uint16_t color; + + if (tft.getTouch(&x, &y)) { + + tft.setCursor(5, 5, 2); + tft.printf("x: %i ", x); + tft.setCursor(5, 20, 2); + tft.printf("y: %i ", y); + + tft.drawPixel(x, y, color); + color += 155; + } +} diff --git a/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE.ino b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE.ino new file mode 100644 index 0000000..2f1434d --- /dev/null +++ b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE.ino @@ -0,0 +1,201 @@ +#define WIFI_SSID "" +#define PASSWORD "" +#include +#include +#include + +// Include SPIFFS +#define FS_NO_GLOBALS +#include + +// Include WiFi and http client +#ifdef ESP8266 + #include + #include +#else + #include "SPIFFS.h" // Required for ESP32 only + #include + #include +#endif + +// Load tabs attached to this sketch +#include "List_SPIFFS.h" +#include "Web_Fetch.h" +#include "SPI.h" +#include // Hardware-specific library +TFT_eSPI tft = TFT_eSPI(); // Invoke custom library + +BearSSL::CertStore certStore; + +const char * host = "maps.googleapis.com"; +const char * path = "/maps/api/staticmap?center=40.714728,-73.998672&zoom=14&size=480x320&format=jpg-baseline&key="; +const char * mapFile = "/map.jpg"; + +bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap) +{ + // Stop further decoding as image is running off bottom of screen + if ( y >= tft.height() ) return 0; + + // This function will clip the image block rendering automatically at the TFT boundaries + tft.pushImage(x, y, w, h, bitmap); + + // Return 1 to decode next block + return 1; +} + +void setup() +{ + Serial.begin(115200); + Serial.println("\n\n"); + + // Initialise SPIFFS + if (!SPIFFS.begin()) { + Serial.println("SPIFFS initialisation failed!"); + while (1) yield(); // Stay here twiddling thumbs waiting + } + Serial.println("\r\nInitialisation done."); + + + // Initialise the TFT + tft.begin(); + tft.fillScreen(TFT_BLACK); + tft.setRotation(3); + + // The jpeg image can be scaled by a factor of 1, 2, 4, or 8 + TJpgDec.setJpgScale(1); + + // The byte order can be swapped (set true for TFT_eSPI) + TJpgDec.setSwapBytes(true); + + // The decoder must be given the exact name of the rendering function above + TJpgDec.setCallback(tft_output); + + WiFi.begin(WIFI_SSID, PASSWORD); + + while (WiFi.status() != WL_CONNECTED) { + delay(1000); + Serial.print("."); + } + Serial.println(); + + setClock(); // Required for X.509 validation + + int numCerts = certStore.initCertStore(SPIFFS, PSTR("/certs.idx"), PSTR("/certs.ar")); + Serial.printf("Number of CA certs read: %d\n", numCerts); + if (numCerts == 0) { + Serial.printf("No certs found. Did you run certs-from-mozilla.py and upload the SPIFFS directory before running?\n"); + return; // Can't connect to anything w/o certs! + } + + listSPIFFS(); + + if(getStaticMapImage(host, path, mapFile)){ + listSPIFFS(); + TJpgDec.drawFsJpg(0, 0, mapFile); + } + +} + +void loop() +{ + +} + +// Set time via NTP, as required for x.509 validation +void setClock() { + configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov"); + + Serial.print("Waiting for NTP time sync: "); + time_t now = time(nullptr); + while (now < 8 * 3600 * 2) { + delay(500); + Serial.print("."); + now = time(nullptr); + } + Serial.println(""); + struct tm timeinfo; + gmtime_r(&now, &timeinfo); + Serial.print("Current time: "); + Serial.print(asctime(&timeinfo)); +} + +bool getStaticMapImage(const char *host, const char *path, String fileName){ + if(WiFi.status() != WL_CONNECTED){ + return false; + } + + int contentLength = 0; + int httpCode; + + BearSSL::WiFiClientSecure *client = new BearSSL::WiFiClientSecure(); + // Integrate the cert store with this connection + client->setCertStore(&certStore); + client->connect(host, 443); //HTTPS + + Serial.printf("Trying: %s:443...", host); + + if(!client->connected()){ + client->stop(); + Serial.printf("*** Can't connect. ***\n-------\n"); + return false; + } + + Serial.println("HTTPS Connected!"); + client->write("GET "); + client->write(path); + client->write(" HTTP/1.0\r\nHost: "); + client->write(host); + client->write("\r\nUser-Agent: ESP8266\r\n"); + client->write("\r\n"); + + while(client->connected()){ + String header = client-> readStringUntil('\n'); + if(header.startsWith(F("HTTP/1."))){ + httpCode = header.substring(9, 12).toInt(); + if(httpCode != 200){ + client->stop(); + return false; + } + } + + if(header.startsWith(F("Content-Length: "))){ + contentLength = header.substring(15).toInt(); + } + + if(header == F("\r")){ + break; + } + + } + + if(!(contentLength > 0)){ + client->stop(); + return false; + } + + fs::File f = SPIFFS.open(fileName, "w"); + if(!f){ + Serial.println(F("FILE OPEN FAILED")); + client->stop(); + return false; + } + + int remaining = contentLength; + int received; + uint8_t buff[512] = {0}; + + while(client->available() && remaining > 0){ + received = client->readBytes(buff, ((remaining > sizeof(buff)) ? sizeof(buff) : remaining)); + f.write(buff, received); + + if(remaining > 0){ + remaining -= received; + } + yield(); + } + + f.close(); + client->stop(); + Serial.println("DOWNLOAD END"); + return (remaining == 0 ? true : false); +} diff --git a/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE/List_SPIFFS.h b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE/List_SPIFFS.h new file mode 100644 index 0000000..9ef1392 --- /dev/null +++ b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE/List_SPIFFS.h @@ -0,0 +1,87 @@ +/*************************************************************************************** +** Function name: listSPIFFS +** Description: Listing SPIFFS files +***************************************************************************************/ +#ifdef ESP8266 +void listSPIFFS(void) { + Serial.println(F("\r\nListing SPIFFS files:")); + + fs::Dir dir = SPIFFS.openDir("/"); // Root directory + + static const char line[] PROGMEM = "================================================="; + Serial.println(FPSTR(line)); + Serial.println(F(" File name Size")); + Serial.println(FPSTR(line)); + + while (dir.next()) { + String fileName = dir.fileName(); + Serial.print(fileName); + int spaces = 33 - fileName.length(); // Tabulate nicely + if (spaces < 1) spaces = 1; + while (spaces--) Serial.print(" "); + + fs::File f = dir.openFile("r"); + String fileSize = (String) f.size(); + spaces = 10 - fileSize.length(); // Tabulate nicely + if (spaces < 1) spaces = 1; + while (spaces--) Serial.print(" "); + Serial.println(fileSize + " bytes"); + } + + Serial.println(FPSTR(line)); + Serial.println(); + delay(1000); +} + +//==================================================================================== + +#elif defined ESP32 + +void listSPIFFS(void) { + Serial.println(F("\r\nListing SPIFFS files:")); + static const char line[] PROGMEM = "================================================="; + + Serial.println(FPSTR(line)); + Serial.println(F(" File name Size")); + Serial.println(FPSTR(line)); + + fs::File root = SPIFFS.open("/"); + if (!root) { + Serial.println(F("Failed to open directory")); + return; + } + if (!root.isDirectory()) { + Serial.println(F("Not a directory")); + return; + } + + fs::File file = root.openNextFile(); + while (file) { + + if (file.isDirectory()) { + Serial.print("DIR : "); + String fileName = file.name(); + Serial.print(fileName); + } else { + String fileName = file.name(); + Serial.print(" " + fileName); + // File path can be 31 characters maximum in SPIFFS + int spaces = 33 - fileName.length(); // Tabulate nicely + if (spaces < 1) spaces = 1; + while (spaces--) Serial.print(" "); + String fileSize = (String) file.size(); + spaces = 10 - fileSize.length(); // Tabulate nicely + if (spaces < 1) spaces = 1; + while (spaces--) Serial.print(" "); + Serial.println(fileSize + " bytes"); + } + + file = root.openNextFile(); + } + + Serial.println(FPSTR(line)); + Serial.println(); + delay(1000); +} + +#endif diff --git a/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE/Web_Fetch.h b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE/Web_Fetch.h new file mode 100644 index 0000000..a5cd2d2 --- /dev/null +++ b/ESP8266_GOOGLEMAP_GPS/ESP8266_GOOGLEMAP_GPS_ILI9488_WEB_IMAGE/Web_Fetch.h @@ -0,0 +1,77 @@ +// Fetch a file from the URL given and save it in SPIFFS +// Return 1 if a web fetch was needed or 0 if file already exists +bool getFile(String url, String filename) { + + // If it exists then no need to fetch it + if (SPIFFS.exists(filename) == true) { + Serial.println("Found " + filename); + return 0; + } + + Serial.println("Downloading " + filename + " from " + url); + + // Check WiFi connection + if ((WiFi.status() == WL_CONNECTED)) { + HTTPClient http; + + Serial.print("[HTTP] begin...\n"); + + // Configure server and url + http.begin(url); + + Serial.print("[HTTP] GET...\n"); + // Start connection and send HTTP header + int httpCode = http.GET(); + if (httpCode > 0) { + fs::File f = SPIFFS.open(filename, "w+"); + if (!f) { + Serial.println("file open failed"); + return 0; + } + // HTTP header has been send and Server response header has been handled + Serial.printf("[HTTP] GET... code: %d\n", httpCode); + + // File found at server + if (httpCode == HTTP_CODE_OK) { + + // Get length of document (is -1 when Server sends no Content-Length header) + int total = http.getSize(); + int len = total; + + // Create buffer for read + uint8_t buff[128] = { 0 }; + + // Get tcp stream + WiFiClient * stream = http.getStreamPtr(); + + // Read all data from server + while (http.connected() && (len > 0 || len == -1)) { + // Get available data size + size_t size = stream->available(); + + if (size) { + // Read up to 128 bytes + int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); + + // Write it to file + f.write(buff, c); + + // Calculate remaining bytes + if (len > 0) { + len -= c; + } + } + yield(); + } + Serial.println(); + Serial.print("[HTTP] connection closed or file end.\n"); + } + f.close(); + } + else { + Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); + } + http.end(); + } + return 1; // File was fetched from web +}