Peter D. schrieb: > Wie oben schon gesagt, ich sammele alle Zeichen in einen Puffer und > bearbeite sie erst nach dem CR. genau so!
Peter D. schrieb: > Eine Task darf alle anderen > nicht auf unbestimmte Zeit blockieren. 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.
:
Bearbeitet durch User
Hallo Nemopuk, Helmut H, Joachim B, Klaus (feelfree) und Veit, vielen herzlichen Dank für eure hilfreichen Anregungen und Antworten. Nemopuk:
1 | Wo kommen die 20ms Verzögerung her? Ich würde das Problem dort beheben, |
2 | denn das ist nicht normal. |
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:
1 | Vielleicht schaust Du dir mal diese Arduino lib an: https://docs.arduino.cc/libraries/at24c/ |
2 | Die kümmert sich um I2C transfer buffer limit 32 Byte AT24 page size 64 Byte Aufruf mit beliebigem bytecount byc, z.B. beginned ab buffer[4] nach EEPROM adr: |
Vielen Dank - super Lib - nur leider ist mein Flash fast voll..... Beim nächsten Projekt bestimmt. Joachim:
1 | dann nutze den ATmega1284p mit 16KB Ram, Leerplatinen gibt es bei OSH Park, fertig aufgebaute leider nicht mehr zu finden. |
Der ATMEGA 1284 ist ein 40-Pinner. Meine Platine mit ATMEGA328P (28-Pin) ist bereits gefertigt und funktioniert einwandfrei. Alle Funktionen bis auf das Einlesen der Dateien sind fertig. Wenn diese Funktioniert ist das Projekt abgeschlossen. Eine Frage am Rande, welche ich dir schon immer mal stellen wollte: Hast du eine 1977 eine Ausbildung bei der Deutschen Bundespost in Düsseldorf gemacht? Klaus:
1 | Richtig wäre c) in der Empfangsroutine immer nur so viele Bytes aufsammeln wie halt da sind. Erst wenn sich z.B. 32 Bytes angesammelt haben werden diese weggeschrieben. |
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: 1. Ich habe dein abgespecktes Minimal-Programm (ohne EEPROM-Zugriff mittlerweile 100 Mal getestet - es kommt bei mir nie durcheinander. 2. Ich habe deine wirklich sehr elegantes Einlese-Routine getestet. Sie funktioniert perfekt. ABER: das verbliebene RAM in der Applikation reicht höchstens für 200 Zeichen.... a) Der Sketch von Veit arbeitet ohne externes EEPROM - daher ist das Timing völlig anders.... - habe ich daher nicht weiter untersucht.
1 | Deine Argumentation verstehe ich nicht. Versteht bestimmt niemand. Ich weiß nicht wie du Fehlersuche betreibst wenn das Offensichtliche |
2 | ignoriert wird. Ich habe gezeigt das deine Einleseroutine fehlerhaft ist. Wenn man das ohne EEprom nachvollziehen kann, dann umso besser. Es |
3 | gibt dabei genau so einen Versatz wie Eingangs von dir festgestellt. |
Antwort siehe oben
1 | Wie eine saubere Einleseroutine aussehen kann bzw. aussieht habe ich mit Link und Code gezeigt. Warum das alles ignoriert verstehe ich echt nicht mehr. |
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.
1 | Dein festhalten am paarweisen einlesen ist jedenfalls Mist. Du suchst lieber an anderen Baustellen und versaust dir den Code mit Zwangswartezeiten u.ä.. Wenn ich dann Ideen lese wie "Empfangsroutine nicht mehr verlassen" oder "Warteroutine" ... |
Ich muss schon 2 ASCII-Zeichen lesen und zu einem Byte zusammensetzen, bevor ich es ins EEPROM schreiben kann - siehst du das anders? Die Zwangswartezeit gibt es nur nach dem ersten Byte - ab hier darf die Einlese-Routine nicht verlassen werden, da andernfalls durch die doppelte Zykluszeit von 20ms der Puffer überläuft. Mit "Warteroutine" meinte ich konkret das Warten auf eine ausreichende Anzahl von Daten für den Page-Write.
1 | Ich denke du hast keine Zeit? Aber möchtest noch mehr blockieren? Mein wiederholter Rat. Fang nochmal sauber von vorn an. |
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
:
Bearbeitet durch User
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.
1 | +++++++++++- |
2 | |
3 | Max. buffer fill state: 48 number real received bytes: 256 variable cnt: 256 OK Char left in serial buffer 0 Remaining -1 Timeout 0 Checksum 0 |
4 | |
5 | 1. page-write: cnt 0 cur_byte 24 -> 24 status 0 written 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 read 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 |
6 | 2. page-write: cnt 24 cur_byte 8 -> 32 status 0 written 18 19 1A 1B 1C 1D 1E 1F read 18 19 1A 1B 1C 1D 1E 1F |
7 | 3. page-write: cnt 32 cur_byte 24 -> 56 status 0 written 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 read 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 |
8 | 4. page-write: cnt 56 cur_byte 24 -> 80 status 0 written 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F read 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F |
9 | 5. page-write: cnt 80 cur_byte 16 -> 96 status 0 written 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F read 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F |
10 | 6. page-write: cnt 96 cur_byte 24 -> 120 status 0 written 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 read 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 |
11 | 7. page-write: cnt 120 cur_byte 24 -> 144 status 0 written 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F read 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F |
12 | 8. page-write: cnt 144 cur_byte 16 -> 160 status 0 written 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F read 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F |
13 | 9. page-write: cnt 160 cur_byte 24 -> 184 status 0 written A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 read A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 |
14 | 10. page-write: cnt 184 cur_byte 24 -> 208 status 0 written B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF read B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF |
15 | 11. page-write: cnt 208 cur_byte 16 -> 224 status 0 written D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF read D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF |
16 | 12. page-write: cnt 224 cur_byte 24 -> 248 status 0 written E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 read E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 |
17 | 13. page-write: cnt 248 cur_byte 8 -> 256 status 0 written F8 F9 FA FB FC FD FE FF read F8 F9 FA FB FC FD FE FF |
18 | |
19 | Log of combined values (val): |
20 | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 00 |
21 | |
22 | EEPROM Settings |
23 | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 16 |
24 | 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 32 |
25 | 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 48 |
26 | 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 64 |
27 | 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 80 |
28 | 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 96 |
29 | 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 112 |
30 | 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 128 |
31 | 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 144 |
32 | 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F 160 |
33 | A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF 176 |
34 | B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF 192 |
35 | C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF 208 |
36 | D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF 224 |
37 | E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF 240 |
38 | F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 256 |
39 | |
40 | RAM rx_test |
41 | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 16 |
42 | 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 32 |
43 | 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 48 |
44 | 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 64 |
45 | 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 80 |
46 | 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 96 |
47 | 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 112 |
48 | 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 128 |
49 | 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 144 |
50 | 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F 160 |
51 | A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF 176 |
52 | B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF 192 |
53 | C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF 208 |
54 | D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF 224 |
55 | E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF 240 |
56 | F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 256 |
57 | |
58 | EEPROM clear |
59 | |
60 | RX-RAM clear |
61 | |
62 | BUFFER clear |
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.
1 | Dann mach doch das EEPROM Zeugs einfach mit in die schnellen Tasks vor |
2 | der 20ms Wartezeit: |
Guter Vorschlag - es gibt aber in dem Sinne keine Wartezeit von 20ms. Diese Zeit ist die Zykluszeit aller nacheinander aufgerufenen Funktionen der Loop.
1 | Nein, das ist (fast) immer eine Sackgasse. Eine Task darf alle anderen |
2 | nicht auf unbestimmte Zeit blockieren. |
3 | Wenn eine Task gerade auf etwas warten muß, dann verlasse sie einfach |
4 | und setze sie beim nächsten Aufruf fort. Mit einem switch/case kann man |
5 | sich merken, wo weitergemacht werden soll. |
6 | Wie oben schon gesagt, ich sammele alle Zeichen in einen Puffer und |
7 | bearbeite sie erst nach dem CR. |
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
Kai schrieb: > Hallo selber, was ist mit: Wichtige Regeln - erst lesen, dann posten! Groß- und Kleinschreibung verwenden Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
Kai schrieb: > 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 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,
1 | Wieviel? Wenn man es richtig macht, wartet man exakt GAR NICHT, sondern |
2 | holt das nächste Zeichen beim nächsten Aufruf der Statemachine ab. |
3 | Siehe Multitasking. Und wenn man den RX Interrupt benutzt, |
4 | wartet man mal sicher nicht. |
2 ms Viele Grüße Kai
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.