How can I simulate a USB printer to LPT on Linux?
You need to set printer in raw mode. In cups\ppd\lpoptions set raw mode.
raw=true, lp -o raw
Linux: Connect Seiko usb printer as serial port
I have the impression the printer is actually installed correctly. usblp2
is the device ID. You should be able to print to the printer, but, as usblp2
is not probably not the standard device, you might have to program the print service (probably cups
) to use that device to print.
Did you check if usblp2 appears in the printers dialog of cups, when you do 'add new printer' (in administratation
)? (You'll probably have to authenticate as administrator)
Note that the printer is not listening to serial commands - it's simulating a parallel port. You can probably print simple things by copying directly to it: cat <some_text> > /dev/usblp2
Raw printing directly to a USB printer, bypassing Windows spooler
Thanks for the comments.
After some more digging around, I found this interesting article on using Windows printer functions provided by usbprint.sys. With a bit of hacking the sample code there seemed to work. I think I'll take this route.
There is the final code given in the article:
/* Code to find the device path for a usbprint.sys controlled
* usb printer and print to it
*/
#include <usb.h>
#include <usbiodef.h>
#include <usbioctl.h>
#include <usbprint.h>
#include <setupapi.h>
#include <devguid.h>
#include <wdmguid.h>
/* This define is required so that the GUID_DEVINTERFACE_USBPRINT variable is
* declared an initialised as a static locally, since windows does not include it
* in any of its libraries
*/
#define SS_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
static const GUID name \
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
SS_DEFINE_GUID(GUID_DEVINTERFACE_USBPRINT, 0x28d78fad, 0x5a12, 0x11D1, 0xae,
0x5b, 0x00, 0x00, 0xf8, 0x03, 0xa8, 0xc2);
void SomeFunctionToWriteToUSB()
{
HDEVINFO devs;
DWORD devcount;
SP_DEVINFO_DATA devinfo;
SP_DEVICE_INTERFACE_DATA devinterface;
DWORD size;
GUID intfce;
PSP_DEVICE_INTERFACE_DETAIL_DATA interface_detail;
intfce = GUID_DEVINTERFACE_USBPRINT;
devs = SetupDiGetClassDevs(&intfce, 0, 0, DIGCF_PRESENT |
DIGCF_DEVICEINTERFACE);
if (devs == INVALID_HANDLE_VALUE) {
return;
}
devcount = 0;
devinterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
while (SetupDiEnumDeviceInterfaces(devs, 0, &intfce, devcount, &devinterface)) {
/* The following buffers would normally be malloced to he correct size
* but here we just declare them as large stack variables
* to make the code more readable
*/
char driverkey[2048];
char interfacename[2048];
char location[2048];
char description[2048];
/* If this is not the device we want, we would normally continue onto the
* next one or so something like
* if (!required_device) continue; would be added here
*/
devcount++;
size = 0;
/* See how large a buffer we require for the device interface details */
SetupDiGetDeviceInterfaceDetail(devs, &devinterface, 0, 0, &size, 0);
devinfo.cbSize = sizeof(SP_DEVINFO_DATA);
interface_detail = calloc(1, size);
if (interface_detail) {
interface_detail->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
devinfo.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiGetDeviceInterfaceDetail(devs, &devinterface, interface_detail,
size, 0, &devinfo)) {
free(interface_detail);
SetupDiDestroyDeviceInfoList(devs);
return;
}
/* Make a copy of the device path for later use */
strcpy(interfacename, interface_detail->DevicePath);
free(interface_detail);
/* And now fetch some useful registry entries */
size = sizeof(driverkey);
driverkey[0] = 0;
if (!SetupDiGetDeviceRegistryProperty(devs, &devinfo, SPDRP_DRIVER, &dataType,
(LPBYTE)driverkey, size, 0)) {
SetupDiDestroyDeviceInfoList(devs);
return;
}
size = sizeof(location);
location[0] = 0;
if (!SetupDiGetDeviceRegistryProperty(devs, &devinfo,
SPDRP_LOCATION_INFORMATION, &dataType,
(LPBYTE)location, size, 0)) {
SetupDiDestroyDeviceInfoList(devs);
return;
}
usbHandle = CreateFile(interfacename, GENERIC_WRITE, FILE_SHARE_READ,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (usbHandle != INVALID_HANDLE_VALUE) {
/* Now perform all the writing to the device ie.
* while (some condition) WriteFile(usbHandle, buf, size, &bytes_written);
*/
CloseHandle(usbHandle);
}
}
}
SetupDiDestroyDeviceInfoList(devs);
}
Thanks again for the suggestions.
C,C++ write on parallel port via USB adapter (LINUX)
Since you don't have an actual parallel port on your computer there isn't anything at the I/O address 0x0378. Since you're using the a USB to parallel adapter, the parallel port is the adapter, not your PC. To the Linux kernel your USB adapter looks like a standard USB printer device. To access you'll need to go through kernel's USB printer device driver. Unfortunately I don't know if it provides the low level access you're looking for. You can use it to print things by sending it a stream of data, but I don't think you can manipulate the state of individual pins.
After looking at the USB Printer Class Specification it looks like it doesn't provide any way to manipulate the data pins the way you want.
Virtual Serial Port for Linux
You can use a pty ("pseudo-teletype", where a serial port is a "real teletype") for this. From one end, open /dev/ptyp5
, and then attach your program to /dev/ttyp5
; ttyp5
will act just like a serial port, but will send/receive everything it does via /dev/ptyp5.
If you really need it to talk to a file called /dev/ttys2
, then simply move your old /dev/ttys2
out of the way and make a symlink from ptyp5
to ttys2
.
Of course you can use some number other than ptyp5
. Perhaps pick one with a high number to avoid duplicates, since all your login terminals will also be using ptys.
Wikipedia has more about ptys: http://en.wikipedia.org/wiki/Pseudo_terminal
Related Topics
How to Put All Command Arguments in One Variable
Bash Script Commands Not Working in Cron
.Rodata Section Loaded in Executable Page
Rename Multiple Files - Linux/Ubuntu
Linking with 32Bit Libraries Under Linux 64Bit
Floating Point Exception (Core Dumped) While Doing Division in Assembly
Google Suggest Query Using Curl
How to Read The Password from The Text File in Perl
Error When Compiling Linux Kernel 3.2 for Arm
How to Add External References in Monodevelop
Find Port Number of Ibm Mq Queue Manager
Difference Between The Commands "Gcloud Compute Ssh" and "Ssh"
Sending Data on Af_Packet Socket
Count Total Number of Pattern Between Two Pattern (Using Sed If Possible) in Linux
Aosp Build Error: Unrecognized Module Type "Hidl_Package_Root"