Serial RS232 communication with printer CITIZEN PMU 2300II

jenako

Member
Join Date
May 2019
Location
Northampton
Posts
14
I need to print data produced by the program PLC (Beckhoff PLC) from a Citizen PMU 2300 printer. More precisely I need to send the data to the printer and the print should print in QR code. I have looked into the user manual found on the internet but it does not give any advice of how to setup the serial communication, has anyone attempted something like this and could provide some help?
 
https://www.citizen-systems.co.jp/english/support/download/printer/document/user/data_box/CT-P29x_UME_50F.pdf
The above manual will show you the setup of the printer. Baud, data bits, etc.

https://www.citizen-systems.co.jp/english/support/download/printer/document/command/data/CommandReference025E.pdf
This manual will tell you the commands to send to the printer. Each instruction will show you the hexadecimal number.

http://www.plctalk.net/qanda/showthread.php?t=45916
This will show you sending ASCII characters out of the port.

I hope this helps you out.
Regards,
 
Thank you very much for your replies! I have to admit though that I am bit confused of your second point

https://www.citizen-systems.co.jp/en...erence025E.pdf
This manual will tell you the commands to send to the printer. Each instruction will show you the hexadecimal number.

So according to pg. 78 if I want to print 4 A's I need to send the string 'LPRINT CHR$(&H1B);" "; CHR$(0); LPRINT "AAAAA"; CHR$(&HA);' ? Or I need to convert this string to hexadecimal? What do I have to send to the printer to print the 4 A's?

Thanks in advance for the replies!
 
So according to pg. 78 if I want to print 4 A's I need to send the string 'LPRINT CHR$(&H1B);" "; CHR$(0); LPRINT "AAAAA"; CHR$(&HA);' ? Or I need to convert this string to hexadecimal? What do I have to send to the printer to print the 4 A's?

The serial printer will accept ASCII Characters. The instruction that you are looking at on page 78 is the "Setting the right spacing of the character"
The code is <1B>H<20>H<n>
The CHR$ instruction will show you the ASCII equivalent.
IF you convert this to hexadecimal code only then it would look like this.
1B20304141414141HA
Note: 41 hex = A; 30 hex = 0

https://www.rapidtables.com/convert/number/ascii-to-hex.html
This converter will convert from ASCII to HEX

Regards,
 
gclshortt I really appreciate the help and all the effort. However I hate to admit I do not really understand how <1B>H<20>H<n> is converted into 1B20304141414141HA or the principle of sending data to the printer in general.

When I put 1B20304141414141HA using the converter you attached I come with 0AAAAA in ASCII, how can these be equivalent? Could you break the code <1B>H<20>H<n> into the ASCII characters? Thanks for all the help, it is highly appreciated!
 
This post may help you out.
https://accautomation.ca/what-everybody-ought-to-know-about-plc-programmable-logic-controller-numbering-systems/

ASCII characters cannot be printed or displayed on a screen so we either use the hexadecimal equivalent or the programming option (CHR$(&H1B)) to display.
You get that result because some of the characters cannot be displayed.
1B Hex = 00011011 in binary = CHR$(&H1B)
20 Hex = 00100000 in binary = " " = CHR$(&H20)
n Hex is the variable for the instruction in our case we have used 0.
30 Hex = 00110000 in binary = "0" = CHR$(&H30)

I hope this clarifies the conversions for you.
Regards,
 
Maybe these will help:

ASCII man page


ASCII wiki


ASCII Wiki: character groups (tables contain the same info as the ASCII man page)


For the protocol implemented by your printer, pay particular attention to the ESC (escape) and GS (group separator) character.

See also the code tables starting on p. 463 of the printer manual.


For sending characters to the printer:

  • The examples in the manual use conventions unique to the BASIC programming language;
    • See below for interpretation of those conventions
    • Specifically, you will likely never send the character strings "LPRINT" or "CHR$(" to the printer
  • You will need to use different techniques i.e. those available to your brand and model of PLC

These three are all equivalent

  • 1B2030AAAAHA - hexadecimal shorthand
  • <1B>H<20>H<30>H<41>H<41>H<41>H<41>H<A>H - printer manual hexadecimal shorthand
  • ESC SP 0 A A A A NL - ASCII shorthand

TL;DR

In the domain of your printer, the terms "character" and "byte" are somewhat interchangeable: they are two ways of referring to an 8-bit code.*

Character refers to the glyph for printables, or shorthand name for non-printables, the code represents e.g. "A" or "0" or "!" or "ESC" etc.


Byte refers to the numeric value of the code, which is in the hexadecimal range 00 to FF and in the decimal range 0 to 255.



The primary convention used in the printer manual for codes is <h>H or <hh>H, where each h represents one hexadecimal digit.


The secondary convention used in the printer manual for codes is &Hhh, where again each h represents on hexadecimal digit. N.B. this secondary convention is only used in the context of BASIC program examples.



Common codes to note in the context of this printer are

  • <1B>H = &H1B => ESC escape control character (27 decimal)
  • <1D>H = &H1D => GS group separator control character (29 decimal)
  • <A>H = &HA => NL new line control character (13 decimal)

The primary convention used in the printer manual for characters is the glyph (A or 0 or !) for 7-bit ASCII printable characters or the name (ESC or GS) for non-printable control characters

The secondary convention used in the printer manual for a sequence (i.e. string) of printable characters, in the context of BASIC program examples, is one or more glyphs enclosed in quotes e.g. "AAAA" for four uppercase A characters.

The secondary convention used in the printer manual for non-printable control characters, in the context of BASIC program examples, is CHR$(&Hhh) or CHR$(d), which is a function (CHR$) that converts the hexadecimal (&Hhh) or decimal (d) code to their single corresponding character.

Key concepts to understand

  • A or "A" refers a character i.e. in this case the first letter of the western alphabet
  • <A>H or &HA is a code (hexadecimal A = decimal 10) of a character
  • CHR$(&HA) refers to the character with code A(hex) = 10(dec) i.e. NL newline.
  • LPRINT is the BASIC command to send data to the printer; you will probably never send the string "LPRINT" to this printer.

On page 78 of that manual, which tells you how to set the inter-character spacing, the header is
Code:
ESC SP n
This tells you that it takes three characters (bytes) sent in sequence to set the spacing:


  • ESC is the escape control character
  • SP is the space character
  • n is a user-specified single character, the code for which will be the inter-character spacing
Further down, we see the same thing, but in hexadecimal form:
Code:
<1B>H<20>H<n>
  • <1B>h = 1B hex = 27 decimal = the code for ESCape
  • <20>H = 20 hex = 32 decimal = the code for SPace
  • <n> => n will be the code of the user-specified character sent, and that code will be the spacing use
And finally, in the example on p. 78, we see this line:
Code:
LPRINT CHR$(&H1B);" ";CHR$(0);
  • LPRINT is the [send to printer] BASIC command
  • CHR$(&H1B) is the ESCape character
  • ; (semi-colon) ensures LPRINT does not send anything, e.g. spaces, between the characters on the line
  • " " is a space; it could also be CHR$(&H20) or CHR$(32)
  • ; another semi-colon
  • CHR$(0) is the NUL character, so n is zero, and the inter-character spacing will be zero
  • ; a final semi-colon ensures LPRINT does not append line termination to the characters sent to the printer
After that, we see this line:
Code:
LPRINT "AAAA";CHR$(&HA);
  • LPRINT is the [send to printer] BASIC command
  • "AAAA" is a string of four uppercase A characters
  • ; semi-colon to prevent LPRINT send spaces
  • CHR$(&HA) is the NL newline character i.e. line termination
  • ; a final semi-colon to prevent LPRINT from sending an automatic line terminator
After that we see line pairs, except that CHR$(1) and CHR$(12) are used to specify inter-character (n) spacings of 1 (decimal) and 12 (decimal).


Note that the following three statements would produce identical results
Code:
[LIST]
[*]LPRINT CHR$(&H1B);" ";CHR$(&H20);
[*]  LPRINT CHR$(&H1B);" ";CHR$(32);
[*]LPRINT CHR$(&H1B);"  ";
[/LIST]
because the third character is a SPace i.e. code 32 (decimal) = code 20 (hexadecimal).



* Technically ASCII codes are all 7-bits, but we conventionally send data 8 bits (one byte) at a time, so the ASCII codes are in the low 7-bits of the sent byte and the high bit is zero.
 
Thank you for the responses guys, I think I am getting there.

So if I understood what you are saying the commands I send to the printer should be in the form : command code in hex i.e. 1B 20 30 + data I want to send in hex i.e. 41 41 41 41 + A in hex for a new line 0A, is this correct?

dtbitboy you said above

These three are all equivalent
1B2030AAAAHA - hexadecimal shorthand
<1B>H<20>H<30>H<41>H<41>H<41>H<41>H<A>H - printer manual hexadecimal shorthand
ESC SP 0 A A A A NL - ASCII shorthand

for the hexadecimal shorthand did you mean 1B 20 30 41 41 41 41 0A (41 is hex for A and 0A is the character for new line) instead of 1B2030AAAAHA ?
 
Last edited:
Thank you for the responses guys, I think I am getting there.

So if I understood what you are saying the commands I send to the printer should be in the form : command code in hex i.e. 1B 20 30 + data I want to send in hex i.e. 41 41 41 41 + A in hex for a new line 0A, is this correct?


I think not, although we might just be having a semantic issue in our communication.




You send the actual character i.e. the byte that has the value represented by the hexadecimal digits. So if the hex value is <41>H, then you send the character uppercase A. That is what the BASIC LPRINT command sends for CHR$(&H41): &H41 is 41 hex = 65 decimal = the ASCII code for uppercase A.


You will never send the hexadecimal digits unless you want to see the hexadecimal digits (literally "41414141" on the printer.





At this point I assume you would be happy to see AAAA on a piece of paper. But I think you said you want to print a QR code, and that will use a different protocol and printer setup, but the principle will be the same: you send 8-bit bytes (a.k.a. characters) to the printer.



dtbitboy you said above



for the hexadecimal shorthand did you mean 1B 20 30 41 41 41 41 0A (41 is hex for A and 0A is the character for new line) instead of 1B2030AAAAHA ?
Ack yes, ignore that hexadecimal shorthand: AAAA is two bytes of decimal 170! Those should be 41414141, and yes, HA should be 0A for the newline.
 
Last edited:
okay, here's the beef. See the example at the bottom of the image below: that is exactly what you are going to be doing, except you will be doing it in a PLC program instead of a BASIC program.

N.B. in the following, GS, NUL, NL, ETX are each a mnemonic for a one-byte, i.e. single, character.

Code:
GS ( k pL pH cn fn m
where

  • pL=3 and pH=0
    • so pL + (<100>h*pH) = 3
    • N.B. 100 hex = 256 decimal
    • and 3 is the number of characters remaining in the command
    • i.e. the [cn, fn, m] triplet that follows
  • cn=49 (hex),
  • fn=81 (hex) to print the QR code saved by fn=80,
  • m=48 (hex)
Notice that the code provided is

Code:
<1D>H   <28>H   <6B>H   <pL>   <pH>   <cn>   <fn>   <m>
(spaces added by me for clarity) where

  • <1D>H is the hex code for character GS
  • <28>H is the hex code for character (
  • <6B>H is the hex code for character k
so you will literally send the following 8 characters i.e. 8-bitbytes (without the separating spaces shown here):
Code:
GS ( k ETX NUL I ü H
N.B.

  • GS is the one-byte characrer for code 1D hex
  • ETX is the one-byte character for code 03 hex
  • NUL is the one-byte character for code 00 hex
  • I is the character for code 49 hex
  • ü is the character for code 81 hex (see 3.1.1 in printer manual)
  • H is the character for code 48 hex



And if you look at the example at the bottom of that image, you will also see the preceding [GS ( k] command with fn=80 (hex) that writes the data ("CITIZEN") for the QR code to memory (cf. Function 180, on p. 418):


Code:
GS ( k pL pH cn fn m d1...dk
where

  • pL + (<100>H * pH) = 3 + k
  • cn=49 hex
  • fn=80 hex
  • m=48 hex
  • d1...dk = [k] count characters that the QR code will represent
    • In the example, d1...dk is the string CITIZEN
So the first two LPRINT commands in the example will print the characters
Code:
GS ( k NL NUL I Ç H C I T I Z E N
(without the spaces), where

  • NL is the one-byte character for code 0A hex
  • NUL is the one-byte character for code 00 hex
  • Ç is the one-byte character for code 80 hex
Note that 0A + (100 * 0) = 0A hex = 10 decimal = 7 + 3, and there are seven characters in CITIZEN plus the three characters before that (IÇH), so the [pL,pH] pair represents a 16-bit integer that is three more than the length of the string that is to be QR encoded.

xxx.png
 
Last edited:

Similar Topics

I have wasted a week trying to figure out how to connect an SLC5/03 with my laptop. I do not have and can not Buy the 1747 UIC and PC3 cables. I...
Replies
14
Views
2,544
MELSEC A RS422 (25pin) <> iQR C24 Serial RS232 (9pin) - Simple PLC Communication Communication from a MELSEC-A Series CPU (RS-422 – DB 25 Pin)...
Replies
4
Views
1,036
Good morning everyone, This is my first post here. I am beginning my journey on PLC programming and still a really newbie, I want to write a...
Replies
0
Views
1,245
Hi Guys, I have a Beckhoff CP6607. It has 2 ethernet ports, 2 usb ports, and a serial port. I am trying to connect it to a Scheider VSD, an...
Replies
2
Views
3,974
So I have a very old radio modem that uses hardware flow control. Its RS232 with RTS, CTS and RTD. I have pins: 2- Tx 3- Rx 5- GND 6- RTD 7- RTS...
Replies
5
Views
1,523
Back
Top Bottom