I'm attempting to read the TID bank of the current (Class 1 Generation 2) RFID tag sitting under the print-head in a Zebra RZ400 (running the latest firmware V53.17.22Z). I'm connected via USB.
I'm using the "Direct Communication" program in the Zebra Setup Utilities tool.
This is my program, annotated:
^XA Start program
^RS8 Set RFID mode to Class 1 Gen 2
^RFR,H,0,8,2 Read the first 8 bytes of the TID bank as a Hexadecimal string
^FN1 Store the data into Memory Field #1
^FS End Field
^HV1,,Foo Transfer the contents of Memory Field #2 to the Host PC
^FS End Field
^XZ End program
When I run this, I do not get any output in the "Data received" window.
However, if I append a command like ^HH to the end (after the ^XZ) and re-run the program then the previous expected output will appear (followed by the output of ^HH). I need to keep on re-running the commands to get the previous output, making it impossible to see the current TID value.
It's as though the printer isn't flushing its output buffer until I run ^HH - other commands work temperamentally. The ^HH command isn't appropriate for my application because of the sheer amount of data it produces.
Is there some command that forces a flush?
I need to learn to read the documentation.
The ^HV command has 5 parameters. The sample code I based my program off only provides the first 3 parameters and I didn't think that the other parameters were relevant - mostly because Zebra gave the key parameter the nonobvious name "command applies to":
^HV(fieldNumber),(byteCount),(header),(terminator),(commandAppliesTo)
While I had set fieldNumber, byteCount, and header correctly (I ignored terminator) I completely overlooked the commandAppliesTo parameter, which states:
When ^PQ is greater than 1 or if a void label occurs, send one
response for a label format or one for every label printed.
Accepted Values:
F = Format
L = Label
Default Value: F
So when you don't specify a value it defaults to F which means it will return the data only when the entire job has completed, by changing it to L I get a response for each label that is printed.
Here's my final working command:
^XA
^RS8
^RFR,H,0,8,2
^FN1
^FS
^HV1,256,HEADER,TERMINATOR,L
^FS
^XZ
Which gets me output like this:
HEADERE28011302000240CTERMINATORHEADERE28011302000241CTERMINATORHEADERE28011302000242CTERMINATOR
Sorted :)
Related
I have a piece of software running on concurrent DOS 3.1, which I emulate with QEMU 5.1.
In this program, there are several options to print data. The problem is that the data arriving to my host does not correspond to the data sent.
the command to start qemu:
qemu-system-i386 -chardev file,id=imp0,path=/path/to/file -parallel chardev:imp0 -hda DISK.Raw
So the output sent on parallel port of my guest is redirected to /path/to/file.
When I send the charactère 'é' from CDOS:
echo é>>PRN
The code page used on CDOS is Code Page 437, and in this charactere set, the charactère é is represented by 0x82, but on my host, instead, I receive the following:
cp437 é -> 0x82 ---------> host -> x1b52 x017b x1b52 x00
So I tried something else. I wrote the charactère 'é' in a file, and sent the file with nc.exe (from brutman and libmtcp), and with nc, the value stays 0x82.
So my question, what happen when I send my data to virtual parallel port? When does my data get transformed? Is it the parallel port on Concurrent DOS? Is it the QEMU? I can't figure out how to send my data through LPT1 properly.
I also tried this:
qemu-system-i386 -chardev socket,id=imp0,host=127.0.0.1,port=2222,server,nowait -parallel chardev:imp0 -hda DISK.Raw
I can read the socket fine, but same output as when I write in a file, the é get transformed to x1b52 x017b x1b52 x00.
The byte sequence "1B 52 01 7B 1B 52 00" is using Epson FX-style printer escape sequences (there's a reference here). Specifically, "1B 52 nn" is ESC R n which selects the international character set, where character set 0 is USA and 1 is France. So the sequence as a whole is "Select French character set; print byte 0x7b; select US character set". In the French character set for this printer standard, 0x7B is the e-acute é.
This is almost certainly the CDOS printer driver assuming that the thing on the end of PRN: is an Epson printer and emitting the appropriate escape sequences to output your text on that kind of printer.
OK, so i finally figured it out... After hours of searching where this printer.sys driver could be, or how to remove it, no Concurrent DOS, the setup command is "n". And of course, it is not listed in the "help" command...
Anyway, in there you can setup your printer, and select "no conversion" for the port you want. And it was actually on Epson MX-80/MX-100.
So thanks to Peter's answer, you led me to the right path !
Anyone here using MikroC to implement UART?
I'm trying to connect a PIC18F4550 and SIM900. I want to use UART1_Read_Text(variable, delimiter, attempts). But since there is no specific length of the text that will be received, I'm trying to use NULL as the delimiter but none seems to work. I tried putting "\0", "0"," enter code here" but the microcontroller is stuck in that line of code. Here is the sample code i tried.
UART1_Read_Text(variable,"\0",255) //255 means the PIC will continuously find the NULL
Just so you know, I'm expecting to receive either "OK" or "ERROR". The PIC will then repeat a certain line of code if it receives "ERROR".
I have an Intermec PX6i printer.
The label code is generated, saved as a .txt file and sent to the printer through TCP/IP connection.
Everything works perfectly, but when executed, it saves the current file to the memory and prints the previous label.
This means that i have to execute the print twice in order to get my requested label. Every other label is then discarded due to the fact that is is a copy of the previous successful label.
Even an empty FEED directly from the printer control panel, feeds an empty label and stores it. Then when I request a print job, another empty label is printed and the request is only saved.
Can anyone tell me why this is happening?
I have tried clearing the buffer before and after every request. The buffer seems to get cleared, but the print history still has the previous label somewhere and still reprints it.
I have tried sending the file without printing it and sending a second file with the print command, but it does not replace the previous label until the print is executed.
I have tried sending the file using a different title, but this does not replace the previous image.
I have used the CLL and CLEAR commands before the code, after the code and even in a separate print request.
I have tried with and without the PRINTKEY command. turned it ON and OFF , but still does not work.
This is my CMD code:
PUT ftpData.txt PR1
This is the label code:
CLIP ON
CLIP BARCODE ON
CLL
PP 0,95:AN 7
BARSET "QRCODE",1,1,4,2,2
PB "2762884799"
PP87,100:AN 7
FT "Swiss 721 BT"
FONTSIZE 7
PT "2762884799"
PP87,60:AN 7
FT "Swiss 721 BT"
FONTSIZE 7
PT "27JUL2019"
PP180,32:AN 7
FT "Swiss 721 BT"
FONTSIZE 7
PT "12"
PRINT KEY OFF
PF
CLL
CLEAR
RUN
CMD results:
ftp> open xxx.xxx.xxx.xxx
Connected to xxx.xxx.xxx.xxx.
220 EasyCoder FTP Server v.2024 ready.
ftp> user username password
331 Password required for admin.
230 User logged in.
ftp> PUT ftpData.txt PR1
200 PORT command OK.
150 Opening ASCII mode data connection for 'pr1'
226 Transfer complete.
ftp: 799 bytes sent in 0.20Seconds 3.96Kbytes/sec.
Then the printer prints, but not the current label.
Only the previously saved label is printed and this current label is saved.
Then on the next request, this current label is printed and that next one is only saved.
It turns out that the problem was not in the code, nor was it as a result of a buffer/memory problem.
Internal "Print Engine" settings needed adjusting.
In the past, the printer would feed an extra blank label after every print.
Also, it would retract a bit before printing.
So, to resolve this and streamline the print process, I changed STARTADJ to 0 and STOPADJ to -120.
This fixed the feed problems, but inadvertently caused this new "Reprint" problem.
The printer basically keeps track of where the print job stopped, then adds the new request thereafter.
Conclusion of what happened:
By setting the STOPADJ to -120, after every print command, it basically set the end position of the print job to before the last label started.
Because of this, the starting point for the next print job is before the last printed label, thus the last historic label will be the first to be printed.
It then executes a single print, as per the requested command and PF (PRINTFEED).
The result is that the previous label gets printed and stops before the new label.
This causes a kind of virtual queuing that is always one label behind.
If it was a multi-label print job PF 2 or more, the first label would be the historic version, then it would produce the correct labels thereafter, but still one less than requested because the end position of the print job will be before the last label executes.
I am using a MMA7361 accelerometer from sparkfun that is connected to my arduino uno and it is in turn connected to my pc.
I am simply reading the values from each axis(x,y,z) and sending them straight through the serial port to my pc with a series of Serial.print and Serial.write. From there I have set up a program to read and display the info with myPort.readString();
Now it works fine 80% of the time and it gives the right results and all, but sometimes I get some random value sent through the serial port and it messes up the receiving program making me unable to use the signal properly.
I am pretty sure its not the sensor itself sending the disturbing signal because I have tried to save 10 different readings and then sending an average to minimize the effect with no luck. The receiving pc still got the weird value spikes around 0-200 (from what I saw as output).
I tried with pulling out the cable that connects from the sensor to the analog in port and weirdly it gave out some random value instead of the expected 0, I'm not sure but for me it seems like that has something to do about my problem.
I have read about some kind of pull down resistor but that only works for buttons, right?
I just got my arduino and I'm trying to learn how to use sensors and what you can do with them and what can go wrong so I'd appreciate if someone could help me with this :)
Heres an example of the random value messing up the output:
252:236:218
251:202:215
2 <-- this is where it begins
59:231:245
28
4:144:142 <-- messing up the order of the values
251:19
2:187
246:235
:244
240:190:
238
250:202:2
32
248:243:224
245:227:240
251:228:244
253:223:241
If you want I got the code for sending and recieving too:
Serial.print(analogRead(xpin));
Serial.write(":");
Serial.print(analogRead(ypin));
Serial.write(":");
Serial.println(analogRead(zpin));
I'd really like the sending to be just one line of code but I haven't been able to join all numbers and strings to a one line string on the arduino.
Recieving:
if ( myPort.available() > 0) {
result = myPort.readString();
println(result);
}
Looking at your output, it seems that the values are all received, but somehow a CR and/or LF character is added to the output. And that comes from the println statement:
if ( myPort.available() > 0) {
result = myPort.readString();
println(result);
}
What happens is that the receiving end gets some characters (not necessarily all), it prints them, adding a linefeed character then exits the function.
Then it enters the if statement again and prints the available characters in the buffer. And so it goes.
If you wish to ensure a consistent output you have to either
1. build a packet of the data or
2. Count the received bytes and print them when all are received.
As to 1. it would be my preferred method, add a start- and end-character to the data. The receiving end will then know that all data between the start- and end-character is the data to be printed.
I seem to have fixed this by using readChar and checking if the current character inputted is the delimiter. It is a bit slower but it works.
i need to tell a printer driver to issue a form feed.
i'm printing directly to a printer using the:
OpenPrinter
StartDocPrinter
StartPagePrinter
WritePrinter
EndPagePrinter
EndDocPrinter
ClosePrinter
set of API calls.
A lot of the inspiration came from KB138594 - HOWTO: Send Raw Data to a Printer by Using the Win32 API. An important point to note in that KB article is that they (and my copied code) start the document in RAW mode:
// Fill in the structure with info about this "document."
docInfo.pDocName = "My Document";
docInfo.pOutputFile = NULL;
docInfo.pDatatype = "RAW";
StartDocPrinter(hPrinter, 1, docInfo);
Note: RAW mode (as opposed to TEXT mode) means we are issuing raw bytes to the printer driver. We promise to talk in the language it understands.
We can then use WritePrinter to write everything we want:
WritePrinter(hPrinter, "Hello, world!"); //note, extra parameters removed for clarity
WritePrinter(hPrinter, 0x0c); //form-feed
The problem here is the 0x0c form-feed character. Because we've opened the printer in RAW mode, we are promising we will send the printer driver bytes it can process. The drivers of most printers take 0x0C to mean you want to issue a form-feed.
The problem is that other printers (PDF printer, Microsoft XPS Printers) expect RAW print jobs to be in their own printer language. If you use the above to print to an XPS or PDF printer: nothing happens (i.e. no save dialog, nothing printed).
i asked for a solution to this question a while ago, and a response was that you have to change the document mode from RAW:
docInfo.pDatatype = "RAW";
to TEXT:
docInfo.pDataType = "TEXT";
Well this probably is because you send
"RAW" data directly to the printer,
and RAW can be any PDL. But the XPS
driver will probably only understands
XPS, and it will probably just ignore
your "unknown: Hello, world!0xFF" PDL. The
XPS driver will probably, if any, only
accept XPS data when you write
directly to it.
If you want to render text on the XPS
driver, you should use GDI. You might
be able to send plain text to the
driver if you specify "TEXT" as the
datatype. The print processor attached
to the driver will then "convert" the
plaintext for you by rendering the job
via GDI to the driver.
So that worked, i changed my code to declare the print document as TEXT:
// Fill in the structure with info about this "document."
docInfo.pDocName = "My Document";
docInfo.pOutputFile = NULL;
docInfo.pDatatype = "TEXT";
StartDocPrinter(hPrinter, 1, docInfo);
WritePrinter(hPrinter, "Hello, world!");
WritePrinter(hPrinter, 0x0c); //form-feed
And then the Save As dialog for XPS and PDF printers appear, and it saves correctly. And i thought all was fixed.
Except months later, when i tried to print to a <quote>real</quote> printer: the form-feed doesn't happen - presumably because i am no longer printing in "raw printer commands" mode.
So what i need is the Windows-ish way of issuing a form feed. i need the API call that will tell printer driver that i want the printer to perform a form-feed.
My question: How to tell a printer to issue a Form-Feed during printing?
Background on Data Types
The print processor tells the spooler to alter a job according to the document data type. It works in conjunction with the printer driver to send the spooled print jobs from the hard drive to the printer.
Software vendors occasionally develop their own print processors to support custom data types. Normally, the print processor does not require any settings or intervention from administrators.
Data types
The Windows printing process normally supports five data types. The two most commonly used data types, enhanced metafile (EMF) and ready to print (RAW), affect performance in different ways on both the client computer and the print server computer.
RAW is the default data type for clients other than Windows-based programs. The RAW data type tells the spooler not to alter the print job at all prior to printing. With this data type, the entire process of preparing the print job is done on the client computer.
EMF, or enhanced metafile, is the default datatype with most Windows-based programs. With EMF, the printed document is altered into a metafile format that is more portable than RAW files and usually can be printed on any printer. EMF files tend to be smaller than RAW files that contain the same print job. Regarding performance, only the first portion of a print job is altered, or rendered on the client computer, but most of the impact is on the print server computer, which also helps the application on the client computer to return control to the user faster.
The following table (taken from MSDN) shows the five different data types supported by the default Windows print processor:
Data type: RAW
Directions to spooler: Print the document with no changes.
Use: This is the data type for all clients not based on Windows.
Data type: RAW [FF appended]
Directions to spooler: Append a form-feed character (0x0C), but make no other changes. (A PCL printer omits the document's last page if there is no trailing form-feed.)
Use: Required for some applications. Windows does not assign it, but it can be set as the default in the Print Processor dialog box.
Data type: RAW [FF auto]
Directions to spooler: Check for a trailing form-feed and add one if it is not already there, but make no other changes.
Use: Required for some applications. Windows does not assign it, but it can be set as the default in the Print Processor dialog box.
Data type: NT EMF 1.00x
Directions to spooler: Treat the document as an enhanced metafile (EMF) rather than the RAW data that the printer driver puts out.
Use: EMF documents are created by Windows.
Data type: TEXT
Directions to spooler: Treat the entire job as ANSI text and add print specifications using the print device's factory defaults.
Use: This is useful when the print job is simple text and the target print device cannot interpret simple text.
You can see the print processors available for a printer, and the data types that each processor supports, through the properties of a printer in the control panel:
See also
Send ESC commands to a printer in C#
Feed paper on POS Printer C#
Print raw data to a thermal-printer using .NET
Yeah, that doesn't work. You are intentionally bypassing the printer driver, the chunk of code that presents a universal interface to any printer. Which leaves you to deal with the peculiarities of each specific printer model.
There are some common interfaces, the one you used in your code is the one that dot matrix printers of old used. PCL is common on Hewlett Packard laser printers. Postscript is common on high-end printers. The latter two have their own incantations to get a form feed.
Then there's the ocean of cheap laser and ink jet printers. They often don't have a well defined interface at all. Instead of having a processor inside the printer that translates printer commands to dots on paper, they let the printer driver do all the hard work. You'll never get one of those going, the interface is proprietary and undocumented.
The printer driver is your friend here. PrintDocument the class to use it. Getting a form feed is easy, just set e.HasMorePages = true and exit the PrintPage event handler. You already saw the StreamPrinter class I linked.
I'm unfamiliar with the TEXT document type, but I presume it's just a lowest common denominator "dumb printer" representation. If so, it might recognize a form-feed character, except you've been using the wrong character - it's not 0x12 or 0xFF, it's 0x0c. See http://en.wikipedia.org/wiki/Ascii
Since my last answer was no help, lets try the obvious. Have you tried doing EndPagePrinter followed by StartPagePrinter whenever you need a page break?
If that still doesn't work you may need to do it the hard way, using GDI. The stack looks just slightly different from the one you're using:
CreateDC
CreateFont
SelectObject
StartDoc
StartPage
TextOut
EndPage
EndDoc
DeleteDC
You'll be required to manage a font and place the text on the page yourself at each line position.