Forum: Mikrocontroller und Digitale Elektronik ESP32 SPIFFS Multidimensionales Array speichern / laden


von Arnold A. (arnold1977)


Lesenswert?

Hallo zusammen,

ich habe ein Array (bin mir nicht sicher, ob der Begriff so passt):
uint8_t vals[18][3];

klar, könnte ich jetzt via Loop alle Felder in eine Textdatei schreiben. 
Aber gibt es auch "Elegante Varianten"?

Meine Idee wäre, das ganze einfach via memcpy in ein Chararray 
schreiben. Und auf dem Rückweg aus dem Chararray wieder in mein "vals" 
schreiben.

Leider bekomme ich das nicht wirklich hin.

Freue mich über jeden Tipp.

Grüße

von Falk B. (falk)


Lesenswert?

Arnold A. schrieb:
> ich habe ein Array (bin mir nicht sicher, ob der Begriff so passt):
> uint8_t vals[18][3];

Das ist ein Array.

> klar, könnte ich jetzt via Loop alle Felder in eine Textdatei schreiben.
> Aber gibt es auch "Elegante Varianten"?

Was ist daran nicht elegant?

> Meine Idee wäre, das ganze einfach via memcpy in ein Chararray
> schreiben.

Und dann? Das kann man nicht direkt in eine Textdatei ausgeben, 
bestenfalls in eine Binärdatei. Dafür braucht es aber nicht dem Umweg 
des char-Arrays, das kann man mit deinem Array auch direkt.

> Leider bekomme ich das nicht wirklich hin.

Sag erstmal, was INSGESAMT erreicht werden soll, siehe Netiquette.

von Arnold A. (arnold1977)


Lesenswert?

das ist einfach nur ein Array für 18 LEDs mit jeweils HUE, SAT und VAL 
werten...

Ich hab mich gegen Typedef/Strukt entschieden, weil das ganze Speicher 
Technik "minimal" schlanker ist und ich nicht mit List arbeiten muss.
Und da die Werte alle uint8 sind, hat mir die Idee gut gefallen.

Das ganze via Loop in eine Textdatei zu schreiben, bedeutet auch, dass 
ich anschließend die Textdatei wieder "zerlegen" muss. Das ist nicht 
sonderlich aufwendig und wenn ich ehrlich bin sogar schon fertig.

Aber es fühlt sich so "umständlich" an.

Grüße

von Falk B. (falk)


Lesenswert?

Arnold A. schrieb:
> das ist einfach nur ein Array für 18 LEDs mit jeweils HUE, SAT und VAL
> werten...
>
> Ich hab mich gegen Typedef/Strukt entschieden, weil das ganze Speicher
> Technik "minimal" schlanker ist

Nö.

> und ich nicht mit List arbeiten muss.

List?

> Und da die Werte alle uint8 sind, hat mir die Idee gut gefallen.

Schlechte Idee. Variablen sollten so weit wie möglich selbsterkärende 
Namen haben, so auch hier.
1
typedef struct {
2
    uint8_t hue;
3
    uint8_t sat;
4
    uint8_t val;
5
} led_t;
6
7
led_t my_leds[18];

Damit weiß man im Programm, was die Daten bedeuten und spart sich die 
Kommentare.

von Arnold A. (arnold1977)


Lesenswert?

ja...
Das Konzept habe ich bislang gemieden, ist aber eine Option...

Hilft mir aber bei meiner Problemstellung exakt 0
> Wenn du mir jetzt die Lösung an die Hand gibst, wie ich das ganze "elegant" in 
den Speicher laden kann käme ich weiter.
> Wie gesagt, mir gefällt der Loop und das Split nicht sehr gut... genauso über 50 
Dateien anlegen eher fraglich ^^

von Martin (Gast)


Lesenswert?

Beachte aber :


SPIFFS Deprecation Warning

SPIFFS is currently deprecated and may be removed in future releases of 
the core. Please consider moving your code to LittleFS. SPIFFS is not 
actively supported anymore by the upstream developer, while LittleFS is 
under active development, supports real directories, and is many times 
faster for most operations.


https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html#spiffs-deprecation-warning

von STK500-Besitzer (Gast)


Lesenswert?

Falk B. schrieb:
1
typedef struct {
2
    uint8_t hue;
3
    uint8_t sat;
4
    uint8_t val;
5
} led_t;
6
led_t my_leds[18];
7
[/c}
8
9
Und wenn man "lustig" ist, packt man die struct in eine union, damit man sie 
10
als Array verschicken kann:
11
[c]
12
typedef struct {
13
    uint8_t hue;
14
    uint8_t sat;
15
    uint8_t val;
16
} led_t;
17
typdef union {
18
    led_t ledData;
19
    uint8_t array[3];
20
} sendableLedData_t;
21
sendableLedData_t my_leds[18];

Dabei muss man den Endian des Compilers beachten, und ggf. die per 
#pragma die Structgröße setzen, weil sind das Alingnment nicht stimmt.
Ich kann mich aber auch mal wieder irren.

von Martin (Gast)


Lesenswert?

Arnold A. schrieb:
> Hilft mir aber bei meiner Problemstellung exakt 0
>> Wenn du mir jetzt die Lösung an die Hand gibst, wie ich das ganze "elegant" in
> den Speicher laden kann käme ich weiter.
>> Wie gesagt, mir gefällt der Loop und das Split nicht sehr gut... genauso über 
50
> Dateien anlegen eher fraglich ^^


Warum muss es eine Textdatei sein und keine Binärdatei?

Was für ein Split?

Zeig mal deinen gesamten Code. Sonst wird das alles Glaskugelraten.

von Philipp K. (philipp_k59)


Lesenswert?

Du könntest eine kleine Partition als Transparent Cache anlegen, da 
bekommst du einen Pointer in die Partition als wenn es Ein 
Speicherpointer wäre.. da kannst du Binär ohne Overhead wilde sau 
spielen.

von STK500-Besitzer (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Dabei muss man den Endian des Compilers beachten,

"Controllers" statt "Compilers" war gemeint.

von noiasca (Gast)


Lesenswert?

Arnold A. schrieb:
> Freue mich über jeden Tipp.

der richtige Weg Daten am ESP32 zu persistieren wäre dafür die Nutzung 
von "Preferences"

https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/preferences.html

von EAF (Gast)


Lesenswert?

noiasca schrieb:
> der richtige Weg Daten am ESP32 zu persistieren wäre dafür die Nutzung
> von "Preferences"
Macht das auch ein wear leveling, so wie die Flash-FS Varianten?

von J. S. (jojos)


Lesenswert?

Abhängig von den Randbedingungen würde ich sogar eher JSON nehmen. 
Binärdateien haben den Nachteil das die Daten bei Änderungen an der 
Struktur inkompatibel sind.
Mit ArduinoJSON ist sehr einfach weil man auch da die Daten als Array 
von Strukturen abbilden kann.
Beispiele siehe https://arduinojson.org/

von Philipp_K59 (Gast)


Lesenswert?

In Arduino habe ich das eindimensional mal so gelöst, müsste man halt 
schauen ob das auch mit struct geht, bzw wie man das dann umgeht:
1
int mainconfig[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2
3
bool loadConfig() {
4
  File configFile = SPIFFS.open("/config.json", "r");
5
  if (!configFile) {
6
    Serial.println("Failed to open config file");
7
    return false;
8
  }
9
  size_t size = configFile.size();
10
  if (size > 2000) {
11
    Serial.println("Config file size is too large");
12
    return false;
13
  }
14
  std::unique_ptr<char[]> buf(new char[size]);
15
  configFile.readBytes(buf.get(), size);
16
  StaticJsonBuffer<2000> jsonBuffer;
17
  JsonObject& json = jsonBuffer.parseObject(buf.get());
18
  if (!json.success()) {
19
    Serial.println("Failed to parse config file");
20
    return false;
21
  }
22
  json["mainconfig"].as<JsonArray>().copyTo(mainconfig);
23
  configFile.close();
24
  return true;
25
}
26
27
bool saveConfig() {
28
  StaticJsonBuffer<2000> jsonBuffer;
29
  JsonObject& root = jsonBuffer.createObject();
30
  JsonArray& array4 = root.createNestedArray("mainconfig");
31
  array4.copyFrom(mainconfig);
32
  File configFile = SPIFFS.open("/config.json", "w");
33
  if (!configFile) {
34
    Serial.println("Failed to open config file for writing");
35
    return false;
36
  }
37
  root.printTo(configFile);
38
  configFile.close();
39
  return true;
40
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.