Wie oben schon gesagt, ich sammele alle Zeichen in einen Puffer und bearbeite sie erst nach dem CR.
genau so!
|
Anzeige
|
Arduino: page-write in I2C eeprom verliert sporadisch ein Byte
genau so!
Aus dem Grund hat meine I2C Klasse, welche ich vor einiger Zeit in diesem Thread vorgestellt habe, einen CallBack um die EEPROM Wartezeit eben nicht zu verplempern. Hallo Nemopuk, Helmut H, Joachim B, Klaus (feelfree) und Veit, vielen herzlichen Dank für eure hilfreichen Anregungen und Antworten. Nemopuk:
Wichtigster Punkt: Die 20ms sind der ausgewogenen Reaktion auf die Fernbedienung geschuldet. Nichts nervt hier mehr, als verzögerte Reaktion oder wenn Tastendrücke verloren gehen. Das Gesamtprogramm ist nicht blockierend. Jede Funktion in der Loop wird zyklisch aufgerufen und arbeitet dann einen ihre Aufgabe ab. So kann zum Beispiel das LED-Fading oder eine Melodie ungestört weiterlaufen, während beliebige andere Funktionen ausgeführt werden. Helmut:
Vielen Dank - super Lib - nur leider ist mein Flash fast voll..... Beim nächsten Projekt bestimmt. Joachim:
Der ATMEGA 1284 ist ein 40-Pinner. Meine Platine mit ATMEGA328P (28-Pin) ist bereits gefertigt und funktioniert einwandfrei. Klaus:
Genau das meinte ich damit: bestimmen, wie viel Platz für den Page-Write bleibt, diese Anzahl abwarten und dann Schreiben. Es muss aber ein Timeout geben, wenn das Ende der Übertragung erreicht ist, aber bis zum Erreichen des Page-Endes noch Daten fehlen. Veit: diese Antwort fällt mir schwer - es tut mir leid, wenn ich dir das Gefühl vermittelt habe, deine Vorschläge zu ignorieren. Das ist definitiv nicht so! Nochmal: wirklich vielen Dank für deine Mühe mit dem Testen und Verbessern meines Minimal-Sketches! Ich habe deine Vorschläge nicht ignoriert und bin in den vorherigen Antworten auf meine Beweggründe bereits geschildert:
a) Der Sketch von Veit arbeitet ohne externes EEPROM - daher ist das Timing völlig anders.... - habe ich daher nicht weiter untersucht.
Antwort siehe oben
Habe ich keinesfalls ignoriert, denn ich habe sie getestet. Sie funktioniert perfekt, nur leider habe ich nicht so viel RAM. Die Dateien sind mindestens 2kB groß, was einer Arraygröße von 2000 Bytes entspricht. Hier der Speicherbedarf meines realen Programmes (mit der bisheriger Einlese-Routine): Der Sketch verwendet 32222 Bytes (99%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes. Globale Variablen verwenden 1580 Bytes (77%) des dynamischen Speichers, 468 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
Ich muss schon 2 ASCII-Zeichen lesen und zu einem Byte zusammensetzen, bevor ich es ins EEPROM schreiben kann - siehst du das anders?
Nicht "mehr blockieren" sondern lediglich an der richtigen Stelle mit Timeout auf das 2. ASCII-Zeichen warten. Habe ich - es gibt dann ein Problem am Ende - der Puffer läuft hier über. Die Ursache ist die Zykluszeit in Verbindung der geringen Anzahl geschriebener Daten. Deshalb die Routine, welche auf das Eintreffen eine ausreichender Anzahl von Daten wartet. Ich hoffe, ich konnte alle Missverständnisse beseitigen und habe niemanden mit meinen Antworten "vor den Kopf gestoßen", was keinesfalls gewollt wäre! Viele Grüße Kai Hallo zusammen, es läuft endlich - bisher jedoch nur im Uno getestet, dafür mit mehr Daten (512 ASCII-Zeichen = 256 Bytes). Jetzt bin ich mit diesem an der Grenze der Logging-Kapazität.... Ein Delay von 50ms in der Loop bringt die Routine nicht durcheinander. Die Anzahl der zu sammelnden Bytes musste ich oberhalb von 25 Bytes begrenzen, da der serielle Puffer andernfalls auf 60 hochläuft, was mir zu unsicher war. Mit der Begrenzung liegt der Maximalwert bei 48.
Ich werde jetzt die Routine zunächst in den fliegenden Aufbau mit Arduino Mega integrieren und dann die Datenmenge erhöhen. Viele Grüße Kai Hallo Peter d, entschuldige, dass ich erst jetzt antworte, aber ich habe noch mit der Routine gekämpft. Auch dir vielen Dank für alle hilfreichen Tipps und Beispiele.
Guter Vorschlag - es gibt aber in dem Sinne keine Wartezeit von 20ms. Diese Zeit ist die Zykluszeit aller nacheinander aufgerufenen Funktionen der Loop.
Das Warten passiert nur im Datenübertragungsmenü und das auch nur, wenn Mindestens nur ein Zeichen eingetroffen ist. In diesem Fall warte ich eine gewisse Zeit auf das 2. Zeichen. Kommt das nicht, wird die Wartezeit beendet. Viele Grüße Kai
selber, was ist mit: Wichtige Regeln - erst lesen, dann posten!
Wieviel? Wenn man es richtig macht, wartet man exakt GAR NICHT, sondern holt das nächste Zeichen beim nächsten Aufruf der Statemachine ab. Siehe Multitasking. Und wenn man den RX Interrupt benutzt, wartet man mal sicher nicht. Hallo Joachim, Entschuldigung - hatte ich nicht als so lang empfunden - kann es leider nicht mehr ändern. Viele Grüße Kai Hallo Falk,
2 ms Viele Grüße Kai Hallo und einen schönen Restsonntag, der aktuelle Stand ist, dass Dateien bis 1900 Byte (mehr Daten habe ich zurzeit noch nicht) fehlerfrei abgespeichert und wieder eingelesen werden können und die eingelesenen funktional sind (dies bedeutet, dass mit den eingelesenen Daten die exakt identische Funktion gegeben ist, wie mit dem Original). Sicherheitshalber gibt es noch eine Checksumme. Zwischendurch hatte ich eine riesige Schrecksekunde, als das Logging jede Menge Fehler zeigte - das lag aber daran, dass Arrays des Logging überliefen. Der darauf folgende Absturz hat es geschafft, falsche Daten in die RTC zu schreiben und alle Kalenderdaten zu verfälschen. Da zahlte es sich aus, dass ich endlich ein Backup einlesen konnte.... Die Daten werden über die Eingabeaufforderung (CMD) eingelesen und ausgegeben (siehe Screenshot). Anbei ein auch ein Screenshot des Logging der Datenübertragung - jedes + in der obersten Zeile bedeutet, dass genug Daten von der seriellen Schnittstelle kamen, das - am Ende, dass hier ein Timeout auftrat, da die Anzahl geringer war, als die mögliche Anzahl für Page-Write (für dieses Logging wurden die Daten über den seriellen Monitor gesendet). Beim Erstellen des Screenshots dachte ich darüber nach, ob Veit evtl. mit anderen Einstellungen (CR, CR+LF) getestet hat? Mein Sketch verträgt diese nicht. @Arduino F:
20ms ist die Zykluszeit des Gesamtprogrammes - 2ms ist der Wert für das Timeout, wenn nur 1 Zeichen eintrifft. Ist auf jeden Fall ein riesiges Erfolgserlebnis.... Viele Grüße Kai Jetzt hatte ich doch glatt die Datei ohne Schrecksekunde vergessen..... Hallo zusammen, anbei der aktuelle Stand: Mittlerweile ist der Datenbestand angestiegen, so dass ich die Übertragung von Dateien oberhalb von 8 kB (cnt = 8605 Bytes entsprechend 40 Melodien mit je 215 Bytes + 1 Byte Präambel + CRC) erfolgreich prüfen konnte. Interessant ist, dass sich das Verhalten der Datenübertragung mittels Eingabeaufforderung (CMD) geringfügig ändert. Nicht eindeutig verifizierte Hypothese ist, je nachdem ob man vorher mittels Arduino-Ide Programme übertragen hat oder nicht. Es funktioniert, jedoch erkennt der PC teilweise das Dateiende-Zeichen nicht und es vergehen einige Sekunden bis zum Timeout durch den PC. Danach befinden sich die Daten in der angegebenen Datei (Test.txt). Nachdem ich bei der Datenübertragung einige Male nicht darauf achtete, den richtigen Bereich anzuwählen, habe ich eine automatische Erkennung des Datentyps implementiert. Beim Senden wird den Daten ein Zeichen vorangestellt, welches den Typ repräsentiert (S=Setting, C=Kalender, M=Melodie, T=Text, A=Alle). Beim Empfang wird anhand dieses Zeichens die EEPROM-Adresse umgeschaltet. Dabei wäre ich fast in die böse Falle gelaufen, dass die Definitionen der einzelnen EEPROM Bereiche nicht an der selben Page-Anfangs-Adresse lagen. Das wurde mir bewusst, als ich diese Funktion in den PAP aufnahm. Jetzt bleibt noch die Frage offen, wie ich es denn schaffen will, alle Funktionen in den 32kB des ATMEGA 328P unterzubringen..... Nach erster Sichtung aller Funktionen schien es recht aussichtslos und darauf hinauszulaufen, auf einige Funktionen verzichten zu müssen. So habe ich beispielsweise erst einmal die Funktion, Daten innerhalb des internen EEPROM umzukopieren, zu vergleichen und zu löschen, welche bisher als Ersatz für eine Datensicherung diente, deaktiviert, wodurch ich 1kB gewann. Weiteres Potenzial fand ich in der Tastenauswertung der Fernbedienung für die 18 Menüs. Hier war es beispielsweise möglich, die Auswertung für einige Menüs zusammenzufassen. Dann habe ich alle Funktionen daraufhin überprüft, ob diese in der Stand-Alone-Variante (ohne permanent angeschlossenen PC) überhaupt sinnvoll sind (beispielsweise EPROM-DUMP). Das brachte nochmal fast 1kB. Die Idee, alle Textkonstanten ins externe EEPROM zu verlagern, habe ich deshalb verworfen, weil das Gerät im Falle des Ausfalls des EEPROMS nicht mehr bedienbar wäre (zurzeit fallen dann nur die Melodien von Robson Couto und die Datensicherung aus). Das wären weitere 500 Bytes gewesen. Ebenso habe ich auf zu tiefe Schachtelung von Funktionen verzichtet, um sporadischen Abstürzen vorzubeugen. Intensive Überarbeitung aller Texte ergaben noch einmal ein paar Bytes, so dass nun alle Funktionen (einschließlich der Kopierroutine) integriert sind. Ob dieser Aufwand nun sinnvoll ist oder nicht, ist die Frage der Sinnhaftigkeit eines jeden Hobbys. Auf jeden fall war es sehr lehrreich und hat auch viel Spaß gemacht. Nun kann ich mich der optisch ansprechende Gestaltung des Gerätes widmen. Ideen zur Erweiterung verschiebe ich erst einmal, obwohl es da schon einige gibt. Viele Grüße Kai Hallo zusammen, weshalb nicht mal versuchen, das ganze EEPROM zu sichern um die Daten in ein neues und unprogrammiertes zu übertragen? Gedacht, getan und es funktioniert (siehe cnt_32k.png). Da blieb dann noch die Frage, wie sicher die Übertragung funktioniert bzw. wie viel "Luft" noch bis zum nicht mehr funktionieren ist. Daher habe ich die Übertragungsgeschwindigkeit zunächst auf 19200 Baud erhöht. Diese Funktionierte immer noch ohne Fehler. Eine zu optimistische Erhöhung auf 57600 Baud schlug (fast erwartungsgemäß) fehl. 38400 Baud führt sporadisch zu Fehlern. Da ich mich aber schon mit 9600 BAUD abgefunden hatte, ist die doppelte Übertragungsrate ein netter Bonbon (All_send.png). Viele Grüße Kai
Eine Datenübertragung ist erst dann als sicher (funktionierend) zu betrachten wenn sie unabhängig von der Datenrate arbeitet. Stell dir vor du kannst bei 10MBit Ethernet im Internet surfen, aber bei 100MBit nicht. Würdest du das akzeptieren?
Nein! Sie hat unter definierten Bedingungen zu funktionieren. Außerhalb dieser definierten Rahmenbedingungen darf sie versagen.
Na gut. Chacun à son goût.
komische Logik, neuerdings bekomme ich bei meinem AVR NETIO immer Fehlermeldungen (timeout) weil es zu langsam ist. Wenn mein LTE Kontingent aufgebraucht ist bekomme ich gedrosselt keine Webseite mehr über GSM (auch timeout) obwohl der Vertrag Flatrate mit runterschalten verspricht.
Dann ist dein Protokoll oder Handshake Schrott.
Er hat ja keins. Insofern bleibt wohl kaum anderes übrig, als eine passende Baudrate festzulegen.
Das nennt der Zeitgeist dann wohl "fail". Hallo Wastl, Arduino F, Joachim, Nemopuk und Falk, vielen Dank für eure Antworten. der Zweck der seriellen Datenübertragung ist in diesem Fall eine gelegentliche Datensicherung auf dem PC sowie das Zurückschreiben ins EEPROM und zwar "On the Fly". Das bedeutet, dass die eintreffenden Daten sofort mittels Page-Write ins EEPROM geschrieben werden. Für diesen Zweck ist aus meiner Sicht eine Übertragung mit fixen Parametern vollkommen ausreichend. @Arduino F:
Stimme ich 100% zu @Falk:
Aus deiner Sicht mag dies zutreffen - für meine Zwecke ist es vollkommen ausreichend Eventuell war das im LCD angezeigte "Auto-Detect" missverständlich: es bezieht sich hier auf die automatische Erkennung des Datentyps und daraus resultierender Einstellung der Speicheradresse. Viele Grüße Kai Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|