Hi 
Im try to LOG serveral Informations on SD-Card. This LOGs are in memory in an Array of Strings . When i got an new line the old File gets deleted and an new one is written.
Im also got a Funktion whitch reads the SD-Card completly and put it in an HTML-String passing this to the webserver.
Heres the first Problem : If this is done Teensy gets slow and I2C won´t work any more. Webserver is working but nothing else.
On the other Side sometimes i´m got read/write errors in the File.
My Programm now gets very big so im show here only the SD-Card related .cpp.
Im Work with Sloeber/Eclipse on WIN10. Teensy got 8MB of PSRAM.
Here the Function to get all Data from SD-Card to the webserver:
Im try to LOG serveral Informations on SD-Card. This LOGs are in memory in an Array of Strings . When i got an new line the old File gets deleted and an new one is written.
Im also got a Funktion whitch reads the SD-Card completly and put it in an HTML-String passing this to the webserver.
Heres the first Problem : If this is done Teensy gets slow and I2C won´t work any more. Webserver is working but nothing else.
On the other Side sometimes i´m got read/write errors in the File.
My Programm now gets very big so im show here only the SD-Card related .cpp.
Im Work with Sloeber/Eclipse on WIN10. Teensy got 8MB of PSRAM.
Code:
/*
* my_LOGtoSD.cpp
*
* Created on: 24.12.2021
* Author: Mike
*/
#include <Arduino.h>
#include <SD.h>
#include <FS.h>
#include "my_ethernet.h"
#include "my_LOGtoSD.h"
#include "main.h"
EXTMEM myLOG LOG;
void write_File(const char *path, const char *message) {
//debug("Einstieg in SUB write_File()");
SD.begin(BUILTIN_SDCARD);
if (SD.exists(path)) {
SD.remove(path);
}
File file = SD.open(path, FILE_WRITE);
file.println(message);
file.close();
}
void write_File(const char *path, double message) {
SD.begin(BUILTIN_SDCARD);
if (SD.exists(path)) {
SD.remove(path);
}
File file = SD.open(path, FILE_WRITE);
file.println(message);
file.close();
}
void write_File(const char *path, int message) {
SD.begin(BUILTIN_SDCARD);
if (SD.exists(path)) {
SD.remove(path);
}
File file = SD.open(path, FILE_WRITE);
file.println(message, DEC);
file.close();
}
//--------------------------------------------------------------------------------
String read_File(const char *path) {
SD.begin(BUILTIN_SDCARD);
String message;
File file = SD.open(path);
if (!file) {
debug("Failed to open file for reading");
file.close();
return String("Failed to open file for reading");
}
while (file.available()) {
message += char(file.read());
}
file.close();
debug(message);
return message;
}
//--------------------------------------------------------------------------------
void LOGtoSD_begin() {
//zum Anfang die LOG-Array mit Daten füllen:
for (byte j = 0; j <= 3; j++) {
for (byte i = 0; i <= 49; i++) {
LOG.LOG_STRING[j][i] = TimeStamp_Formated() + " --------------------";
LOG.LOG_STRING_COLOR[j][i] = 1;
}
}
/*
LOGwrite(0, 1, "");
LOGwrite(1, 1, "");
LOGwrite(2, 1, "");
LOGwrite(3, 1, "");
*/
debug("LOG-Dateien von SD lesen.");
LOGread(); // LOG-Dateien von SD-Karte lesen
}
void write_WindowContact_WatchdogState(byte Number, const double Timestamp, const int BatteryCharge) {
char NumberAsChar[2];
NumberAsChar[0] = Number + '0';
NumberAsChar[1] = '\0';
if (SD.begin(BUILTIN_SDCARD)) {
char Path[40] = "/WindowContact_Last_Report_";
strcat(Path, NumberAsChar);
strcat(Path, ".txt");
write_File(Path, Timestamp);
strcpy(Path, "/WindowContact_BatteryCharge_");
strcat(Path, NumberAsChar);
strcat(Path, ".txt");
write_File(Path, BatteryCharge);
}
}
//--------------------------------------------------------------------------------
void write_STATE_WINDOWCONTACT(byte Number, byte State) {
debug("Einstieg in SUB write_STATE_WINDOWCONTACT()");
char NumberAsChar[1];
NumberAsChar[0] = Number + '0';
char StatusAsChar[2];
StatusAsChar[0] = State + '0';
StatusAsChar[1] = '\0';
char Path[30] = "/STATE_WINDOWCONTACT_";
strcat(Path, NumberAsChar);
strcat(Path, ".txt");
write_File(Path, StatusAsChar);
}
//--------------------------------------------------------------------------------
double read_WindowContact_Last_Report(byte Number) {
char NumberAsChar[2];
NumberAsChar[0] = Number + '0';
NumberAsChar[1] = '\0';
double TimeStamp;
char Path[40] = "/WindowContact_Last_Report_";
strcat(Path, NumberAsChar);
strcat(Path, ".txt");
String tmp;
tmp = read_File(Path);
TimeStamp = atof(tmp.c_str());
return TimeStamp;
}
int read_WindowContact_BatteryCharge(byte Number) {
char NumberAsChar[2];
NumberAsChar[0] = Number + '0';
NumberAsChar[1] = '\0';
int BatteryCharge = 0;
char Path[40] = "/WindowContact_BatteryCharge_";
strcat(Path, NumberAsChar);
strcat(Path, ".txt");
String tmp;
tmp = read_File(Path);
BatteryCharge = tmp.toInt();
//telnet.println("------------------------");
return BatteryCharge;
}
//--------------------------------------------------------------------------------
int read_STATE_WINDOWCONTACT(byte Number) {
char NumberAsChar[2];
NumberAsChar[0] = Number + '0';
NumberAsChar[1] = '\0';
int MK_State = 0;
char Path[30] = "/STATE_WINDOWCONTACT_";
String tmp;
strcat(Path, NumberAsChar);
strcat(Path, ".txt");
//telnet.println(Path);
tmp = read_File(Path);
//telnet.println(tmp);
//telnet.println("------------------------");
MK_State = tmp.toInt();
return MK_State;
}
//--------------------------------------------------------------------------------
void write_System_RestartReason(const char *message) {
write_File("/System_RestartReason.txt", message);
}
//--------------------------------------------------------------------------------
String read_System_RestartReason() {
String message = read_File("/System_RestartReason.txt");
return message;
}
//--------------------------------------------------------------------------------
void LOGread() {
debug("LOG-Dateien einlesen:");
for (byte i = 0; i <= 3; i++) { // Alle 4 LOGs auslesen
char LOGtypeAsChar[2];
LOGtypeAsChar[0] = i + '0';
LOGtypeAsChar[1] = '\0';
char Path[30] = "/LOG_";
strcat(Path, LOGtypeAsChar);
strcat(Path, ".txt");
SD.begin(BUILTIN_SDCARD);
File file = SD.open(Path);
String buffer;
// Erste Zeile > Aktuelle Zeile auslesen
buffer = file.readStringUntil('\n', 150);
LOG.LOG_CurrentLine[i] = buffer.substring(1, 3).toInt() - 10;
// Die Meldungen auslesen:
int x = 0;
for (byte j = 0; j <= LOG.LOG_MaxLines; j++) {
buffer = file.readStringUntil('\n', 150);
debug(buffer);
x = buffer.substring(0, 2).toInt() - 10;
LOG.LOG_STRING[i][j] = buffer.substring(6);
LOG.LOG_STRING_COLOR[i][j] = buffer.substring(3, 4).toInt();
debug(String(j));
debug(LOG.LOG_STRING[i][j]);
}
file.close();
}
}
//--------------------------------------------------------------------------------
// LOGtype: 0 = LOG, 1 = Technisches LOG, 2 = Meldekontakte LOG, 3 = 12h Meldungen Meldekontakte
// Color : 1 = Weiss, 2 = Gelb, 3 = Grün, 4 = Rot
void LOGwrite(int LOGtype, int Color, String message) {
// Zeile in ARRAY einfügen:
LOG.LOG_STRING[LOGtype][LOG.LOG_CurrentLine[LOGtype]] = TimeStamp_Formated() + " " + message;
LOG.LOG_STRING_COLOR[LOGtype][LOG.LOG_CurrentLine[LOGtype]] = Color;
// LOG auf SD-Karte schreiben:
SD.begin(BUILTIN_SDCARD);
char LOGtypeAsChar[2];
LOGtypeAsChar[0] = LOGtype + '0';
LOGtypeAsChar[1] = '\0';
char Path[30] = "/LOG_";
strcat(Path, LOGtypeAsChar);
strcat(Path, ".txt");
if (SD.exists(Path)) {
SD.remove(Path);
}
File file = SD.open(Path, FILE_WRITE);
//Serial.print("open File: ");
//Serial.println(Path);
file.println(">" + String(LOG.LOG_CurrentLine[LOGtype] + 11) + "< // Zuerst die aktuelle Zeile +10, danach folgen die einzelnen Einträge:");
for (byte i = 0; i <= LOG.LOG_MaxLines; i++) {
file.println(String(i + 10) + "_" + String(LOG.LOG_STRING_COLOR[LOGtype][i]) + "_" + LOG.LOG_STRING[LOGtype][i]);
}
file.close();
// Aktuelle Zeile hochzählen:
LOG.LOG_CurrentLine[LOGtype] = LOG.LOG_CurrentLine[LOGtype] + 1;
// Wenn die maximale Anzahl der Zeilen erreicht ist wieder auf 0:
if (LOG.LOG_CurrentLine[LOGtype] == LOG.LOG_MaxLines + 1) {
LOG.LOG_CurrentLine[LOGtype] = 0;
}
}
/*
* my_LOGtoSD.h
*
* Created on: 24.12.2021
* Author: Mike
*/
#ifndef MY_LOGTOSD_H_
#define MY_LOGTOSD_H_
void write_File(const char *path, const char *message);
void write_File(const char *path, double message);
void write_File(const char *path, int message);
void LOGtoSD_begin();
String read_File(const char *path);
// WiFi-Meldekontakte:
void write_WindowContact_WatchdogState(byte Number, const double Timestamp, const int Battery);
void write_STATE_WINDOWCONTACT(byte Number, byte Status);
int read_STATE_WINDOWCONTACT(byte Number);
double read_WindowContact_Last_Report(byte Number);
int read_WindowContact_BatteryCharge(byte Number);
// Warum wurde neu gestartet?
void write_System_RestartReason(const char *message);
String read_System_RestartReason();
void LOGwrite(int LOGtype, int Color, String message);
void LOGread();
struct myLOG {
String LOG_STRING[4][50];
int LOG_STRING_COLOR[4][50];
int LOG_MaxLines = 49;
int LOG_CurrentLine[4];
};
#endif /* MY_LOGTOSD_H_ */
Here the Function to get all Data from SD-Card to the webserver:
Code:
void build_SD_HTML() {
debug("Einstieg in SUB build_SD_HTML()");
debug(" ");
SD.begin(BUILTIN_SDCARD);
String buffer;
HTML_BUFFER_SD = "<!DOCTYPE html><html>"
"<head><meta http-equiv='content-type' content='text/html;charset=utf-8'/>"
"<title>Alarmanlage SD-Karte</title>"
"</head>"
"<body>"
"<h1>SD-Karte:</h1>"
"<p> </p>";
/*
HTML_BUFFER[LOGtype] += "Card type: ";
switch (card.type()) {
case SD_CARD_TYPE_SD1:
HTML_BUFFER[LOGtype] += "SD1";
break;
case SD_CARD_TYPE_SD2:
HTML_BUFFER[LOGtype] += "SD2";
break;
case SD_CARD_TYPE_SDHC:
HTML_BUFFER[LOGtype] += "SDHC";
break;
default:
HTML_BUFFER[LOGtype] += "Unknown";
}
HTML_BUFFER[LOGtype] += "<br />";
uint32_t volumesize;
HTML_BUFFER[LOGtype] += "Volume type is FAT";
HTML_BUFFER[LOGtype] += String(volume.fatType());
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
if (volumesize < 8388608ul) {
HTML_BUFFER[LOGtype] += String("<br />Volume size (bytes): ");
HTML_BUFFER[LOGtype] += String(volumesize * 512); // SD card blocks are always 512 bytes
}
HTML_BUFFER[LOGtype] += "<br />Volume size (Kbytes): ";
volumesize /= 2;
HTML_BUFFER[LOGtype] += String(volumesize);
HTML_BUFFER[LOGtype] += "<br />Volume size (Mbytes): ";
volumesize /= 1024;
HTML_BUFFER[LOGtype] += String(volumesize);
HTML_BUFFER[LOGtype] += "<p> </p>";
*/
HTML_BUFFER_SD += "Listing directory: /";
File root = SD.open("/");
if (!root) {
HTML_BUFFER_SD += "Failed to open directory";
return;
}
if (!root.isDirectory()) {
HTML_BUFFER_SD += "Not a directory";
return;
}
HTML_BUFFER_SD += "<p> </p>";
File file = root.openNextFile();
while (file) {
if (file.isDirectory()) {
HTML_BUFFER_SD += " DIR : ";
HTML_BUFFER_SD += String(file.name());
HTML_BUFFER_SD += "<br />";
} else {
HTML_BUFFER_SD += " FILE: ";
HTML_BUFFER_SD += String(file.name());
HTML_BUFFER_SD += "<br />";
HTML_BUFFER_SD += "<BLOCKQUOTE>";
while (file.available()) {
yield();
buffer = file.readStringUntil('\n', 200);
debug(buffer.length());
debug(buffer);
HTML_BUFFER_SD += "<br />";
HTML_BUFFER_SD += buffer;
}
HTML_BUFFER_SD += "</BLOCKQUOTE>";
HTML_BUFFER_SD += "<p> </p>";
}
file.close();
file = root.openNextFile();
}
//letzte Zeile HTML
HTML_BUFFER_SD += "</body></html>";
root.close();
}