"Ältestes" File auf SD löschen (vorm: Zurodnung mehrdimensionales Array)

Hallo liebe Leute,

ich habe ein Problem.

Irgendwie funktioniert die Zuordnung meiner Werte zu dem mehrdimensionalen Array nicht.

Was ich versuche zu tun: Ich trenne die Strings bei () auf und konvertiere sie in int und versuche diese dann in ein mehrdimensionales Array zu schreiben- also das was vor dem () war in die erste Zeile und das was nach dem "_" war in die zweite Zeile.
Leider läuft beim index 0 etwas falsch, da steht nicht der aufgeteilte string drin sondern ein string der erst später sein sollte.

Wenn jemand so nett wäre mir zu helfen, wäre ich sehr dankbar.

Schönen Tag noch!

Ps. was ich damit versuche ist, die Filenamen von einer sd card (JahrMonatTagStundeMinute.log) zu sortieren, damit ich dann falls die SD voll ist, das älteste File löschen kann also sowas wie einen FIFO.

Hier mein codebeispiel:

String filelist[9] = {"/20220719_0945.log", "/20220819_0945.log", "/20230817_0945.log", "/20230818_0945.log", "/20230818_0953.log", "/20230818_2136.log", "/20230819_0942.log", "/20230819_0945.log", "/20240819_0947.log"};
int filelist_length;
int filename_act_length;
int str_geteilt1_int;
int str_geteilt2_int;
String filename_act;
char *str_geteilt1;
char *str_geteilt2;
int filelist_int[2][8];

void sort_sd_files() {
  filelist_length = sizeof(filelist) / sizeof(filelist[0]);
  Serial.print("filelist_length: "); Serial.println(filelist_length);  //debug
  int filname_arr_int[2][filelist_length - 1];
  for (int i_sort = 0; i_sort <= filelist_length - 1; i_sort++) {
    Serial.print("Durchlauf: "); Serial.println(i_sort); //debug
    filename_act = filelist[i_sort];
    filename_act.remove(0, 1);
    Serial.print("filename_act after remove: "); Serial.println(filename_act); //debug
    filename_act_length = sizeof(filename_act) + 2;
    //Serial.print("filename_act length str array: "); Serial.println(filename_act_length); //debug
    char str_array[filename_act_length];
    filename_act.toCharArray(str_array, filename_act_length);
    Serial.print("filename_act str array: "); Serial.println(str_array); //debug

    str_geteilt1 = strtok(str_array, "_");
    str_geteilt2 = strtok(NULL, "_");
    //strtok(NULL, "." );
    Serial.print("geteilter string 1: "); Serial.println(str_geteilt1);  //debug
    Serial.print("geteilter string 2: "); Serial.println(str_geteilt2);  //debug

    str_geteilt1_int = atoi(str_geteilt1);
    str_geteilt2_int = atoi(str_geteilt2);

    filname_arr_int[0][i_sort] = str_geteilt1_int;
    filname_arr_int[1][i_sort] = str_geteilt2_int;
    filelist_int[0][i_sort] = str_geteilt1_int;
    filelist_int[1][i_sort] = str_geteilt2_int;
  }

  for (int i_sort = 0; i_sort <= filelist_length - 1; i_sort++) {
    Serial.print("Durchlauf: "); Serial.println(i_sort); //debug
    Serial.print("filename bevore sort "); Serial.print(i_sort); Serial.print(": "); Serial.print(filelist_int[0][i_sort]); Serial.print("_"); Serial.println(filelist_int[1][i_sort]);  //debug
    Serial.print("filename bevore sort "); Serial.print("[0]"); Serial.print("["); Serial.print(i_sort);  Serial.print("]"); Serial.println(filname_arr_int[0][i_sort]);
    Serial.print("filename bevore sort "); Serial.print("[1]"); Serial.print("["); Serial.print(i_sort);  Serial.print("]"); Serial.println(filname_arr_int[1][i_sort]);
  }//debug

}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(500);
  sort_sd_files();
}

void loop() {
  // put your main code here, to run repeatedly:

}

Warum muss das String sein?

Hey, danke für die antwort.

Muss es nicht.
Ich lese die filenamen mit filename_akt = entry.name(); aus und habe ich als String filename_akt definiert.

Hättest du eine bessere Idee?

Vermutlich aber weil es mit Strings am einfachten ist aber ja mc und strings sind nicht so gut, das weiß ich schon..

Lg

#include <Streaming.h> // die Lib findest du selber ;-)
Print &cout = Serial; // cout Emulation für "Arme"

template<typename T, size_t N> size_t arrayCount(T(&)[N]){ return N; }

String filelist[] = {"/20220719_0945.log", "/20220819_0945.log", "/20230817_0945.log", "/20230818_0945.log", "/20230818_0953.log", "/20230818_2136.log", "/20230819_0942.log", "/20230819_0945.log", "/20240819_0947.log"};

int compare_string (const void *a, const void *b)
{
 // return (*(String*)a).compareTo(*(String*)b); // aufsteigend
  return (*(String*)b).compareTo(*(String*)a); // absteigend
}

void setup() 
{
  Serial.begin(9600);
  cout << F("Start: ") << F(__FILE__) << endl;
  
  cout << "vor dem sortieren:" << endl;
  for(String &s:filelist) cout << s  << endl;
  
  qsort(filelist,arrayCount(filelist),sizeof(String),compare_string);
  
  cout << "nach dem sortieren:" << endl;
  for(String &s:filelist) cout << s  << endl;
}

void loop() 
{

}

Hier solltest Du besser jeweils ein Element mehr spendieren. Noch besser läßt Du es berechnen, machst du ja, nutzt es aber nicht konsequent.

Bereichsüberschreitungen von Feldern sind blöd zu findende Laufzeitfehler.

Programm getestet mit ESP32
String filelist[9] = {"/20220719_0945.log", "/20220819_0945.log", "/20230817_0945.log", "/20230818_0945.log", "/20230818_0953.log", "/20230818_2136.log", "/20230819_0942.log", "/20230819_0945.log", "/20240819_0947.log"};
const int filelist_length = sizeof(filelist) / sizeof(filelist[0]);
int filename_act_length;
int str_geteilt1_int;
int str_geteilt2_int;
String filename_act;
char *str_geteilt1;
char *str_geteilt2;
int filelist_int[2][filelist_length];

void sort_sd_files() {
  Serial.print("filelist_length: "); Serial.println(filelist_length);  //debug
  int filname_arr_int[2][filelist_length];
  for (int i_sort = 0; i_sort < filelist_length; i_sort++) {
    Serial.print("Durchlauf: "); Serial.println(i_sort); //debug
    filename_act = filelist[i_sort];
    filename_act.remove(0, 1);
    Serial.print("filename_act after remove: "); Serial.println(filename_act); //debug
    filename_act_length = sizeof(filename_act) + 2;
    //Serial.print("filename_act length str array: "); Serial.println(filename_act_length); //debug
    char str_array[filename_act_length];
    filename_act.toCharArray(str_array, filename_act_length);
    Serial.print("filename_act str array: "); Serial.println(str_array); //debug

    str_geteilt1 = strtok(str_array, "_");
    str_geteilt2 = strtok(NULL, "_");
    //strtok(NULL, "." );
    Serial.print("geteilter string 1: "); Serial.println(str_geteilt1);  //debug
    Serial.print("geteilter string 2: "); Serial.println(str_geteilt2);  //debug

    str_geteilt1_int = atoi(str_geteilt1);
    str_geteilt2_int = atoi(str_geteilt2);

    filname_arr_int[0][i_sort] = str_geteilt1_int;
    filname_arr_int[1][i_sort] = str_geteilt2_int;
    filelist_int[0][i_sort] = str_geteilt1_int;
    filelist_int[1][i_sort] = str_geteilt2_int;
  }

  for (int i_sort = 0; i_sort < filelist_length; i_sort++) {
    Serial.print("Durchlauf: "); Serial.println(i_sort); //debug
    Serial.print("filename bevore sort "); Serial.print(i_sort); Serial.print(": "); Serial.print(filelist_int[0][i_sort]); Serial.print("_"); Serial.println(filelist_int[1][i_sort]);  //debug
    Serial.print("filename bevore sort "); Serial.print("[0]"); Serial.print("["); Serial.print(i_sort);  Serial.print("]"); Serial.println(filname_arr_int[0][i_sort]);
    Serial.print("filename bevore sort "); Serial.print("[1]"); Serial.print("["); Serial.print(i_sort);  Serial.print("]"); Serial.println(filname_arr_int[1][i_sort]);
  }//debug

}


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(500);
  sort_sd_files();
}

void loop() {
  // put your main code here, to run repeatedly:

}
serieller Monitor
filelist_length: 9
Durchlauf: 0
filename_act after remove: 20220719_0945.log
filename_act str array: 20220719_0945.log
geteilter string 1: 20220719
geteilter string 2: 0945.log
Durchlauf: 1
filename_act after remove: 20220819_0945.log
filename_act str array: 20220819_0945.log
geteilter string 1: 20220819
geteilter string 2: 0945.log
Durchlauf: 2
filename_act after remove: 20230817_0945.log
filename_act str array: 20230817_0945.log
geteilter string 1: 20230817
geteilter string 2: 0945.log
Durchlauf: 3
filename_act after remove: 20230818_0945.log
filename_act str array: 20230818_0945.log
geteilter string 1: 20230818
geteilter string 2: 0945.log
Durchlauf: 4
filename_act after remove: 20230818_0953.log
filename_act str array: 20230818_0953.log
geteilter string 1: 20230818
geteilter string 2: 0953.log
Durchlauf: 5
filename_act after remove: 20230818_2136.log
filename_act str array: 20230818_2136.log
geteilter string 1: 20230818
geteilter string 2: 2136.log
Durchlauf: 6
filename_act after remove: 20230819_0942.log
filename_act str array: 20230819_0942.log
geteilter string 1: 20230819
geteilter string 2: 0942.log
Durchlauf: 7
filename_act after remove: 20230819_0945.log
filename_act str array: 20230819_0945.log
geteilter string 1: 20230819
geteilter string 2: 0945.log
Durchlauf: 8
filename_act after remove: 20240819_0947.log
filename_act str array: 20240819_0947.log
geteilter string 1: 20240819
geteilter string 2: 0947.log
Durchlauf: 0
filename bevore sort 0: 20220719_945
filename bevore sort [0][0]20220719
filename bevore sort [1][0]945
Durchlauf: 1
filename bevore sort 1: 20220819_945
filename bevore sort [0][1]20220819
filename bevore sort [1][1]945
Durchlauf: 2
filename bevore sort 2: 20230817_945
filename bevore sort [0][2]20230817
filename bevore sort [1][2]945
Durchlauf: 3
filename bevore sort 3: 20230818_945
filename bevore sort [0][3]20230818
filename bevore sort [1][3]945
Durchlauf: 4
filename bevore sort 4: 20230818_953
filename bevore sort [0][4]20230818
filename bevore sort [1][4]953
Durchlauf: 5
filename bevore sort 5: 20230818_2136
filename bevore sort [0][5]20230818
filename bevore sort [1][5]2136
Durchlauf: 6
filename bevore sort 6: 20230819_942
filename bevore sort [0][6]20230819
filename bevore sort [1][6]942
Durchlauf: 7
filename bevore sort 7: 20230819_945
filename bevore sort [0][7]20230819
filename bevore sort [1][7]945
Durchlauf: 8
filename bevore sort 8: 20240819_947
filename bevore sort [0][8]20240819
filename bevore sort [1][8]947

:disguised_face: before :nerd_face:

Hallo,

herzlichen dank für deine Zeit und deine Hilfe!
Funktioniert soweit prima.
Muss mir nur mehr überlegen wie ich mit den vielen Dateinamen umgehe, da viele Files auf der sd liegen..

Aber ich bin dir wirklich dankbar!

Hoffe du hasttest und hast noch einen schönen Tag!

Hallo,

auch dir danke fürs antworten!
Ums zu verstehen werde ich es dann noch probieren.
Versuchs aber gerade mit combie seiner/ihrer antwort.

Lg

hat deine SD Library support für long file names?
Nicht dass du da ohnehin auf 8.3 beschränkt bist ...

ja das hat mich auch gewundert das die Filanes passen. Habe im internet auch gelsesen dass nur 13 zeichen gehen, aber bei mir geht sich das mit (JahrMonatTag_StundeMinuteSekunde-> 20230819_180452) aus.

Edit: meine Filname ist ein String kein long int der so aussieht wie oben beschrieben und das funktioniert soweit.

Hab jetzt nur mehr das Problem, dass ich alles verwefen muss, da es mit den Strings nicht funktionieren wird.
Da ein File bei mir ca. 45kB groß ist und wenn ich eine 2GB Karte nehme, dann gehen ca. 44444 Files darauf.
Somit habe ich demetsprechend gleich file filnames und das packt der ESP32 nicht.

Keine Ahnung ob jemand vlt eine ide hat, wie ich bei einer vollen SD einfach das älteste File löschen kann- also wie ein FIFO.

Danke

lg

so lange das jeweils älteste File löschen bis das schreiben des neuen Files erfolgreich war.

Ja wie finde ich das älteste file heraus?
Deshalb wollte ich ein array machen das sortiert ist aber wie gesagt bei 44444 Files die dort drauf sein können, schafft der ESP32 das sortieren nicht mehr.

Mir fehlt die Idee wie ich den Namen des ältesten Files herausfinden kann um dann das zu löschen..

Lg

du musst ja gar nicht sortieren.
Lies ein file nach dem anderen.
Merk dir das ältere
Ist das nächste File älter merkst dir das.
usw.
du hast nur immer zwei Filenamen im Speicher.
bist mit 44TSD durch ... weist was das älteste ist.

2 Likes

Ui stimmt ja!!!

Ich bin so blöd, dabei ist die Antwort ja so naheliegend.
Dann werd ich das gleich mal versuchen.

Danke für den super tipp und mit dem programm von combie sollte das bald funktionieren.

Super, bin euch mega dankbar.

Melde mich falls es was gibt oder wenn ichs dann geschafft habe..
Danke an alles!

Am Uno/Mega hab ich da mal was ähnliches gemacht da suche ich auch nach dem "ältsten" File damit ich das als erstes zum Server übertragen kann:

http://werner.rothschopf.net/microcontroller/202208_arduino_webclient_sd_saf_ntp.htm

vieleicht ist was drinnen.

1 Like

Danke für den Link, sehe ich mir gleich mal an

Lg

Selbst ein UNO kann mit der Bibliothek SdFat lange Dateinamen nutzen. Habe ich mal für MP3-Dateinamen mit dem Musiktitel benötigt.

Der ESP32 hat mehr Speicher zur Verfügung und kann daher manche speichersparenden Beschränkungen überspringen.

Eine Salamischeibe dazu!
Natürlich verwendet man auf dem ESP "Iteratoren Container Suchen Sortieren Vergleichen", alles in der Libstdc++ fertig vorgekaut und mitgeliefert

Und natürlich kann man auch über Verzeichnisse iterieren. ohne sich 4000 Dateinamen gleichzeitig in den Speicher zu stecken.

Bedenke:
Du hast nach Y gefragt, willst aber X erledigen.
Meine Antwort bezog sich auf Y und liefert dafür eine Lösung.
Diese ist auf X nicht anwendbar bzw. unsinnig.
Lesetipp: XY-Problem

Ja ich weis das deine Lösung nicht dafür gedacht ist aber ich habe daraus was gelernt und versuche damit selbst was weiter zu schaffen.
Falls ich stecken bleibe hoffe ich das jemand so nett wie du ist und mir tipps gibt.

Aber zuerst versuche ich es gerne selbst mal und das von dir hat doch auch für mich zumindest für Y geholfen.
Kann aber auch sein das ich einfach nicht genug dazu weiß.

Danke trotzdem für den hinweis!!!

Aber ich komme morgen sicher mit einer neuen frage :slight_smile:

Schönen Abend alle!

Von einem Wissenschaftler, der Materialeigenschaften nahe des absoluten Nullpunkts erforschte, habe ich gelesen: "Manche Fragen kann man erst dann richtig formulieren, wenn man die Antwort kennt!"

Da stimme ich zu.
Meist weiß man erst beim Ergebnis welche Fragen die richtigen gewesen wären um schnell dort hin zu kommen.
Aber durch Umwege lernt man dazu...