Lesen/Schreiben FRAM klappt nicht

OP (Firma: Q3) #7442697

Woran könnte es liegen, dass die beiden folgenden Methoden (oder eine von ihnen) nicht korrekt funktionieren? Die I2C-Adresse des FRAM ist 0x50 (80 dezimal), ich schreibe testweise in die Speicherplätze 0-9 die Werte 10,11,12 ... 19, bekomme jedoch beim Lesen immer nur 255 zurück. "sw" ist eine Software-I2C, "softwire". Die funktioniert, das habe ich mit einem angepassten I2C-Scanner-Code getestet, der findet auch brav das FRAM auf 0x50.

1
void fram_write(byte i2c_addr, uint16_t ram_addr, byte value)
2
{
3
  sw.beginTransmission(i2c_addr);
4
  sw.write(ram_addr >> 8);
5
  sw.write(ram_addr);
6
  sw.write(value);
7
  sw.endTransmission();
8
}
9

10
byte fram_read(byte i2c_addr, uint16_t ram_addr)
11
{
12
  sw.beginTransmission(i2c_addr);
13
  sw.write(ram_addr >> 8);
14
  sw.write(ram_addr);
15
  sw.endTransmission();
16
  sw.requestFrom((int)ram_addr, (int)1);
17
  return sw.read();
18
}

Warum ich keine fertige Lib benutze? Keine von denen ist für SoftWire geeignet und soo viel Code ist es ja anscheinend auch nicht, wenn er denn funktionieren würde :-(

OP (Firma: Q3)

Matthias S. schrieb:

Bisher schreibst du da nur blind hin, ohne zu wissen, ob da überhaupt was im FRAM ankommt.

Ja, das klingt sinnvoll, macht aber m.W. keine der Libs, die ich bisher untersucht habe. Viele arbeiten allerdings mit einem unübersichtlichen Wust an globalen Variablen, weshalb ich ziemlich lange gesucht habe

OP (Firma: Q3)

Matthias S. schrieb:

Wie heisst denn das FRAM? Und an deiner Stelle würde ich mal etwas Fehlerabfrage machen, wie z.B. das ACK Bit. Bisher schreibst du da nur blind hin, ohne zu wissen, ob da überhaupt was im FRAM ankommt.

Hättest du ein Beispiel, wie ich das als Boolean-Rückgabewert in der Write-Methode verwenden könnte, statt "void"?

OP (Firma: Q3)

Wastl schrieb:

Frank E. schrieb:

Woran könnte es liegen, dass die beiden folgenden Methoden (oder eine von ihnen) nicht korrekt funktionieren?

Auch an deinem Aufbau und Schaltplan den du nicht zeigen willst.

Wennd der I2C-Scanner den Chip findet, sehe ich da eigentlich kein Problem. Derzeit ist das ein "Aufbau" mit Dupont-Wires ... am Uno

(Firma: matzetronics)

Frank E. schrieb:

Hättest du ein Beispiel, wie ich das als Boolean-Rückgabewert in der Write-Methode verwenden könnte, statt "void"?

Ich weiss ja nicht mal, mit was für einem MC du da rummachst. Wenns AVR wäre, verlasse ich mich da auf die bei mir sehr bewährte Library von PFleury. Für STM32 habe ich hier was für die SPL, was auch Fehler meldet.

Harald K. schrieb:

Und wo ist das r/w-Bit?

Gute Frage. Es müsste ja in der Read Routine Bit 0 gesetzt sein.

Frank E. schrieb:

der findet auch brav das FRAM auf 0x50

im Datenblatt steht aber 0xA0 für schreiben und 0xA1 für lesen (bei A2..A0 =0) Dein Scanner gibt aber 7 Bit Adressen aus. Du must das R/W Bit selber dranpfriemeln. also etwa so:

  • (0x50 << 1) | 0 beim schreiben
  • (0x50 << 1) | 1 beim lesen

Wenn ich mich richtig erinnere machst du den Fehler nicht zum ersten mal. Deine Routinen haben im Lesebetrieb nichts mit der im DB geforderten Sequenz zu tun, und im Schreibbetrieb hast du halt die falsche Adresse. Würdest du auf ACK prüfen würdest du das sofort sehen.

OP (Firma: Q3)

Thomas Z. schrieb:

  • (0x50 << 1) | 0 beim schreiben
  • (0x50 << 1) | 1 beim lesen

Wenn ich mich richtig erinnere machst du den Fehler nicht zum ersten mal. Deine Routinen haben im Lesebetrieb nichts mit der im DB geforderten Sequenz zu tun, und im Schreibbetrieb hast du halt die falsche Adresse. Würdest du auf ACK prüfen würdest du das sofort sehen.

Wie ich schon schrieb, ich habe beide Methoden aus einer anderen, fertigen Lib entnommen, die sind genau so, wie eingangs beschrieben. Werde ich aber heute mal versuchen.

Frank E. schrieb:

Wie ich schon schrieb, ich habe beide Methoden aus einer anderen, fertigen Lib entnommen,

mach es einfach so wie es im DB beschrieben ist und es wird funktionieren. Wie das wire Gedöns mit Ack und dem r/w Bit umgeht musst du dort nachschauen. Übrigens EEprom Libs für 64k EEproms sollten auch funktionieren

OP (Firma: Q3)

Ich habe das Problem jetzt anders gelöst.

Grund für den Einsatz FRAM ist die etwas zu langsame Ausgabe eines Bondruckers in einem Automaten-Prototypen (ca. 5s für ca. 12cm). Das hat leider genügt, dass mancher Kunde meinte, an dem Bon ziehen zu müssen, was das Druckmodul regelmäßig mit einer Fehlermeldung "Papierstau!" missinterpretiert und seinen Betrieb vorläufig einstellt.

Die schnelle Lösung für den im Einsatz befindlichen Prototyp: Die Druckdaten nicht pö-a-pö ausgeben, sondern erstmal (im FRAM) sammeln. Dann erfolgt am Ende die Bonausgabe "in einem Rutsch" schnell genug, so dass niemand mehr Zeit hat, an dem Bon zu zerren.

Aufgrund mechanischer Gegebenheiten wollte ich den FRAM zunächst nicht an die originalen Hardware-Pins für I2C des Arduino Mega anschließen, sondern SoftWire benutzen. Das wiederum klappt nicht auf die Schnelle mit den vorhandenen Libs (Adafruit u.a.), die sind alle auf Wire ausgelegt.

Nach 2 Tagen Zeitverschwendung habe ich nun doch eine kleine Adapterplatine gebaut, die sogar vom Kunden vor Ort einfach aufgesteckt werden kann. Die geänderte Firmware läuft nun mit der Adafruit-I2C-FRAM-Lib und FIFO-Druckerpuffer, die kann ich über Fernzugag einspielen.

Frank E. schrieb:

Die schnelle Lösung für den im Einsatz befindlichen Prototyp: Die Druckdaten nicht pö-a-pö ausgeben, sondern erstmal (im FRAM) sammeln.

Und warum muss das dann FRAM sein? Stinknormales SRAM täte es auch und dürfte deutlich weniger kosten.

Daß /während/ des Druckvorganges die Stromversorgung ausfällt, dürfte eher unwahrscheinlich sein (oder das Gerät ist sehr, sehr merkwürdig "designt").

Frank E. schrieb:

Harald K. schrieb:

Frank E. schrieb:

Und warum muss das dann FRAM sein? Stinknormales SRAM täte es auch und dürfte deutlich weniger kosten.

Gibts I2C-Ram? Habe keinen auf einem breakout für Arduino-Umgebung gefunden. Und seriell muss auch sein, wegen der Anzahl der freien Pins.

Google schon wieder Offline? (Sorry, musste jetzt mal sein…)

https://www.mouser.de/c/semiconductors/memory-ics/sram/?interface%20type=I2C

Nachtrag: die Frage wäre bei mir eher, warum die lahme I2C jetzt sRAM bedienen soll. Aber ja, vielleicht mangels freier Pins…

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 3 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.