diff --git a/ESP32_PrusaConnectCam/ESP32_PrusaConnectCam.ino b/ESP32_PrusaConnectCam/ESP32_PrusaConnectCam.ino
index 4ac76ab..3b3b834 100644
--- a/ESP32_PrusaConnectCam/ESP32_PrusaConnectCam.ino
+++ b/ESP32_PrusaConnectCam/ESP32_PrusaConnectCam.ino
@@ -115,14 +115,14 @@ void setup() {
/* init tasks */
SystemLog.AddEvent(LogLevel_Info, F("Start tasks"));
- xTaskCreatePinnedToCore(System_TaskMain, "SystemNtpOtaUpdate", 6500, NULL, 1, &Task_SystemMain, 0); /*function, description, stack size, parameters, priority, task handle, core*/
- xTaskCreatePinnedToCore(System_TaskCaptureAndSendPhoto, "CaptureAndSendPhoto", 4700, NULL, 2, &Task_CapturePhotoAndSend, 0); /*function, description, stack size, parameters, priority, task handle, core*/
- xTaskCreatePinnedToCore(System_TaskWifiManagement, "WiFiManagement", 3300, NULL, 3, &Task_WiFiManagement, 0); /*function, description, stack size, parameters, priority, task handle, core*/
+ xTaskCreatePinnedToCore(System_TaskMain, "SystemNtpOtaUpdate", 6200, NULL, 1, &Task_SystemMain, 0); /*function, description, stack size, parameters, priority, task handle, core*/
+ xTaskCreatePinnedToCore(System_TaskCaptureAndSendPhoto, "CaptureAndSendPhoto", 4400, NULL, 2, &Task_CapturePhotoAndSend, 0); /*function, description, stack size, parameters, priority, task handle, core*/
+ xTaskCreatePinnedToCore(System_TaskWifiManagement, "WiFiManagement", 2800, NULL, 3, &Task_WiFiManagement, 0); /*function, description, stack size, parameters, priority, task handle, core*/
xTaskCreatePinnedToCore(System_TaskSdCardCheck, "CheckMicroSdCard", 3000, NULL, 4, &Task_SdCardCheck, 0); /*function, description, stack size, parameters, priority, task handle, core*/
- xTaskCreatePinnedToCore(System_TaskSerialCfg, "CheckSerialConfiguration", 3300, NULL, 5, &Task_SerialCfg, 0); /*function, description, stack size, parameters, priority, task handle, core*/
- xTaskCreatePinnedToCore(System_TaskStreamTelemetry, "PrintStreamTelemetry", 3000, NULL, 6, &Task_StreamTelemetry, 0); /*function, description, stack size, parameters, priority, task handle, core*/
- xTaskCreatePinnedToCore(System_TaskSysLed, "SystemLed", 2900, NULL, 7, &Task_SysLed, 0); /*function, description, stack size, parameters, priority, task handle, core*/
- xTaskCreatePinnedToCore(System_TaskWiFiWatchdog, "WiFiWatchdog", 3000, NULL, 8, &Task_WiFiWatchdog, 0); /*function, description, stack size, parameters, priority, task handle, core*/
+ xTaskCreatePinnedToCore(System_TaskSerialCfg, "CheckSerialConfiguration", 2600, NULL, 5, &Task_SerialCfg, 0); /*function, description, stack size, parameters, priority, task handle, core*/
+ xTaskCreatePinnedToCore(System_TaskStreamTelemetry, "PrintStreamTelemetry", 2200, NULL, 6, &Task_StreamTelemetry, 0); /*function, description, stack size, parameters, priority, task handle, core*/
+ xTaskCreatePinnedToCore(System_TaskSysLed, "SystemLed", 2100, NULL, 7, &Task_SysLed, 0); /*function, description, stack size, parameters, priority, task handle, core*/
+ xTaskCreatePinnedToCore(System_TaskWiFiWatchdog, "WiFiWatchdog", 2200, NULL, 8, &Task_WiFiWatchdog, 0); /*function, description, stack size, parameters, priority, task handle, core*/
//xTaskCreatePinnedToCore(System_TaskSdCardRemove, "SdCardRemove", 3000, NULL, 9, &Task_SdCardFileRemove, 0); /*function, description, stack size, parameters, priority, task handle, core*/
/* init wdg */
diff --git a/ESP32_PrusaConnectCam/WebPage.h b/ESP32_PrusaConnectCam/WebPage.h
index 829a98a..04c3784 100644
--- a/ESP32_PrusaConnectCam/WebPage.h
+++ b/ESP32_PrusaConnectCam/WebPage.h
@@ -72,6 +72,7 @@ const char index_html[] PROGMEM = R"rawliteral(
+
diff --git a/ESP32_PrusaConnectCam/connect.cpp b/ESP32_PrusaConnectCam/connect.cpp
index 270c8eb..d0e283f 100644
--- a/ESP32_PrusaConnectCam/connect.cpp
+++ b/ESP32_PrusaConnectCam/connect.cpp
@@ -130,7 +130,7 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i
size_t fbLen = camera->GetPhotoFb()->len;
/* sending exif data */
- if (camera->GetPhotoExifData()->header != NULL) {
+ if ((camera->GetPhotoExifData()->header != NULL) && (camera->GetStreamStatus() == false)) {
SendWithExif = true;
sendet_data += client.write(camera->GetPhotoExifData()->header, camera->GetPhotoExifData()->len);
fbBuf += camera->GetPhotoExifData()->offset;
@@ -151,7 +151,6 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i
}
}
client.println("\r\n");
- client.flush();
/* log message */
if (SendWithExif) {
@@ -164,15 +163,24 @@ bool PrusaConnect::SendDataToBackend(String *i_data, int i_data_length, String i
} else if (SendInfo == i_data_type) {
log->AddEvent(LogLevel_Verbose, F("Sending info"));
sendet_data = client.print(*i_data);
- client.flush();
}
+ client.flush();
log->AddEvent(LogLevel_Info, "Send done: " + String(i_data_length) + "/" + String(sendet_data) + " bytes");
- esp_task_wdt_reset();
+
+ /* check if all data was sent */
+ if (i_data_length != sendet_data) {
+ BackendReceivedStatus = F("INCOMPLETE DATA SEND TO SERVER!");
+ log->AddEvent(LogLevel_Error, F("ERROR SEND DATA TO SERVER! INCORRECT DATA LENGTH!"));
+ client.stop();
+ return false;
+ }
+ //esp_task_wdt_reset();
/* read response from server */
String response = "";
String fullResponse = "";
+ delay(10); // wait for response
log->AddEvent(LogLevel_Verbose, F("Response:"));
while (client.connected()) {
if (client.available()) {
@@ -225,7 +233,7 @@ void PrusaConnect::SendPhotoToBackend() {
String Photo = "";
size_t total_len = 0;
- if (camera->GetPhotoExifData()->header != NULL) {
+ if ((camera->GetPhotoExifData()->header != NULL) && (camera->GetStreamStatus() == false)) {
total_len = camera->GetPhotoExifData()->len + camera->GetPhotoFb()->len - camera->GetPhotoExifData()->offset;
} else {
total_len = camera->GetPhotoFb()->len;
@@ -294,7 +302,9 @@ void PrusaConnect::TakePictureAndSendToBackend() {
log->AddEvent(LogLevel_Error, F("Error capturing photo. Stop sending to backend!"));
}
- camera->CaptureReturnFrameBuffer();
+ if (camera->GetStreamStatus() == false) {
+ camera->CaptureReturnFrameBuffer();
+ }
}
/**
@@ -459,18 +469,29 @@ void PrusaConnect::SetTimeLapsPhotoSaveStatus(bool i_data) {
@return none
*/
void PrusaConnect::SavePhotoToSdCard() {
+ /* check if time laps photo save is enabled */
if (EnableTimelapsPhotoSave == true) {
log->AddEvent(LogLevel_Info, F("Save TimeLaps photo to SD card"));
+
+ /* check if SD card is detected */
+ if (log->GetCardDetectedStatus() == false) {
+ log->AddEvent(LogLevel_Error, F("SD card not detected!"));
+ return;
+ }
+
+ /* check if folder for time laps photos exists */
if (false == log->CheckDir(SD_MMC, TIMELAPS_PHOTO_FOLDER)) {
log->AddEvent(LogLevel_Info, F("Create folder for TimeLaps photos"));
log->CreateDir(SD_MMC, TIMELAPS_PHOTO_FOLDER);
}
+ /* create file name */
String FileName = String(TIMELAPS_PHOTO_FOLDER) + "/" + String(TIMELAPS_PHOTO_PREFIX) + "_";
FileName += log->GetSystemTime();
FileName += TIMELAPS_PHOTO_SUFFIX;
log->AddEvent(LogLevel_Verbose, F("Saving file: "), FileName);
+ /* save photo to SD card */
if (camera->GetPhotoExifData()->header != NULL) {
if (log->WritePicture(FileName, camera->GetPhotoFb()->buf + camera->GetPhotoExifData()->offset, camera->GetPhotoFb()->len - camera->GetPhotoExifData()->offset, camera->GetPhotoExifData()->header, camera->GetPhotoExifData()->len) == true) {
log->AddEvent(LogLevel_Info, F("Photo saved to SD card. EXIF"));
diff --git a/ESP32_PrusaConnectCam/log.cpp b/ESP32_PrusaConnectCam/log.cpp
index adcd98d..563032f 100644
--- a/ESP32_PrusaConnectCam/log.cpp
+++ b/ESP32_PrusaConnectCam/log.cpp
@@ -24,6 +24,7 @@ Logs::Logs() {
FileMaxSize = 1024;
NtpTimeSynced = false;
LogMsg = "";
+ LogMutex = xSemaphoreCreateMutex();
}
/**
@@ -39,6 +40,7 @@ Logs::Logs(String i_FilePath, String i_FileName) {
FileMaxSize = 1024;
NtpTimeSynced = false;
LogMsg = "";
+ LogMutex = xSemaphoreCreateMutex();
}
/**
@@ -55,6 +57,7 @@ Logs::Logs(LogLevel_enum i_LogLevel, String i_FilePath, String i_FileName) {
FileMaxSize = 1024;
NtpTimeSynced = false;
LogMsg = "";
+ LogMutex = xSemaphoreCreateMutex();
}
/**
@@ -71,6 +74,7 @@ Logs::Logs(String i_FilePath, String i_FileName, uint16_t i_FileSize) {
FileMaxSize = i_FileSize;
NtpTimeSynced = false;
LogMsg = "";
+ LogMutex = xSemaphoreCreateMutex();
}
/**
@@ -88,6 +92,7 @@ Logs::Logs(LogLevel_enum i_LogLevel, String i_FilePath, String i_FileName, uint1
FileMaxSize = i_FileSize;
NtpTimeSynced = false;
LogMsg = "";
+ LogMutex = xSemaphoreCreateMutex();
}
/**
@@ -103,6 +108,7 @@ void Logs::Init() {
/* init micro SD card */
InitSdCard();
+ LogFileOpened = OpenFile(&LogFile, FilePath + FileName);
if (true == GetCardDetectedStatus()) {
/* check maximum log file size */
@@ -121,13 +127,37 @@ void Logs::Init() {
LogMsg += F("Log level: ");
LogMsg += String(LogLevel);
LogMsg += "\n";
- AppendFile(SD_MMC, FilePath + FileName, LogMsg);
+ AppendFile(&LogFile, &LogMsg);
} else {
Serial.println(F("Micro-SD card not found! Disable logs"));
}
}
+/**
+ * @brief Open log file
+ *
+ */
+void Logs::LogOpenFile() {
+ LogFileOpened = OpenFile(&LogFile, FilePath + FileName);
+}
+
+/**
+ * @brief Close log file
+ *
+ */
+void Logs::LogCloseFile() {
+ CloseFile(&LogFile);
+}
+
+/**
+ * @brief Function for check opened log file
+ *
+ */
+void Logs::LogCheckOpenedFile() {
+ LogFileOpened = CheckOpenFile(&LogFile);
+}
+
/**
@info set log level
@param LogLevel_enum - log level
@@ -146,9 +176,13 @@ void Logs::SetLogLevel(LogLevel_enum level) {
@return none
*/
void Logs::AddEvent(LogLevel_enum level, String msg, bool newLine, bool date) {
+ /* mutex for log */
+ xSemaphoreTake(LogMutex, portMAX_DELAY);
+ /* check log level */
if (LogLevel >= level) {
- LogMsg = "";
+ /* create log message */
+ LogMsg = "";
if (true == date) {
LogMsg += GetSystemTime();
LogMsg += " - ";
@@ -158,14 +192,27 @@ void Logs::AddEvent(LogLevel_enum level, String msg, bool newLine, bool date) {
LogMsg += "\n";
}
- AppendFile(SD_MMC, FilePath + FileName, LogMsg);
+ /* print log message to console */
Serial.print(LogMsg);
+
+ /* append log message to log file */
+ if (true == LogFileOpened) {
+ LogFileOpened = AppendFile(&LogFile, &LogMsg);
+ if ((false == LogFileOpened) && (true == GetCardDetectedStatus())){
+ LogCloseFile();
+ LogOpenFile();
+ if (true == LogFileOpened) {
+ LogFileOpened = AppendFile(&LogFile, &LogMsg);
+ }
+ }
+ }
}
#if (true == CONSOLE_VERBOSE_DEBUG)
else {
Serial.println(msg);
}
#endif
+ xSemaphoreGive(LogMutex);
}
/**
@@ -178,9 +225,14 @@ void Logs::AddEvent(LogLevel_enum level, String msg, bool newLine, bool date) {
@return none
*/
void Logs::AddEvent(LogLevel_enum level, const __FlashStringHelper *msg, String parameters, bool newLine, bool date) {
- if (LogLevel >= level) {
- LogMsg = "";
+ /* mutex for log */
+ xSemaphoreTake(LogMutex, portMAX_DELAY);
+ /* check log level */
+ if (LogLevel >= level) {
+
+ /* create log message */
+ LogMsg = "";
if (true == date) {
LogMsg += GetSystemTime();
LogMsg += " - ";
@@ -191,14 +243,29 @@ void Logs::AddEvent(LogLevel_enum level, const __FlashStringHelper *msg, String
LogMsg += "\n";
}
- AppendFile(SD_MMC, FilePath + FileName, LogMsg);
+ /* print log message to console */
Serial.print(LogMsg);
+
+ /* append log message to log file */
+ if (true == LogFileOpened) {
+ LogFileOpened = AppendFile(&LogFile, &LogMsg);
+ if ((false == LogFileOpened) && (true == GetCardDetectedStatus())){
+ LogCloseFile();
+ LogOpenFile();
+ if (true == LogFileOpened) {
+ AppendFile(&LogFile, &LogMsg);
+ }
+ }
+ }
}
#if (true == CONSOLE_VERBOSE_DEBUG)
else {
Serial.println(msg);
}
#endif
+
+ /* release mutex */
+ xSemaphoreGive(LogMutex);
}
/**
@@ -281,13 +348,14 @@ bool Logs::GetNtpTimeSynced() {
*/
void Logs::CheckMaxLogFileSize() {
uint32_t FileSize = GetFileSize(SD_MMC, FilePath + FileName);
- AddEvent(LogLevel_Verbose, F("Log file size: "), String(FileSize) + " bytes");
+ AddEvent(LogLevel_Verbose, F("Log file size: "), String(FileSize) + "/" + String(LOGS_FILE_MAX_SIZE) + " B");
if (FileSize >= LOGS_FILE_MAX_SIZE) {
uint16_t file_count = FileCount(SD_MMC, FilePath, FileName);
AddEvent(LogLevel_Info, F("Maximum log file size. File count: "), String(file_count));
+ LogCloseFile();
RenameFile(SD_MMC, FilePath + FileName, FilePath + FileName + String(file_count));
-
+ LogOpenFile();
}
}
@@ -296,6 +364,15 @@ void Logs::CheckCardSpace() {
AddEvent(LogLevel_Verbose, "Card size: " + String(GetCardSizeMB()), + " MB, Used: " + String(GetCardUsedMB()) + " MB, Free: " + String(GetCardUsedMB()) + " MB");
}
+/**
+ @info Get log file opened
+ @param none
+ @return bool - log file opened
+*/
+bool Logs::GetLogFileOpened() {
+ return LogFileOpened;
+}
+
/**
@info Get system time
@param none
diff --git a/ESP32_PrusaConnectCam/log.h b/ESP32_PrusaConnectCam/log.h
index edc95ea..159e98a 100644
--- a/ESP32_PrusaConnectCam/log.h
+++ b/ESP32_PrusaConnectCam/log.h
@@ -27,12 +27,15 @@ enum LogLevel_enum {
class Logs : public MicroSd {
private:
- LogLevel_enum LogLevel; ///< LogLevel
- String FileName; ///< log File name
- String FilePath; ///< log file patch
- uint16_t FileMaxSize; ///< log file max size
- bool NtpTimeSynced; ///< status NTP time sync
- String LogMsg; ///< log message
+ LogLevel_enum LogLevel; ///< LogLevel
+ String FileName; ///< log File name
+ String FilePath; ///< log file patch
+ uint16_t FileMaxSize; ///< log file max size
+ bool NtpTimeSynced; ///< status NTP time sync
+ String LogMsg; ///< log message
+ File LogFile; ///< log file object
+ bool LogFileOpened; ///< log file opened status
+ SemaphoreHandle_t LogMutex; ///< log mutex
public:
Logs();
@@ -43,6 +46,9 @@ public:
~Logs(){};
void Init();
+ void LogOpenFile();
+ void LogCloseFile();
+ void LogCheckOpenedFile();
void AddEvent(LogLevel_enum, String, bool = true, bool = true);
void AddEvent(LogLevel_enum, const __FlashStringHelper*, String, bool = true, bool = true);
void SetLogLevel(LogLevel_enum);
@@ -57,6 +63,7 @@ public:
bool GetNtpTimeSynced();
void CheckMaxLogFileSize();
void CheckCardSpace();
+ bool GetLogFileOpened();
String GetSystemTime();
};
diff --git a/ESP32_PrusaConnectCam/mcu_cfg.h b/ESP32_PrusaConnectCam/mcu_cfg.h
index a473cf3..caa484c 100644
--- a/ESP32_PrusaConnectCam/mcu_cfg.h
+++ b/ESP32_PrusaConnectCam/mcu_cfg.h
@@ -14,7 +14,7 @@
#define _MCU_CFG_H_
/* ---------------- BASIC MCU CFG --------------*/
-#define SW_VERSION "1.0.3-rc1" ///< SW version
+#define SW_VERSION "1.0.3-rc2" ///< SW version
#define SW_BUILD __DATE__ " " __TIME__ ///< build number
#define CONSOLE_VERBOSE_DEBUG false ///< enable/disable verbose debug log level for console
#define DEVICE_HOSTNAME "Prusa-ESP32cam" ///< device hostname
@@ -44,10 +44,10 @@
#define STATUS_LED_ERROR 100 ///< time for blink status LED when is module in the error state [ms]
/* ------------------- TASKS --------------------*/
-#define TASK_SYSTEM 2000 ///< system task interval [ms]
-#define TASK_SDCARD 30000 ///< sd card task interval [ms]
-#define TASK_WIFI 30000 ///< wifi reconnect interval. Checking when is signal lost [ms]
-#define TASK_SERIAL_CFG 2000 ///< serial cfg task interval [ms]
+#define TASK_SYSTEM 1000 ///< system task interval [ms]
+#define TASK_SDCARD 25000 ///< sd card task interval [ms]
+#define TASK_WIFI 28000 ///< wifi reconnect interval. Checking when is signal lost [ms]
+#define TASK_SERIAL_CFG 1000 ///< serial cfg task interval [ms]
#define TASK_STREAM_TELEMETRY 30000 ///< stream telemetry task interval [ms]
#define TASK_WIFI_WATCHDOG 20000 ///< wifi watchdog task interval [ms]
#define TASK_PHOTO_SEND 1000 ///< photo send task interval [ms]
@@ -57,7 +57,7 @@
#define WEB_SERVER_PORT 80 ///< WEB server port
#define SERIAL_PORT_SPEED 115200 ///< baud rate
#define WDG_TIMEOUT 40 ///< wdg timeout [second]
-#define PHOTO_FRAGMENT_SIZE 5120 ///< photo fragmentation size [bytes]
+#define PHOTO_FRAGMENT_SIZE 5120 ///< photo fragmentation size [bytes]
#define LOOP_DELAY 100 ///< loop delay [ms]
#define WIFI_CLIENT_WAIT_CON false ///< wait for connecting to WiFi network
#define WEB_CACHE_INTERVAL 86400 ///< cache interval for browser [s] 86400s = 24h
@@ -75,7 +75,7 @@
/* ---------------- MicroSD Logs ----------------*/
#define LOGS_FILE_NAME "SysLog.log" ///< syslog file name
#define LOGS_FILE_PATH "/" ///< directory for log files
-#define LOGS_FILE_MAX_SIZE 512 ///< maximum file size in the [kb]
+#define LOGS_FILE_MAX_SIZE 1024 ///< maximum file size in the [kb]
#define FILE_REMOVE_MAX_COUNT 5 ///< maximum count for remove files from sd card
/* ---------------- AP MODE CFG ----------------*/
diff --git a/ESP32_PrusaConnectCam/micro_sd.cpp b/ESP32_PrusaConnectCam/micro_sd.cpp
index 07464c1..d01edf1 100644
--- a/ESP32_PrusaConnectCam/micro_sd.cpp
+++ b/ESP32_PrusaConnectCam/micro_sd.cpp
@@ -19,6 +19,7 @@
MicroSd::MicroSd() {
CardDetected = false;
DetectAfterBoot = false;
+ sdCardMutex = xSemaphoreCreateMutex();
}
/**
@@ -35,6 +36,73 @@ void MicroSd::ReinitCard() {
InitSdCard();
}
+/**
+ * @brief Open file
+ *
+ * @param i_file - file
+ * @param i_path - path and file name
+ * @return true
+ * @return false
+ */
+bool MicroSd::OpenFile(File *i_file, String i_path) {
+ bool status = false;
+
+ if (true == CardDetected) {
+#if (true == CONSOLE_VERBOSE_DEBUG)
+ Serial.println("Opening file: " + i_path);
+#endif
+
+ if (SD_MMC.cardType() == CARD_NONE) {
+ Serial.println("No SD card detected");
+ CardDetected = false;
+ } else {
+
+ *i_file = SD_MMC.open(i_path.c_str(), FILE_APPEND);
+ if (!*i_file) {
+#if (true == CONSOLE_VERBOSE_DEBUG)
+ Serial.println("Failed to open file");
+#endif
+ CardDetected = false;
+ } else {
+ status = true;
+#if (true == CONSOLE_VERBOSE_DEBUG)
+ Serial.println("File opened");
+#endif
+ }
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief Close file
+ *
+ * @param i_file - file
+ */
+void MicroSd::CloseFile(File *i_file) {
+ if (*i_file) {
+ i_file->close();
+ }
+}
+
+/**
+ * @brief Check if file is opened
+ *
+ * @param i_file - file
+ * @return true
+ * @return false
+ */
+bool MicroSd::CheckOpenFile(File *i_file) {
+ if (!*i_file) {
+#if (true == CONSOLE_VERBOSE_DEBUG)
+ Serial.println(F("File not opened!"));
+#endif
+ return false;
+ } else {
+ return true;
+ }
+}
+
/**
@brief Init SD card. And check, if is SD card inserted
@param none
@@ -46,11 +114,11 @@ void MicroSd::InitSdCard() {
/* set SD card to 1-line/1-bit mode. GPIO 4 is used for LED and for microSD card. But communication is slower. */
/* https://github.com/espressif/arduino-esp32/blob/master/libraries/SD_MMC/src/SD_MMC.h */
+
if (!SD_MMC.begin("/sdcard", true)) {
Serial.println(F("SD Card Mount Failed"));
CardDetected = false;
CardSizeMB = 0;
- //DetectAfterBoot = false;
return;
}
@@ -60,20 +128,19 @@ void MicroSd::InitSdCard() {
Serial.println(F("No SD_MMC card attached"));
CardDetected = false;
CardSizeMB = 0;
- //DetectAfterBoot = false;
return;
}
/* print card type */
Serial.print(F("Found card. Card Type: "));
if (cardType == CARD_MMC) {
- Serial.print(F("MMC"));
+ Serial.println(F("MMC"));
} else if (cardType == CARD_SD) {
- Serial.print(F("SDSC"));
+ Serial.println(F("SDSC"));
} else if (cardType == CARD_SDHC) {
- Serial.print(F("SDHC"));
+ Serial.println(F("SDHC"));
} else {
- Serial.print(F("UNKNOWN"));
+ Serial.println(F("UNKNOWN"));
}
CardDetected = true;
@@ -281,6 +348,70 @@ bool MicroSd::AppendFile(fs::FS &fs, String path, String message) {
return status;
}
+/**
+ @brief Added text to end of file
+ @param File - file
+ @param String - message
+ @return bool - status
+*/
+bool MicroSd::AppendFile(File *i_file, String *i_msg) {
+ /* take mutex */
+ xSemaphoreTake(sdCardMutex, portMAX_DELAY);
+ bool status = false;
+
+ /* check if card is corrupted */
+ if (false == isCardCorrupted()) {
+ xSemaphoreGive(sdCardMutex);
+ return false;
+ }
+
+ /* check if card is detected */
+ if (true == CardDetected) {
+#if (true == CONSOLE_VERBOSE_DEBUG)
+ Serial.printf("Appending to file:");
+#endif
+
+ /* check if file is opened */
+ if (!*i_file) {
+ Serial.println("File not opened");
+ CardDetected = false;
+
+ } else {
+ /* write to file */
+ if (i_file->print(i_msg->c_str())) {
+ if (*i_file) {
+ i_file->flush();
+
+ /* check if write was OK */
+ if (!i_file->getWriteError()) {
+#if (true == CONSOLE_VERBOSE_DEBUG)
+ Serial.println("Write OK");
+#endif
+ status = true;
+
+ } else {
+ Serial.println(F("Failed write to file"));
+
+ }
+ } else {
+ Serial.println(F("File not opened!"));
+
+ }
+ } else {
+ Serial.println(F("Failed write to file!"));
+
+ }
+#if (true == CONSOLE_VERBOSE_DEBUG)
+ Serial.println((status == true) ? "Message appended" : "Append Failed");
+#endif
+ }
+ }
+
+ /* give mutex */
+ xSemaphoreGive(sdCardMutex);
+ return status;
+}
+
/**
@brief Rename file on the SD card
@param fs::FS - card
@@ -465,6 +596,51 @@ void MicroSd::CheckCardUsedStatus() {
#endif
}
+/**
+ * @brief Function to check if card is corrupted
+ *
+ * @return true
+ * @return false
+ */
+bool MicroSd::isCardCorrupted() {
+ bool ret = true;
+ if (true == CardDetected) {
+#if (true == CONSOLE_VERBOSE_DEBUG)
+ //Serial.println(F("Checking card..."));
+#endif
+
+ /* check card size */
+ uint64_t use = SD_MMC.usedBytes();
+ uint64_t size = 0;
+ if (use != 0) {
+ size = SD_MMC.cardSize();
+ }
+
+#if (true == CONSOLE_VERBOSE_DEBUG)
+ Serial.printf("Card size: %llu, Used: %llu\n", size, use);
+#endif
+
+ /* check space on the card */
+ if (size == use) {
+ Serial.println(F("No space left on device!"));
+ CardDetected = false;
+ ret = false;
+ }
+
+ /* check another error */
+ if ((size <= 0 ) || (size == 0) || (use <= 0) || (use == 0)) {
+ Serial.println(F("No card detected!"));
+ CardDetected = false;
+ ret = false;
+ }
+
+ } else {
+ ret = false;
+ }
+
+ return ret;
+}
+
/**
@brief Write picture to the SD card
@param fs::FS - card
diff --git a/ESP32_PrusaConnectCam/micro_sd.h b/ESP32_PrusaConnectCam/micro_sd.h
index 49aad4d..d39940d 100644
--- a/ESP32_PrusaConnectCam/micro_sd.h
+++ b/ESP32_PrusaConnectCam/micro_sd.h
@@ -33,15 +33,16 @@
class MicroSd {
private:
- bool CardDetected; ///< Card detected status
- bool DetectAfterBoot; ///< Card detect after boot
- uint32_t CardSizeMB; ///< Card size
- uint32_t CardTotalMB; ///< Card total size
- uint32_t CardUsedMB; ///< Card used size
- uint32_t CardFreeMB; ///< Card free size
- uint8_t FreeSpacePercent; ///< Free space in percent
- uint8_t UsedSpacePercent; ///< Used space in percent
- File file; ///< File object
+ bool CardDetected; ///< Card detected status
+ bool DetectAfterBoot; ///< Card detect after boot
+ uint32_t CardSizeMB; ///< Card size
+ uint32_t CardTotalMB; ///< Card total size
+ uint32_t CardUsedMB; ///< Card used size
+ uint32_t CardFreeMB; ///< Card free size
+ uint8_t FreeSpacePercent; ///< Free space in percent
+ uint8_t UsedSpacePercent; ///< Used space in percent
+ File file; ///< File object
+ SemaphoreHandle_t sdCardMutex; ///< Mutex for SD card
public:
MicroSd();
@@ -49,6 +50,9 @@ public:
void InitSdCard();
void ReinitCard();
+ bool OpenFile(File*, String);
+ void CloseFile(File*);
+ bool CheckOpenFile(File*);
void ListDir(fs::FS &, String, uint8_t);
bool CheckDir(fs::FS &, String);
@@ -57,6 +61,7 @@ public:
void ReadFileConsole(fs::FS &, String);
bool WriteFile(fs::FS &, String, String);
bool AppendFile(fs::FS &, String, String);
+ bool AppendFile(File*, String*);
bool RenameFile(fs::FS &, String, String);
bool DeleteFile(fs::FS &, String);
uint32_t GetFileSize(fs::FS &, String);
@@ -68,6 +73,7 @@ public:
bool WritePicture(String, uint8_t *, size_t, const uint8_t *, size_t);
void CheckCardUsedStatus();
+ bool isCardCorrupted();
bool GetCardDetectedStatus();
bool GetCardDetectAfterBoot();
diff --git a/ESP32_PrusaConnectCam/server.cpp b/ESP32_PrusaConnectCam/server.cpp
index 78e4cf1..c8b9129 100644
--- a/ESP32_PrusaConnectCam/server.cpp
+++ b/ESP32_PrusaConnectCam/server.cpp
@@ -252,6 +252,7 @@ void Server_InitWebServer_WebPages() {
if (true == SystemLog.GetCardDetectedStatus()) {
request->send(SD_MMC, SystemLog.GetFilePath() + SystemLog.GetFileName(), "text/plain");
+ //SystemLog.LogOpenFile();
} else {
request->send_P(404, "text/plain", "Micro SD card not found with FAT32 partition!");
}
diff --git a/ESP32_PrusaConnectCam/stream.cpp b/ESP32_PrusaConnectCam/stream.cpp
index 44f14c2..994bb0c 100644
--- a/ESP32_PrusaConnectCam/stream.cpp
+++ b/ESP32_PrusaConnectCam/stream.cpp
@@ -226,7 +226,7 @@ size_t AsyncJpegStreamResponse::_content(uint8_t *buffer, size_t maxLen, size_t
char buf[50] = { '\0' };
camera->StreamSetFrameSize(_frame.fb->len / 1024);
camera->StreamSetFrameFps(fps);
- //sprintf(buf, "Size: %uKB, Time: %ums (%.1f fps)", _frame.fb->len / 1024, fp, fps);
+ ////sprintf(buf, "Size: %uKB, Time: %ums (%.1f fps)", _frame.fb->len / 1024, fp, fps);
sprintf(buf, "Size: %uKB, FPS: %.1f", _frame.fb->len / 1024, fps);
Serial.println(buf);
lastAsyncRequest = end;
diff --git a/ESP32_PrusaConnectCam/system.cpp b/ESP32_PrusaConnectCam/system.cpp
index 1c79f2d..839e915 100644
--- a/ESP32_PrusaConnectCam/system.cpp
+++ b/ESP32_PrusaConnectCam/system.cpp
@@ -542,7 +542,9 @@ void System_TaskSdCardCheck(void *pvParameters) {
esp_task_wdt_reset();
/* check micro SD card */
if ((true == SystemLog.GetCardDetectAfterBoot()) && (false == SystemLog.GetCardDetectedStatus())) {
+ SystemLog.LogCloseFile();
SystemLog.ReinitCard();
+ SystemLog.LogOpenFile();
SystemLog.AddEvent(LogLevel_Warning, F("Reinit micro SD card done!"));
}
@@ -558,6 +560,16 @@ void System_TaskSdCardCheck(void *pvParameters) {
SystemLog.CheckMaxLogFileSize();
}
+ /* check if log file is opened */
+ if (true == SystemLog.GetCardDetectedStatus()) {
+ SystemLog.LogCheckOpenedFile();
+ if (false == SystemLog.GetLogFileOpened()) {
+ SystemLog.LogOpenFile();
+ SystemLog.AddEvent(LogLevel_Warning, F("Log file is not opened!"));
+ }
+ }
+
+ SystemLog.AddEvent(LogLevel_Info, "CardStatus: " + String(SystemLog.GetCardDetectedStatus()) + " FileStatus: " + String(SystemLog.GetLogFileOpened()));
SystemLog.AddEvent(LogLevel_Verbose, F("MicroSdCard task. Stack free size: "), String(uxTaskGetStackHighWaterMark(NULL)) + "B");
/* reset wdg */