I have a software that prints out to a thermal printer connected to the comm port, the code below works well.
Open "COM3:" For Output Access Write As #1
Print #1, Space(8) & "FRAKAS LTD"
Print #1, Space(7) & "P.O. Box 7678 SHIMONI"
...
...
Close #1
Now I want to print on the same comm port but from a different computer on the network, is it possible?
You can redirect the serial port across the network by running software at each end. There is some info on Wikipedia here about some solutions - I haven't tried any.
We have used ethernet to serial converters from Moxa - these redirect a local COM port to a remote one without any PC at the remote end. One example is here
if the printer is availabe then you can use the following to prepare text to be printed :
printer.print "text"
to start the actual printing you use the following :
printer.enddoc
Related
Today I installed NodeMCU on one ESP8266 module.
I made a simple telnet server (logging in to the AP is already done and connected)
srv=net.createServer(net.TCP,7200)
srv:listen(23,function(conn)
conn:on("receive", function(conn,telnetdata)
print(telnetdata)
conn:send("Got it\r\n")
end)
conn:on("sent",function(conn)
print("[Sent]");
--conn:close();
--collectgarbage();
end)
end)
I can telnet into the ESP8266 using Putty and I can send static data back to Putty (conn:send("Got it\r\n")).
What I want to do is to send data to Putty from the esp serial port (UART). I've googled for an example without success. BTW I'm using ESPlorer to program the ESP and to send data back to putty.
Instead of using conn:send("Got it\r\n") I want to dynamically type the response. I've tried uart:on callback but I haven't fully understood how it works.
NodeMCU has an "official" Telnet example in the repository. However, that one is also WiFi/socket-based.
If you're connected to the device through ESPlorer (i.e. serial/UART) you can't open another serial connection. See https://stackoverflow.com/a/36779799/131929 for details.
Marcel thank you for your answer.
The link posted is not exactly what I need but it offered good info.
I finally came up with this code that works as a simple bridge between putty and a micro controller (arduino mega 2560 in this case)
socket = net.createServer(net.TCP,7200)
socket:listen(23,function(c)
c:on("receive",function(c,l)
uart.write(0, l)
end)
c:on("disconnection",function(c)
-- not yet implemented
end)
uart.on("data", 0,
function(data)
c:send(data)
end, 0)
end)
I am trying to acquire rs232 data from a device connected to the ESP8266 (data will then be sent our via http/wifi).
I am using max3232 IC to provide the necessary 3.3v TTL to the ESP8266.
I have have connected the max3232 (pin 12) to GPIO pin 13 (rx) on the ESP8266 (I am only receiving data not sending data, so only the rx pin is connected).
The code i am using:
--
--file: test2.lua
--
tst2 = require "tst2"
tst2.start()
--tst2.lua (testing script)
local module = {}
function module.start()
print("in tst2.start")
uart.alt(1) --use alt GPIO pin 13 (Rx)
uart.setup(0, 9600,8, uart.PARITY_NONE, uart.STOPBITS_1,0)
uart.on("data",10,
function(data)
file.open("data.tmp", "w+")
file.writeline("starting")
for i=1,10 do
file.writeline(string.byte(string.sub(data,i,i)) )
end
file.writeline("from uart: ", data)
file.writeline("finished")
file.close()
end, 0)
uart.alt(0) --switch back to standard Rx/Tx pins
end
return module
The rs232 device connected to the ESP8266 is putting out a single alphabetic character every 3 seconds, however the data written to file (data.tmp) is as follows
starting
10
13
10
13
10
13
10
13
10
13
from uart:
finished
file.close()
Problems:
1- The rs232 device is not issuing any newln or cr characters, but these are appearing in the data file.
2- the string "file.close()" is being written to the data file, and looks like it is the actual lua command that follows the final file.writeline command.
3- the alphabetic data is not appearing in the data file.
4- switching back to the standard uart pins via uart.alt(0) does not work (the ESP8266 must be rebooted - this is not a major issue as the standard uart pins are only used during debugging).
I am writing the rs232 data to a file instead of simply printing it out on the screen (I am using ESPlorer v0.2.0) because the uart.alt(1) command redirects the serial port to the alternative ESP8266 gpio pins.
I think I am doing something fundamentally wrong with the uart set up, but i can't tell what it is.
SOLVED:
It appears that you can't connect the ESP8266 to both the serial port for debugging (e.g. the serial port on a pc running ESPlorer) and also have the alternate serial pins (ESP8266 GPIO 13 and 15) connected (to an external serial device) at the same time.
The nodemcu uart.alt() function does not appear to "turn off" the standard serial i/o pins.
Disconnecting the pc from the standard serial i/o pins solved the problem (debugging becomes an issue, but there are work-arounds to resolve this).
(updated) one workaround is to use a simple telnet server to interact with the lua interpreter. you can either connect the ESP8266 to your wifi router or, even better, set it up as an access point (AP) so that all you have to do is to connect your computer to it and then simply telnet in (to the gateway's IP). so, in addition to the telnet code, you'll need set up the AP in your init.lua. full code for the telnet server and the AP setup is below. A nice benefit is that I can program and monitor the ESP8266 from my phone using an off-the-shelf telnet app!
jj = [[
sock = 22 -- just a placeholder, so it stays global. may not be needed.
-- use sock:send("hello") to insert your own custom output to the client.
telnet_srv = net.createServer(net.TCP, 180)
telnet_srv:listen(2323, function(socket)
local fifo = {}
local fifo_drained = true
local function sender(c)
if #fifo > 0 then
c:send(table.remove(fifo, 1))
else
fifo_drained = true
end
end
local function s_output(str)
table.insert(fifo, str)
if socket ~= nil and fifo_drained then
fifo_drained = false
sender(socket)
end
end
sock = socket -- make the socket globally available.
node.output(s_output, 0) -- re-direct output to function s_ouput.
socket:on("receive", function(c, l)
node.input(l) -- works like pcall(loadstring(l)) but support multiple separate line
end)
socket:on("disconnection", function(c)
node.output(nil) -- un-regist the redirect output function, output goes to serial
end)
socket:on("sent", sender)
print("Welcome to NodeMCU world.")
end)
]]
file.open("telnet.lua", "w")
file.write(jj)
file.close()
jj = [[
wifi.setmode(wifi.STATIONAP);
wifi.ap.config({ssid="ESPtest",pwd=""});
print("Server IP Address:",wifi.ap.getip())
dofile("telnet.lua")
]]
file.open("init.lua","w")
file.write(jj)
file.close()
node.restart()
output:
Server IP Address: 192.168.4.1 255.255.255.0 192.168.4.1
>
I am communicating with CUPS using IPP protocol. I have all drivers for my printers installed in CUPS (using .ppd file) and printers got latest firmware.
When I query a job which a printer printing right now it says that the job's state is 'complete' before the printer even finish printing. It seems that the CUPS marks the job as 'complete' when it finish 'uploading' the file.
I would not expect this behaviour and I basically need to know when exactly the printer printed last paper for a job.
The code looks as follow. The self.printer().ippPrinter() is an instance of node-ipp and it points to a printer. To read the the state of the job I am using attribute 'job-state'.
var msg = {
"operation-attributes-tag": {
'job-id': id
}
};
self.printer().ippPrinter().execute("Get-Job-Attributes", msg, function(err, res){
var attributes = res['job-attributes-tag'];
self.setAttributes = attributes;
callback.call(self, attributes);
});
Does anyone know why I am having this issue or .. how to make it working?
Thank you!
CUPS can only forward job-states received from the printer. A lot of printer drivers and protocols work like 'fire and forget'.
Usually IPP printers allow CUPS and other clients to monitor the current job-state until it's finished/printed. Some manufacturers don't implement IPP properly and classify submitted jobs as printed - even if the printer has a paper jam!
Conclusion:
If your printer does not fully support IPP you probably won't be able to check for 'printed successfully'.
RFC 8011 5.3.7.1
If the implementation is a gateway to a printing system that never provides detailed status about the Print Job, the implementation MAY set the IPP Job’s state to ’completed’, provided that it also sets the ’queued-in-device’ value in the Job’s "job-state-reasons" attribute
#Jakub, you may well be communicating with CUPS using IPP... But are you sure that CUPS is communicating with the print device via IPP?
You can check this by running
lpstat -h cupsservername -v
This should return the device URI assigned to each print queue, which CUPS uses to address the actual printing device:
If that URI does contain ipp://, ipps://, http:// or https:// CUPS indeed talks IPP to the print device and you should be able to get actually correct status messages.
But if you see socket:// then CUPS is configured to use the AppSocket method (sometimes also called 'HP Jet Direct' or 'IP Direct Printing') to forward jobs. This is a "fire and forget" protocol. Basically it is the same as if you did run netcat print-device 9100 < myprintfile to shovel the printable data to port 9100 of the printer. The CUPS socket backend handling this spooling to the printer will not get any other acknoledgement from the printer than what TCP/IP provides confirming that the last packet was transfered. Hence it has to close down its process and report to the CUPS daemon successful-ok, even if the printer is still busy spitting out lots paper and will maybe never complete the full job because it runs into a paper jam...
If you see lpd:// the situation is similar (but uses port 515).
You may have success with a full status reporting by switching the CUPS-to-printdevice path from AppSocket or LPD to IPP like so:
sudo lpadmin -p printername ipp://ipaddress-of-printer
or
sudo lpadmin -p printername http://ipaddress-of-printer:631
I have a Zebra GK420d connect to OS X via CUPS. However, when I send files to it that are written in ZPL or EPL they are only printed in plain text.
Am I required to change to mode on the printer?
Contrary to what others said, you don't need to specially add a raw queue.
Instead, you can submit raw files into any queue using -o raw switch:
lpr -P CupsPrinterName -o raw path/to/label.zpl
Printer name can be found over that link in CUPS:
http://localhost:631/printers/
This also works on other platforms that use CUPS, like Linux.
You can create a raw CUPS queue with lpadmin. Here's the command line I used:
lpadmin -p Zebra -E -v usb://Zebra%20Technologies/ZTC%20LP%202824%20Plus?serial=XXXXXX -m raw
You can also set up a raw queue using the CUPS web admin at
http://127.0.0.1:631/
This is a bit more comprehensive answer since I seem to be returning to this question every couple of years. To print with a Zebra or other barcode printers in Linux from command line follow these steps:
List all printer targets and find the printer you want to use:
$ lpinfo -v
network https
serial serial:/dev/ttyS0?baud=115200
serial serial:/dev/ttyS1?baud=115200
network lpd
direct hp
direct usb://GODEX/G500?serial=162203C6
network smb
...
Add new queue:
$ lpadmin -p godex -E -v usb://GODEX/G500?serial=162203C6 -m raw -o usb-unidir-default=true
If your printing is slow (takes long to start), please make sure you added -o usb-unidir-default=true.
Check available queues:
$ lpstat -v
device for godex: usb://GODEX/G500?serial=162203C6
Create a label (text file):
Create a file according to your printer's requirements in EPL (Zebra), ZPL (Zebra), EZPL (Godex).
Warning, certain CUPS versions might have an issue with raw files if they are under 512 bytes of length - longer files will print, while shorter will print once and then stall for a couple of minutes (looks like there is a timeout built in). A workaround is to add comments to extend it over 512 byte limit.
Example Zebra file (test.epl):
N
A20,20,0,2,1,1,N,"text"
B20,40,0,1,1,1,30,N,"aaaa-bbbb-cccc"
P1
Example Godex file (test.ezpl):
;set portrait orientation
^XSET,ROTATION,0
;set height 20mm
^Q20,1
;set width 64mm
^W64
;start label
^L
;AA=print out text with smallest font, x=20dots, y=20dots, magnificationx=0, magnificationy=0, gap=1dot, rotationInverse=0 (no)
AA,20,20,0,0,1,0,Some sample text
;BQ=code128, x=20dots,y=40dots,narrow_bar_width=1,wide_bar_width:2,height=30dots,rotation=0deg,readable=0(no)
BQ,20,40,1,2,30,0,0,1234-1243-43214-432141
;end label
E
Push to printer:
$ lpr -P godex test.ezpl
You would need to avoid any filtering. Print using a RAW filter, as configured in the CUPS interface, or by default in your lpadmin statement. You did not state how the printer was connected, but if IP, your destination would most-likely be socket://ip.addr.ess:9100.
I am a PC guy so I don't know CUPS well, but I have used zpl and epl on PC's and found that they really like to get the raw print files. I always do a :
filecopy "c:\zplfile.txt" "\computername\printershare" type command.
I have used wordpad too, if I just want to do some text. But for labels and barcodes I would see if there is a way for you to send the raw zpl or epl to the printer port. Hope this helps.
Thanks. I have looked at it some more. It seems that while using cups you cannot send raw ZPL commands to the printer. Like what I did was create the printer in cups as a socket and started a netcat listener on 9100 and then issued some sort of command to the printer
nc -l localhost 9100
zpl_mine="^XA ~SD10 ^PW 850 ^MM T ^MN W ^JUS ^XZ,";echo $zpl_mine | nc localhost 9100 -w 1
and this does not send the information to the printer, but I have seen on some forums that you have to use some form of language like C to parse the information
Having a strange problem where a print occasionally is not being printed
The scenario is that we print barcode labels with a barcode printer (Zebra LP2844).
Printer is plugged into the TerminalPC and then shared.
Printer->TerminalPC -> Terminal Server.
Session on TerminalServer is using Printer as \TerminalPC\Printer
When logging print Events we see the following:
Print OK:
1) Print OK (Event 10, User myUser)
2) Print deleted (Event 13, User NT-AUTHORITY\SYSTEM)
Print not OK => only Event 2) appears in the event log
Anybody having a clue about what is happening here?
More information:
This problems occurs about 2 out of 10 times. Only difference is an increasing ID being printed as part af the barcode.
The barcode is the only object being printed. It saves to file (*.emf) every time - and looks fine on file.
The application is developed using Delphi 2010 and works fine in all other ways.
Print jobs are removed from the print spooler by the port monitor. The port monitor "EndDocPort" function calls "SetJob" with JOB_CONTROL_SENT_TO_PRINTER to indicate the the job has finished, and this removes it from the spooler.
If the printer uses a custom port monitor, the problem could be in the printer driver or custom port monitor. If it uses a standard port such as LPT or USB, it's more likely a problem with the application not calling "EndDoc" consistently, or not checking return codes from EndDoc.