Daten in SPIFFS speichern und per http server (html) verändern und auslesen

Hallo ich bin neu hier in diesem Forum.
Und habe ein kleines Project am laufen und komme nicht weiter auch nach langer vielleicht auch falscher Recherche, deshalb suche ich jetzt hier Hilfe.

Ich habe vor eine art "Geldsystem" zu machen.
Ich habe mir vorgestellt das ein ESP32 eine Webseite zur Verfügung stellt
auf der man dann Dinge "kaufen" kann. Sobald mann dann "bezahlt" hat wird das bezahlte dem Guthaben abgezogen. Das Guthaben sollte auch irgendwo angezeigt werden.
Soweit das was ich vorhabe.

Mein Problem besteht darin Daten in eine Datei in das SPIFFS zu schreiben diese dann wieder auszulesen und auf einer html-seite dann wiederzugeben und die daten von der html-seite aus wieder zu verändern und im SPIFFS speichern.
Für das SPIFFS habe ich mich entschieden da dort die Daten dauerhaft gespeichert werden.

Hat jemand vielleicht Anregungen nach was ich suchen soll oder gute Beispiele?

Sieh dir mal die Beispiele auf der Website von Fips an.
Da gibt es auch eins zur Nutzung des Spiffs.

Erstmal danke an @HotSystems

Ich habe jetzt einfach knallhart den admin Tab von Fips geändert.
Dieser sieht jetzt so aus:

float Geldint

void adminGeld() {                          // Funktionsaufruf "admin();" muss im Setup eingebunden werden
  WiFi.mode(WIFI_STA);
  File file = SPIFFS.open("/configGeld.json");
  if (file) {
    String Geld = file.readStringUntil('\n');
    if (Geld != "") {
      Geldint.setGeld(Geld.substring(2, Geld.length() - 2).c_str());
      
    }
  }
  file.close();
  server.on("/adminG/once", handleonceG);
}

void handleonceG() {
  if (server.arg(0) != "") {
    Geldint.setGeld(server.arg(0).c_str());
    File file = SPIFFS.open("/configGeld.json", FILE_WRITE);
    file.printf("[\"%s\"]", Geldint.getGeld());
    file.close();
  }
  String fname = String(__FILE__).substring( 3, String(__FILE__).lastIndexOf ('\\'));
  String temp = R"(", "Geld":")" + Geldint.getGeld()
  server.send(200, "application/json", temp);     // Json als Objekt
}

Jetzt kommt natürlich diese Fehlermeldung:

Geld:28:44: error: request for member 'getGeld' in 'Geldint', which is of non-class type 'float'

   String temp = R"(", "Geld":")" + Geldint.getGeld()

wie kann ich das anders festlegen?

wie viele Daten willst speichern?
Wäre für "wenige" Variablen nicht die EEPROM-Emulation einfacher?
EEPROM.put schreiben und EEPROM.commit speichern
EEPROM.get lesen

Ich hätte 5 verschiedene Werte gespeichert die alle bis 100 000 000 000 zahlen gehen sollten.
Haut das von der EEPROM Größe hin oder ist der zu klein?

beschränke dich auf 4,294,967,295 weil uint32_t leichter handzuhaben sind.
Und ja, 5 derartiger 4 Byte Variablen gehen locker rein.
Wenn du dann etwas Übung hast, kannst noch immer auf 64bit Variablen umsteigen...

Danke für deine Antworten.

4 000 000 000 zahlen sind auch gut wenn es dann einfacher zu schreiben geht.

Ich hätte jetzt doch noch zwei Fragen, du hast ja oben 3 befehle geschrieben kann ich die jetzt einfach so
statt Geldint.setGeld
in mein oben geposteten Sketch einbauen oder gehört warscheinlich da noch mehr dazu?
Und zweitens hat der Esp32 überhaupt ein EEPROM?

LG Lukcraft

lukcraft:
Und zweitens hat der Esp32 überhaupt ein EEPROM?

Nein...aber noiasca hat auch "EEPROM-Emulation" geschrieben.

Oh stimmt habe ich versehentlich überlesen :confused:
Wie kann ich uint32_t geld =EEPROM.get; festlegen?
Gibt es da eine allumfassende Seite die das ganze erklärt?

Gibt es da eine allumfassende Seite die das ganze erklärt?

nein keine saubere die ich empfehlen kann.
Aber das Prinzip ist einfach, beim begin() die gewünschte Grüße mitgeben,
gespeichert wird mit commit().
Rest mit put und get ist wie beim UNO.
Adressverwaltung mit struct und offsetOf wie du es auch beim UNO machen würdest damit es einfach bleibt.

Beginne mit der Arduino Referenz

google mal nach

ESP32 EEPROM.begin()
ESP32 EEPROM.commit()

dann wirst schon was finden, ...

Auf der Ardurino Seite steht

Note
An EEPROM write takes 3.3 ms to complete. The EEPROM memory has a specified life of 100,000 write/erase cycles, so you may need to be careful about how often you write to it.

trifft das auch auf den Esp32 zu?

Für den Flash liegen sie eher bei 10.000 Zyklen.
Wenn Du mehr brauchst, nimm FRAM.

Gruß Tommy

Ok ich glaube ich nehme jetzt doch FRAM das ist denke ich besser.
Wird der Sketch zu schreiben dadurch noch schwieriger?
Und könnt ihr mir ein FRAM empfehlen ich hätte jetzt den FM24C16B von Amazon bestellt ich habe aber keine gescheite Dokumentation für so einen gefunden :o

Der ist für Dich schlecht geeignet, da es ein Tyo mit mindestens 4,5V ist.
Du brauchst FRAM für 3,3V.
Dann solltest Du Dir erst mal Gedanken machen, wie groß der sein muss und on Du I2C oder SPI nehmen willst.
Das Datenblatt findet die Suchmaschine Deiner Wahl.

Gruß Tommy

Ich hätte da noch ein FRAM von Adafruit im Angebot der klinkt für mich als unerfahrener Neuling in diesem Gebiet ziemlich gut ;D (besser als der den ich zuerst reingestellt habe

https://www.amazon.de/dp/B00R3OVG36/ref=cm_sw_r_cp_apa_i_E4DkFbSXBHXM9

Den gibt es auch noch größer statt 8KByte 32KByte welcher würde da infrage kommen für 5 x 2,000,000,000 Zahlen?

LG Lukcraft

lukcraft:
Den gibt es auch noch größer statt 8KByte 32KByte welcher würde da infrage kommen für 5 x 2,000,000,000 Zahlen?

Mit 32 Bit kannst Du eine ganze Zahl bis 4.294.967.295 speichern. Du benötigst daher 5 x 32 Bit = 160 Bit = 20 Byte.

Oder habe ich da was mißverstanden?

Generell betrachtet scheint mir die Überlegung, ob man die aufzuhebenen Daten nun im FRAM, EEPROM oder SIFFS ablegt, vom Grundproblem abzulenken. Denn das Speichern von Daten ist relativ einfach. So habe ich OnBoardLed so verändert, um eine Datei zu schreiben:

#define LED_BUILTIN 13
void onboardLed() {
  pinMode(LED_BUILTIN, OUTPUT);     // OnBoardLed Esp32
  server.on("/bled", []() {
    if (server.hasArg("zap")) {
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));    // LED umschalten
      DEBUG_P(digitalRead(LED_BUILTIN) ? "LED ist an" : "LED ist aus");

    File datei = SPIFFS.open("/configGeld.json", FILE_WRITE);
    datei.print("Millis ");
    datei.println(millis());
    datei.close();
    }
    server.send(200, "text/plain", digitalRead(LED_BUILTIN) ? "Aus" : "Ein");
  });
}

Schwieriger erscheint mir das Dirigieren, also was wann an Informationen wohin geschickt wird im Zusammenspiel mit JavaScript.

@TO: Du schreibst immer von 5 x 2,000,000,000 Zahlen. Wie groß sollen die 5*2 Milliarden Zahlen den werden können? Das dürfte ein Platzproblem geben.

Gruß Tommy

Die zahlen sollten alle nicht über 2 Milliarden gehen nicht mehr aber weniger.
Das kann man sich so vorstellen es wird der Geldstand von z.B. Monopoly für jeden spieler gespeichert. Jeder Spieler bekommt ein Account/Website über den er z.B. ein Haus kaufen kann oder sonstiges.
Und eben dieser Geldstand/Daten/Zahlen sollen irgendwo gepeichert abgerufen und verändert werden (kurzgesagt eine Website erstellen mit der man die Daten/Zahlen die gespeichert sind beliebig verändern kann kann)

Bezüglich der Speicherung habe ich mich jetzt für den FRAM (8 KByte) entschieden der in den nächsten Tagen kommen sollte.
Hier https://github.com/adafruit/Adafruit_FRAM_SPI
ist ein möglicher Treiber für diesen FRAM.
Die Diskussion über das Speichermedium gehört also nicht zum Hauptthema. Ich weis nicht wie das in diesem Forum gehandhabt wird von mir aus kann man die Narichten löschen der übersichts Willen (außer wenn für andere die Infos auch nützlich sein könnten wie sie für mich waren) Ich kann ja wenn das Projekt abgeschlossen ist nochmal eine Zusammenfassung schreiben warum ich was gemacht habe. :slight_smile:

Jetzt geht es

  1. nur noch darum Wie man Daten/Zahlen im FRAM liest/schreibt.
  2. Und vorallen Wie die Daten/Zahlen auf einer Website ausgegeben und verändert werden können.

am ESP kannst mit dem ESP Webserver Daten aus einer form ganz einfach als Parameter auslesen. sowohl GET wie auch POST.

@noiasca sorry das habe ich jetzt nicht so ganz verstanden was du jetzt meinst