Lesen/Schreiben FRAM klappt nicht

OP (Firma: Q3) #7442697
Lesenswert?

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) #7442747
Lesenswert?

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) #7442881
Lesenswert?

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.

#7442926
Lesenswert?

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) #7442941
Lesenswert?

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.

OP (Firma: Q3) #7443639
Lesenswert?

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.

#7443699
Lesenswert?

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").

#7443897
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren