Ich muss mit einem Arduino über SoftSerial einen Bon auf einem Kiosk-Thermodrucker ausgeben. Alle Textausgaben klappen problemlos, aber zuerst kommt ein Logo. Die Daten dafür liegen in einem Array of byte bzw. uint8_t im PROGMEM. Die Größe beträgt 2868 Bytes. In zwei geschachtelten Loops (für 12 Zeilen zu je 239 Spalten) lese ich die Daten aus dem Array mit "pgm_read_byte(&logo[c])" und sende sie zeilenweise und mit der passenden ESC-Sequenz für den Grafikmode voran, zum Drucker. Da Softserial nur einen Puffer von 64 Bytes hat, mache ich zusätlich alle 32 Bytes eine Pause von 1000 Mikrosekunden (Drucker druckt mit 9600 Bit/s)... Problem: Immer so ziemlich in der Mitte des Logos (was ja im Grafikmodus gedruckt wird), werden plötzlich anstelle des Grafikblocks für diese eine Zeile einige Buchstaben im Textmodus eingestreut, bevor der Rest des Logos wieder ordentlich gedruckt wird. Das Argument für pgm_read_byte ist short, reicht also bis 32000, das kann es nicht sein. Gäbe es eine Größenbeschränkung für Arrays im PROGMEN, würde nach der "Störung" wohl nicht der Rest gedruckt ... was kann das sein? Ich vermute noch einen Pufferüberlauf am Drucker, aber der gibt keine entsprechende Rückmeldung (XMODEM, kein XOFF). Ideen, Tips? Danke.
:
Bearbeitet durch User
Frank E. schrieb: > Da Softserial nur einen Puffer von 64 Bytes hat, mache ich > zusätlich alle 32 Bytes eine Pause von 1000 Mikrosekunden (Drucker > druckt mit 9600 Bit/s)... Du sendest also 12 Zeilen je (239+n) Bytes, mit n ~ 3 oder so Du sendest mit 9600 Baud (ist das so gemeint?), also ~1Byte pro ms. Zudem machst Du alle 32 Byte 1 ms Pause. --> Der Funktionsaufruf muss damit "blockierend" sein, denn sonst hilft dir 1ms nicht wirklich. Du sendest also 8 Blöcke pro Zeile, der letzte nur ~ 18 Byte. --> ist sicher, dass die nächste Zeile korrekt neu beginnt? Oder gib es ein "Blockgrenzen" Problem? --> Sind zwei Logos immer gleich kaputt? Oder "random"? Wenn immer gleich, finde die genau Position heraus (notfalls unter einer Lupe die Pixel auszählen).
:
Bearbeitet durch User
Bruno V. schrieb: > Frank E. schrieb: >> Da Softserial nur einen Puffer von 64 Bytes hat, mache ich >> zusätlich alle 32 Bytes eine Pause von 1000 Mikrosekunden (Drucker >> druckt mit 9600 Bit/s)... > > Du sendest also 12 Zeilen je (239+n) Bytes, mit n ~ 3 oder so ja, die ESC-Sequenz 27 '*' 3 239 0 kommt immer vorweg, dann folgen die 239 Bytes > Du sendest mit 9600 Baud (ist das so gemeint?), also ~1Byte pro ms. > Zudem machst Du alle 32 Byte 1 ms Pause. > > --> Du sendest also 8 Blöcke pro Zeile, der letzte nur ~ 18 Byte. ja, 239 (getestet mit der Bronbreite) ist leider eine Primzahl > > --> ist sicher, dass die nächste Zeile korrekt neu beginnt? Oder gib es > ein "Blockgrenzen" Problem? im Druckbild gibt es keine seitliche Verschiebung, ich verwende einen über alle Loops laufenden Zähler, der die Bytes im Array adressiert > --> Sind zwei Logos immer gleich kaputt? Oder "random"? Wenn immer > gleich, finde die genau Position heraus (notfalls unter einer Lupe die > Pixel auszählen). Ja, das Druckbild ist immer an der gleichen Stelle kaputt, es sind auch immer die gleichen Zeichen, und das im Textmodus.
Ich habe den Eindruck, dass der Drucker intern die Bilddaten komprimiert und bei zu vielen Details ins Stolpern kommt. Ich habe anstelle des Logos mal ein anderes Testbild erstellt (nur ein Rahmen mit einem Kreis und einige Zahlen), das wird problemlos ausgedruckt ... Zur Erstellung des Soucecodes für das Progmem-Array verwende ich immer das gleiche Programm.
Frank E. schrieb: > Da Softserial nur einen Puffer von 64 Bytes hat, mache ich > zusätlich alle 32 Bytes eine Pause von 1000 Mikrosekunden (Drucker > druckt mit 9600 Bit/s)... Verlängere die Pause mal auf mehr als 32 Millisekunden ...
Frank E. schrieb: > Ich vermute noch einen Pufferüberlauf am Drucker, aber der gibt keine > entsprechende Rückmeldung (XMODEM, kein XOFF). > > Ideen, Tips? Danke. 1. Ist die Übertragung 8-bit clean? Heißt genau: kannst Du jeden 8 Bit Wert senden, und der wird vom Drucker auch korrekt interpretiert. Auch Nullbytes, XON (0x11), XOFF (0x13), CFR, LF etc? Hast Du das verifiziert? 2. Ist die Übertragung auf der Leitung fehlerfrei? Sind die Daten korrekt? Hast Du das mit einem Logicanalyzer verifiziert? fchk
Frank E. schrieb: > Da Softserial nur einen Puffer von 64 Bytes hat, mache ich zusätlich > alle 32 Bytes eine Pause Der Puffer ist nur für den Empfang. Senden läuft ohne und ist immer blockierend.
Frank K. schrieb: > Frank E. schrieb: > >> Ich vermute noch einen Pufferüberlauf am Drucker, aber der gibt keine >> entsprechende Rückmeldung (XMODEM, kein XOFF). >> >> Ideen, Tips? Danke. > > 1. Ist die Übertragung 8-bit clean? Heißt genau: kannst Du jeden 8 Bit > Wert senden, und der wird vom Drucker auch korrekt interpretiert. Auch > Nullbytes, XON (0x11), XOFF (0x13), CFR, LF etc? Hast Du das > verifiziert? So lange der Drucker die im ESC-Befehl für den Grafikmodus angegebene Anzahl von Bytes nicht vollständig erhalten hat, ist er 8-bit-clean. Man muss schließlich jedes beliebige Bitmuster drucken können. Ausserhalb des Grafikmodus reagiert er natürlich unterschiedlich auf Steuercodes. Das hab ich aber alles schon fertig, z.B. Font auswählen, Fett, Condensed, Vorschub, Rückzug, Abschneiden voll und halb ... läuft alles einwadfrei. Nur die Grafik macht Stress. > 2. Ist die Übertragung auf der Leitung fehlerfrei? Sind die Daten > korrekt? Hast Du das mit einem Logicanalyzer verifiziert? Die Leitung vom Arduino Nano (5V!) zum Drucker ist ca. 30cm lang und führt über ein Max232-Modul (Breakout mit 9pol. Sub-D-Buchse) auf eine "echte" V24 am Drucker.
Frank E. schrieb: > Ich habe den Eindruck, dass der Drucker intern die Bilddaten komprimiert > und bei zu vielen Details ins Stolpern kommt. Wäre tatsächlich denkbar, dass er nicht genug Pufferspeicher hat, um das komplette Bild "raw" aufzubewahren, bis er es tatsächlich ausdrucken kann. Auch bei nur 9,6kBaud dürften die Daten weit schneller zu übertragen sein, als der Ducker sie ausdrucken kann. Wenn es wirklich dieses Problem ist, dann liegt die Lösung klar auf der Hand: einfach langsamer senden. Also: zwar natürlich weiterhin mit 9,6kBaud, aber dafür mit Pausen zwischen den einzelnen Bytes. Die Pausen erst mal sehr großzügig wählen und dann schrittweise verringern. Mit diesem Ansatz kann man also auf jeden Fall erst mal herausfinden, ob das wirklich das Problem ist. Falls ja, kann man dann die Pausenlänge optimieren. Falls nein, war es nicht dieses Problem.
Mario M. schrieb: > Frank E. schrieb: >> Da Softserial nur einen Puffer von 64 Bytes hat, mache ich zusätlich >> alle 32 Bytes eine Pause > > Der Puffer ist nur für den Empfang. Senden läuft ohne und ist immer > blockierend. Das ist mir neu, wäre aber erfreulich, weil dann als Ursache auszuschließen. Frage: Warum kennt SoftSerial dann die Methode "flash"? Laut Referenz wartet die (neuerdings), bis alle zu sendenden Bytes raus sind ... ?
Frank E. schrieb: > Frage: Warum kennt SoftSerial dann die Methode "flash"? Welche Lib verwendest Du denn? Arduinos SoftwareSerial kennt kein "flush".
Mario M. schrieb: > Arduinos SoftwareSerial kennt kein > "flush". Falsch... Kennt es. Macht zwar nix, aber kennt es. https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/SoftwareSerial/src/SoftwareSerial.cpp#L470
Frank E. schrieb: >> 2. Ist die Übertragung auf der Leitung fehlerfrei? Sind die Daten >> korrekt? Hast Du das mit einem Logicanalyzer verifiziert? > > Die Leitung vom Arduino Nano (5V!) zum Drucker ist ca. 30cm lang und > führt über ein Max232-Modul (Breakout mit 9pol. Sub-D-Buchse) auf eine > "echte" V24 am Drucker. Und hast Du das messtechnisch verifiziert, dass da wirklich die Daten drüberlaufen, von denen Du glaubst, dass sie drüberlaufen? Ansonsten ist das alles nur Raterei. Du kannst ja auch einen PC ans andere Ende hängen und die ankommenden Bytes mitprotokollieren und vergleichen. Und Du kannst die Daten auch vom PC an den Drucker schicken. Damit schließt Du den Arduino als Fehlerquelle aus. fchk
Schafft der Drucker es eigentlich, nach etwa 240 Millisekunden das Papier um eine ganze Zeile zu transportieren? Druckt das Ding vier (Graphik-) Zeilen pro Sekunde? Wenn der Drucker ohne Handshake angesteuert wird, könnte bereits das ein Problem sein
Harald K. schrieb: > Schafft der Drucker es eigentlich, nach etwa 240 Millisekunden das > Papier um eine ganze Zeile zu transportieren? Druckt das Ding vier > (Graphik-) Zeilen pro Sekunde? > > Wenn der Drucker ohne Handshake angesteuert wird, könnte bereits das > ein Problem sein Ganz genau. Und wenn man zu doof/faul ist, das (vermutlich vorhandene Hardware-) Handshake zu benutzen, dann ist halt "Senden mit Pausen" angesagt.
Harald K. schrieb: > Ob S. schrieb: >> Und wenn man zu doof/faul ist > > Versuch' das mal anders zu formulieren. Mach' doch mal einen Vorschlag!
Ist das die Fortsetzung von deinem Problem von 2022? Beitrag "Bondrucker mit Fehler im Druckbild" Frank E. schrieb: > Ich habe einfach nicht die Zeit, das Problem bis zur endgültigen Lösung > zu lösen, muss erstmal so. Wird vermutlich niemandem ausser mir > auffallen. Ist nicht schön, aber so ist das Leben ... Scheiße schwimmt immer wieder hoch. Dieses mal solltest du dir die Zeit nehmen, das Problem vollständig zu analysieren, anstatt zu raten. Ich plädiere immer noch dafür, die Stromversorgung zu kontrollieren.
Monk schrieb: > Ich plädiere immer noch dafür, die Stromversorgung zu kontrollieren. Kontrolle kann natürlich nie schaden, aber meiner Meinung nach weist das beschriebene Fehlerbild kein bissel auf diesbezügliche Probleme hin.
Frank E. schrieb: > So lange der Drucker die im ESC-Befehl für den Grafikmodus angegebene > Anzahl von Bytes nicht vollständig erhalten hat, ist er 8-bit-clean. Man > muss schließlich jedes beliebige Bitmuster drucken können. Es gibt keinen Code zum Abbrechen oder neu aufsetzen? Prinzipiell kann man auch in Bitmuster Escapecodes einbauen. Mit einem speziellen Byte (z.B. 47), dass im Datenstrom verdoppelt wird, wenn es kein Escape-Code ist.
Arduino F. schrieb: > Mario M. schrieb: >> Arduinos SoftwareSerial kennt kein >> "flush". > > Falsch... > Kennt es. > Macht zwar nix, aber kennt es. Gut, dann nehme ich meine Aussage zurück. Hatte in der Doku nichts gefunden. https://docs.arduino.cc/learn/built-in-libraries/software-serial/
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.