Senden von Escape-Sequenzen an Drucker (ESC/POS)

  • Liebe Gemeinde,

    da ich kein gescheites Programm finden konnte, um unterwegs Quittungen für Kunden auszudrucken, ohne auf einen DIN A4-Drucker zurückgreifen zu müssen, habe ich mir ein kleines Skript mit der printMG.dll von Martin erstellt, um einen kleinen 80 mm Bluetooth-Bondrucker anzusteuern. Das klappt soweit wunderbar, was den Inhalt angeht. Nur mit der Formatierung habe ich ein kleines Problem.

    Zum Hintergrund: Generell benutzt man bei Kassenanwendungen häufig den Raw- oder Textmodus, da das einfach schneller geht, als Grafiken zum Drucker zu schicken. Z.B. hinterlegt man ein Logo einmal im Speicher des Druckers und löst es zum Anfang des Druckvorgangs einfach aus, statt die ganze Grafik neu zu übermitteln.

    Auch für Textformatierungen und andere Dinge gibt es dann entsprechende Escape-Sequenzen (Lade öffnen, Schrift doppelt breit, doppelt hoch, etc.), die man einfach in den Druck mit einbauen kann.

    Dummerweise bin ich anscheinend zu doof, um die Sequenzen richtig zu senden. Probiert habe ich z.B. den Druck in doppelter Höhe. Dazu müsste ich die Sequenz ESC ! n an den Drucker schicken. n steht dann für die Art des Drucks (n = 16 ist doppelte Höhe, n = 32 ist doppelte Breite). Es gilt also, dem Drucker zu sagen ESC ! 16. Dazu habe ich z.B.

    _PrintText( $Prn Chr( 27) & Chr( 33) & 16 ) sowie _PrintText( $Prn {ESC} & {!} & 16 ) oder auch send( Chr( 27) & Chr( 33) & 16 ) ausprobiert. Leider hat nichts davon funktioniert.

    Hat vielleicht schon einmal jemand von Euch mit solchen Escape-Sequenzen gearbeitet oder sonstwie eine Idee, wie ich diese korrekt an den Drucker schicken kann? Über jedwede Unterstützung würde ich mich riesig freuen. :)

  • Also, mit Escapesequenzen nicht, aber _PrintText( $Prn Chr( 27) & Chr( 33) & 16 ) Kann nicht funktionieren, denn Variablen müssen immer irgendwie verknüpft sein. {ESC} sendet nicht die Taste, sondern den String. AutoIt markiert es nur, falls man damit die Taste meint, damit man weiß, dass es richtig geschrieben ist,... es ist aber immernoch der String "{ESC}". 27 ist richtig escape, wie du gefunden hast. Ob wirklich das Zeichen für Escape oder der String "ESC" gemeint ist weiß ich jetzt nicht. 33 ist das Rufzeichen, also auch richtig, man kann auch "!" schreiben. 16 wird als Zahl auch dahinter gepackt. Vielleicht fehlen dort nur die Leerzeichen, weiß grad nicht, ob die bei dir dorthin müssen.
    Was du sendest sieht so aus:
    [ESC] ist dabei nicht der String, sondern das ASCII-Zeichen 27
    _PrintText( $Prn Chr( 27) & Chr( 33) & 16 ) Erstmal nen Error wegen $PRN CHR(27), sonst wäre das Ergebnis bei _PrintText( $Prn & Chr( 27) & Chr( 33) & 16 ) : "Was in $PRN steht[ESC]!16"
    _PrintText( $Prn {ESC} & {!} & 16 ) Erstmal nen Error wegen $PRN {ESC}, sonst wäre das Ergebnis bei _PrintText( $Prn &"{ESC}" & {!} & 16 ) : "Was in $PRN steht{ESC}{!}16"
    send( Chr( 27) & Chr( 33) & 16 ) Sendet als Tastendruck: [ESC]!16
    Was du vermutlich möchtest: Chr(27)&" "&Chr(33)&" "&16


    Ansonsten bräuchte ich mehr von dem Script, und die Info, ob du per Handy ein Programm auf deinem Rechner ansteuern möchtest, welcher dann Tastendrücke simuliert,...

  • Hallo @Kanashius und schon mal vielen lieben Dank für Deine Hilfe. :)

    Du hast natürlich Recht, Variablen müssen verknüpft sein. In meinem Fall hab ich Dussel ein Komma nach dem $Prn vergessen.

    Ich liste hier mal kurz die Druckfunktion des Scripts ohne jegliche Escape-Sequenzen, dann kann man sich das im Kontext wahrscheinlich besser vorstellen. Der Übersichtlichkeit halber lasse ich die Teile zum Auffangen von Fehlern mal weg.


    Mit der wie folgt eingebauten Sequenz passiert zwar schon mal etwas, aber nicht das Richtige. Schreibe ich z.B.
    _PrintText($Prn, Chr( 27 ) & Chr( 33 ) & 16 & " ZAHLUNGSBELEG NR. " & $sLfdNr , 10, 340)
    dann wird ab dem Wort Zahlungsbeleg alles in einem größeren, fetten Font gedruckt bis zum Schluss. Versuche ich, das in der nächsten Zeile mit
    _PrintText($Prn, Chr( 27 ) & Chr( 33 ) & 0 & " ", 10, 380)
    wieder auf Null zu stellen, kommt ein noch größerer Font bis zum Schluss.

    Wenn ich so wie hier noch Leerzeichen dazu mache
    _PrintText($Prn, Chr( 27 ) & " " & Chr( 33 ) & " " & 16 & " ZAHLUNGSBELEG NR. " & $sLfdNr , 10, 340)
    dann wird ab dieser Stelle alles mit dem normalen Font gedruckt, aber an jeder zweiten Druckposition ein Leerzeichen eingefügt, sodass es wie gesperrter Text aussieht (B e i s p i e l). :S

    P.S.: Nein, ein Handy ist hier nicht im Spiel, Tastendrücke wollte ich eigentlich keine übertragen.

  • Sicher, dass dort 0 hin muss für normal? Normal wird ein Font in Pixel angegeben, also 16 pixel, normal wären dann 12. 0 Würd ja heißen überhaupt keine Größe. Könnte mir dort den Fehler vorstellen.

    Kannst du mir mal das Modell nennen?
    Dort sind unterschiede in den Escapesequenzen, siehe Epson: http://lprng.sourceforge.net/DISTRIB/RESOURCES/PPD/epson.htm

    Spoiler anzeigen


    27 33 n
    ESC ! n

    Master select where n is a combination of:
    0 Pica 16 Double Strike
    1 Elite 32 Double Wide
    4 Condensed 64 Italic
    8 Emphasized 128 Underline
    Pica & Elite and Condensed/Emphasized are mutually exclusive

  • Ja, genau, wie in Deiner Liste. Das Modell ist ein Chinakracher von Hoin, aber der hält sich an diese Epson-Sequenzen (die haben irgendwann mal quasi den Standard gesetzt).

    Die Sequenzen entsprechen daher nahezu Deinen, ich habe den Teil mal aus meiner Anleitung beigefügt.

    24-01-_2017_03-54-18.png

    P.S.: Pixel gibt man bei diesen Druckern übrigens nicht an. Die haben eingebaute Fonts (oft nur zwei), die man einfach abruft und dann sagt, ob sie doppelt hoch, breit oder beides sein sollen. Man hat das früher wohl so eingeführt, weil alles über alte Ports ging und man wollte, dass es trotzdem schnell geht. Will man dann doppelt hoch und breit, addiert man die Bits und schickt z.B. einfach 16 + 32, also 48 als Wert.

  • So evtl.

    printexample2.au3

    2 Mal editiert, zuletzt von Bitnugger (25. Januar 2017 um 17:51)

  • Vielen lieben Dank@'Bitnugger', dass Du auch versuchst, mir zu helfen. :rock:
    Mit Deinen Änderungen im Script funktioniert zwar alles, aber nach wie vor ohne Formatierung. Also quasi so, als hätte sich nichts geändert.

    Konntest Du das mal an einem Bondrucker ausprobieren? Vielleicht schlummert noch irgendwo ein Fehler im Script... *grübel*

  • Konntest Du das mal an einem Bondrucker ausprobieren?

    Nein, habe leider keinen.

    Das könnte helfen... sonst bin ich mit meinem Latein auch am Ende.

    printexample3

    Das hier hast du bereits gesehen?

    PrintWinAPI.au3

    Einmal editiert, zuletzt von Bitnugger (26. Januar 2017 um 01:29)

  • Nochmal danke für Deine Mühe @Bitnugger. Leider hat es so auch nicht geklappt, der Text kommt unverändert normal aus dem Drucker. Ist schon krass, was man manchmal veranstalten muss, um einfach Rohdaten irgendwohin zu schicken. :(

    Das Ding mit der PrintWinAPI.au3 hatte ich mir auch angesehen, aber das scheint definitiv über die Nutzung von grafischen Druckdaten hinauszulaufen wegen GDI & Co. Klar, ist ja auch heutzutage eigentlich der Normalfall. Trotzdem wundert mich, dass es so kompliziert ist, einen solch rudimentären Drucker anzusprechen. Gerade, wo doch in weltweit in jedem 2. Laden einer steht. *seufz*