I am trying to communicate with Edito (Seiko) KSM347 printer through Serial Port. I have successfully printed data through echo "test" > /dev/usb/lp1 or Java's code:
FileOutputStream fs = new FileOutputStream("/dev/usb/lp1");
PrintStream ps = new PrintStream(fs);
ps.write(cmd); // cmd is bytes with corresponding commands
ps.flush();
It works properly too. But I need to send data and get response. In other projects I have been using RXTX library which was working good with for example Huawei MU609 modems. Now this library does not see these /dev/usb/ ports.
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
// this list contains only /dev/ttyS0 and /dev/ttyUSB0 devices.
How to force RXTX to use these ports? Even setting -Dgnu.io.rxtx.SerialPorts does not work. Please help :)
Related
Background
I am trying to create a java application to send ZPL command to a ZPL printer and get a label printed.
I set up a ZPL emulator(https://chrome.google.com/webstore/detail/zpl-printer/phoidlklenidapnijkabnfdgmadlcmjo) by following this post : Emulate ZPL printer
Issue
After setting the emulator up and add it as zpl printer via mac Printer&Scanner ,
I try to use lp command to print it. it is stable the reliable:
lp -o "raw" -q1 -d zpl <<< "^XA\n^FO50,60^A0,40^FDWorld Best Griddle^FS\n^FO60,120^BY3^BCN,60,,,,A^FD1234ABC^FS\n^FO25,25^GB380,200,2^FS\n^XZ"
However, my use case is send the command to a printer remotely on the network, Therefore I need to create a java application to send the Zpl command to the printer. It succeeds initially, then it randomly get splitted:
java code:
import java.io.*;
import java.net.*;
class TCPClient
{
public static void main (String argv[]) throws Exception
{
Socket clientSocket=new Socket("127.0.0.1",9100);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream() );
try {
outToServer.writeBytes("^XA\n^FO50,60^A0,40^FDWorld Best Griddle^FS\n^FO60,120^BY3^BCN,60,,,,A^FD1234ABC^FS\n^FO25,25^GB380,200,2^FS\n^XZ");
} catch (Throwable e) {
System.out.println(e);
}
outToServer.flush();
outToServer.close();
clientSocket.close();
// outToServer.flush();
}
}
Result:
So quite often, it succeeds once and then following 2 or 3 printing get fragmented or failed. I suspect it might be the socket TCP fragmentation issue. or there any socket option I can configure? But not sure how to solve it. Can anyone help here?
Update:
I try to use wireshark. The issue resides in the TCP package size:
For lp command, everything is sent as one single pack:
As for java app, it is broken down into smaller packs for some reason.
But I still don't know how to configure the pack size. Also it confuses me a lot why Java app will break the data packet to like 1 byte or two byte sized?
I think you are using a wrong method to send printing job. I'm not sure lp command uses Socket connection. Try calling lp from Java using Runtime.getRuntime().exec:
String cmd = "lp -o \"raw\" -q1 -d zpl <<< \"^XA\n^FO50,60^A0,40^FDWorld Best Griddle^FS\n^FO60,120^BY3^BCN,60,,,,A^FD1234ABC^FS\n^FO25,25^GB380,200,2^FS\n^XZ\"";
Runtime.getRuntime().exec(String.format(cmd));
I've created a Java GUI which lists all serial ports in a drop down menu from which the user selects the correct port and clicks connect. Connection to an Arduino is then established and the user is able to perform some actions. I get the available ports using Fazecast JSerialComm:
SerialPort[] ports = SerialPort.getCommPorts();
I grab the ports and put the results into the drop down. This works flawlessly BUT only when the Arduino is plugged into the Mac BEFORE launching my Java GUI. Is there a way to detect a hotplugged device in Java? I already thought of getting the com ports periodically (every second or so) but to me that does seem to be a very elegant solution.
update:
I found this answered by another user:
Serial communication manager have APIs to find serial port names like COMxx dynamically. Just connect your USB-USRT IC and SCM library will tell you the device node for it. Just google for Serial communication manager. It is hosted on GitHub.
src
You might do this by checking if the port is opened or not after trying to open it using:
SerialPort[] serialPorts = SerialPort.getCommPorts();
SerialPort liveSerialPort = null;
for (SerialPort p: serialPorts) {
p.openPort();
if (p.isOpen()) {
liveSerialPort = p;
System.out.println("HERE opened port = " + liveSerialPort.getSystemPortName());
break;
}
}
I am trying to establish a serial communication with a USB driven hardware. Unfortunately, the hardware is not recognized in the device manager under the listed COM ports. Therefore, it does not appear in my list and I don't know its COM port number. Instead the device is listed as another type of hardware.
How can I still connect with it?
I am currently using the following code to open my USB ports.
public ArrayList<String> getPorts() {
CommPortIdentifier serialPortId;
ArrayList<String> portID = new ArrayList<String>();
Enumeration enumComm = CommPortIdentifier.getPortIdentifiers();
while (enumComm.hasMoreElements()) {
serialPortId = (CommPortIdentifier) enumComm.nextElement();
if (serialPortId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
String portString= new String(serialPortId.getName());
portID.add(portString);
}
}
return portID;
}
How can I still connect with it?
You need a java binding to whatever driver the hardware actually uses, like LibUSB or hidapi.
Here is the code that I am implementing for Enumeration of devices. I am able to detect and display all the Serial devices connected.But suppose I connected another device and then try to recall this function, It is always showing the devices that are connected during first run of the code.
Code Snipet:
public void Listports() {
Enumeration ports = null;
ports = CommPortIdentifier.getPortIdentifiers();
CommPortIdentifier portId = null;
{
while (ports.hasMoreElements()) {
portId = (CommPortIdentifier) ports.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL){
System.out.println(portId.getName());
}
}
}
}
i.e. For Example, in the first Call of the function , COM1 and COM3 are displayed.
Now suppose, a Serial Device connected is loaded on COM27. So If we re-run the code it is displaying only COM1 and COM3, and no COM27.
Another scenario, Before my first run of the code a Serial device is loade on COM27. Now on first run it shows COM1,COM3,COM27. Now remove the COM27 device and re-run the above piece of code, It still shows COM27 is connected.
Any Help in this regard is greatly Appreciated.
Thanks,
Abhi
Comm port API
you just get a list op comm ports, you can then for example try if the port is owned aka used by some application with isCurrentlyOwned()
Basicly just iterating a list doesnt tell you anyhting in the list until you further test it.
I am developing an Android application were I am supposed to get the data from a database in csv/txt file format and later I have to send the files to a wifi printer.
Do anyone know how I might get started doing that?
The answer was finally easy :
Socket client = new Socket(_IP, PORT);
oStream = new PrintStream(client.getOutputStream(), true, "UTF-8");
oStream.println("-------------------------------------------------\r\n");
oStream.println(" NAME : DEMO CLIENT\r\n");
oStream.println(" CODE : 00000234242\r\n");
oStream.println(" ADDRESS : Street 52\r\n");
oStream.println(" Phone : 2310-892345\r\n");
oStream.println("-------------------------------------------------\r\n");
oStream.flush();
oStream.close();
client.close();
You could read a data from database to a file directly. and then you can connect the printer via sockets or wifi. And then pass on to the printer.
There are bunch of projects on github, maybe you can look at them, for example EasyPrinter.
You can do this using sockets. You can get examples in these links
http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/
Example: Android bi-directional network socket using AsyncTask
and you can google it. (Socket programming via java and android examples)
So first you must get your printer ip and port and send data to printer via a socket.
To be ui friendly, you can create a setting form where you can set available printers ip and port
Here's an Open Source project to print things with a Bixolon Bluetooth or WiFi printer on Android: https://github.com/rocboronat/FewlapsLovesBixolon