Fragen zu FRAM und dessen Nutzung

Nabend,

ich habe es endlich mal geschafft mein 32 KBytes FRAM Breakoutboard richtig zu testen, aktuell betreibe ich es mit der Adafruit Lib, was eigentlich auch schon ganz gut funktioniert. Aber ich habe noch ein paar Fragen.

Die Daten werden Byteweise geschrieben (fram.write8()) und gelesen (fram.read8()), in meinem Testsketch deklariere ich einen char[], mit einem festen Inhalt der im FRAM geschrieben werden soll und einen char mit einer fiktiven Größe in dem der Inhalt des FRAM eingelesen werden soll, die Deklaration erfolgt im Header. Damit schaffe ich es bereits den char oder dessen Inhalt im FRAM mit beliebiger Startadresse zu speichern und den danach auszulesen, durch das automatisch gesetzte Zeichen 0x0 erkennt der Sketch auch wann Schluss ist.

Das Problem ist aber, dass die Größe der char arrays nicht immer vorher bekannt sind, gewisse Werte kann ich vorher größenmäßig einordnen, aber nicht alle.

  1. Wie kann ich den jeweiligen char arrays die jeweils korrekte Größe dynamisch zuweisen, besonders dem einzulesenden Array?

  2. Habt ihr zum folgende Sketch noch weitere Hinweise/Verbesserungen, fällt euch was auf was ich besser machen kann?

#include <Wire.h>
#include "Adafruit_FRAM_I2C.h"

Adafruit_FRAM_I2C fram = Adafruit_FRAM_I2C();
uint16_t framAddr = 0;
char writeName[] = "Das ist ein Test!";
char readName[20];
bool StateFram;

void setup(void) {
  Serial.begin(115200);
  if (fram.begin()) {  // you can stick the new i2c addr in here, e.g. begin(0x51);
    StateFram = true;
    Serial.println(F("Found I2C FRAM"));
  } else {
    StateFram = false;
    Serial.println(F("I2C FRAM not identified ... check your connections?\r\n"));
    Serial.println(F("Will continue in case this processor doesn't support repeated start\r\n"));
  }
  framTest();
  delay(1000);
}

void loop(void) {
}

void framTest() {
  if (StateFram) {
    byte Size = sizeof(writeName);
    Serial.print(F("Sizeof: ")); Serial.println(Size);
    for (int i = 0; i < Size; i++)
    {
      fram.write8(i, writeName[i]);
    }
    //fram.write8(Size, 255);

    int j = 0;
    while (1)
    {
      readName[j] = fram.read8(j);
      Serial.print(j); Serial.print(F(" 0x")); Serial.print(readName[j], HEX); Serial.print(F(" "));
      if (readName[j] == '\0')
      {
        Serial.println("");
        break;
      }
      j++;
    }
    Serial.println(readName);
  }
}

Ein Umstieg z.B. auf die von Tommy56 mitentwickelte FRAM-Lib aus dem Nachbarforum, ist nicht ausgeschlossen, vorher möchte ich aber ein bisschen Praxiswissen dazu sammeln.

Gruß
Jörg

Ich habe hier eine FRAM-Lib (I2C) gebaut (bis zum Ende lesen), die alle beliebigen Daten am Stück schreiben und lesen kann.

Gruß Tommy

  1. Wie kann ich den jeweiligen char arrays die jeweils korrekte Größe dynamisch zuweisen, besonders dem einzulesenden Array?

Soviel ich weiß ist das eine gefährliche Sache da Arduino keine Gabage Collection hat udn jeder neu erzeugte Array (String) neues RAM belegt ohne das alte weiter zu benutzen.
Grüße Uwe

Da gebe ich Dir völlig Recht. Die Benutzung der Klasse String und dynamischer char-Arrays ist zu vermeiden.
@TO: Plane Deine Applikation ordentlich, dann brauchst Du meistens nur 1 Puffer mit der maximal zu erwartenden Größe. Ist diese zu groß, ist der Prozessor dafür nicht geeignet.

Gruß Tommy

Tommy56:
Ich habe hier eine FRAM-Lib (I2C) gebaut (bis zum Ende lesen), die alle beliebigen Daten am Stück schreiben und lesen kann.

Gruß Tommy

Deine Lib schaue ich mir auf jeden Fall mal an, ich bin mit meiner Suche auf einen anderen Thread gestoßen.

uwefed:
Soviel ich weiß ist das eine gefährliche Sache da Arduino keine Gabage Collection hat udn jeder neu erzeugte Array (String) neues RAM belegt ohne das alte weiter zu benutzen.
Grüße Uwe

Speicherprobleme will ich nach Möglichkeit natürlich verhindern :wink:

Tommy56:
Da gebe ich Dir völlig Recht. Die Benutzung der Klasse String und dynamischer char-Arrays ist zu vermeiden.
@TO: Plane Deine Applikation ordentlich, dann brauchst Du meistens nur 1 Puffer mit der maximal zu erwartenden Größe. Ist diese zu groß, ist der Prozessor dafür nicht geeignet.

Gruß Tommy

String vermeide ich wo es nur geht, wenn überhaupt habe ich Strings nur unbewusst verwendet. Aber ein gewisses Speicherschema habe ich schon vorbereitet und kann dadurch auch den Speicherplatz einschätzen. Ich hatte nur die Hoffnung, dass ich die Aufgabe beim Einlesen automatisieren könnte, aber wenn das nicht möglich ist, muss ich Größen halt festlegen.

Danke Euch Beiden

Tommy56:
Ich habe hier eine FRAM-Lib (I2C) gebaut (bis zum Ende lesen), die alle beliebigen Daten am Stück schreiben und lesen kann.

Gruß Tommy

So Tommy, deine Lib hab ich jetzt erfolgreich testen können, einfacher geht es ja schon fast gar nicht! :smiley: Der Compiler bemängelt zwar 3 deklarierte aber ungenutzte Variablen (F_RAM_write(): int rc, F_RAM_read(): int rc und fillHex(): byte t), es wird trotzdem kompiliert. Für meinen Teil werde ich die Variablen einfach rausschmeißen.

Getestet hab ich die Lib mit der Ziffernfolge (uint32_t) 1234567890 und einem char array "Das ist ein Test!", wird alles gespeichert und ausgelesen.

Ich bin mehr als zufrieden, geniale Arbeit, kann ich als (semi)Laie nur sagen! :slight_smile: :smiley:

Kleine Frage noch, setzt die Lib nach dem Schreibvorgang (über mehrere Byteslänge) automatisch ein Trennzeichen (\0)? Sonst wird das Auslesen mehrerer Adressen/Werte etwas kompliziert, oder tue ich mich da nur etwas schwer mit?

Edit: Die Variablen sind doch in Gebrauch (rc = Wire.endTransmission();), keine Ahnung warum der meckert.
Die Variablen rc sind zwar deklariert und mit rc = Wire.endTransmission(); zugewiesen, aber die einzige Nutzung ist in F_RAM_write(), im auskommentierten Serial.print. in F_RAM_read() wird die nicht mehr genutzt und Variable t wird in fillHex() nicht zugewiesen. Daher denke ich, dass ich die gefahrlos löschen kann.
Edit2: Gefahrlos löschen ist nicht, sonst kommt nur Kauderwelsch raus, hab ein "if (rc) {};" und if (t) {}; hinzugefügt, Meldungen sind weg. :wink:

Das '\0' musst Du selbst mit anhängen.

Gruß Tommy

Ok, danke. Werde ich am Wochenende mal ausbauen und testen.

Gruß
Jörg