Teensy 4.1 USB Host with ESC/POS Printer

Status
Not open for further replies.

cslehel

Member
Hello Teensy forum,

i would like to use the Teensy 4.1 board to send ESC/POS commands to a thermal printer.

I tried the following libraries but without success:
https://github.com/gdsports/USBPrinter_t36
https://github.com/gdsports/ESC_POS_Printer

I downloaded the latest USBHost_t36 library from:
https://github.com/PaulStoffregen/USBHost_t36

The USBPrinter_t36 library is using the stripped down serial.cpp library from USBHost_t36.

Can i map my printer in the USBHost_t36's serial.cpp ?
Where can i find the values for mk_setup parameters ?

The printer is detected with the HIDDeviceInfo example and with the SerialTest example i got the following debug information:

Code:
port change: 10001003
    connect
  begin reset
port change: 10001005
  port enabled
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 00 00 00 08 19 05 02 00 00 04 00 02 00 01 
    VendorID = 0519, ProductID = 0002, Version = 0400
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
enumeration:
Product: TUP592 (ESP-001)
enumeration:
Config data length = 32
enumeration:
Configuration Descriptor:
  09 02 20 00 01 01 00 C0 05 
    NumInterfaces = 1
    ConfigurationValue = 1
  09 04 00 00 02 FF 00 FF 00 
    Interface = 0
    Number of endpoints = 2
    Class/Subclass/Protocol = 255 / 0 / 255
  07 05 01 02 40 00 00 
    Endpoint = 1 OUT
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
  07 05 82 02 40 00 00 
    Endpoint = 2 IN
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
enumeration:
USBSerial(64)claim this=200024C0
vid=519, pid=2, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
09 04 00 00 02 FF 00 FF 00 07 05 01 02 40 00 00 07 05 82 02 40 00 00 
Descriptor 4 = INTERFACE
USBSerial(64)claim this=200024C0
vid=519, pid=2, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
09 04 00 00 02 FF 00 FF 00 07 05 01 02 40 00 00 07 05 82 02 40 00 00 
Descriptor 5 = ENDPOINT
Descriptor 5 = ENDPOINT
port change: 1C00100A
    disconnect
disconnect_Device:
USBDriver (available_drivers) list: 200024C0
USBDriver (dev->drivers) list: (empty
USBDriver (available_drivers) list: 200024C0
delete_Pipe 20003400
  shut down async schedule
  Free transfers
  Free transfers attached to QH
    * 536884544
* Delete Pipe completed
removed Device_t from devlist
  disable

Thank you for any information you can offer.
 
I tried with another printer and its working.
I also tried with CC2531, FTDI and a RS232 to USB adapter connected to a barcode scanner.
I can read the barcode and the others are showing connected and disconnected in the Serial Monitor, only with the ESC/POS printer i have problem.

Does anyone have any idea why the ESC/POS printer not connecting to the board ?
 
The USB device does not identify itself as a USB printer class device. The (class,subclass,protocol) is (255,0,255) which means vendor specific. A USB printer class device would have class = 7.

Consult the printer manual to see if there are any options to configure the USB descriptors to USB printer class. If not, the printer might work as a generic USB serial but I do not know. Try printing something like "Hello printer\r\n". You may have to experiment with baud rate, data bits, etc.
 
Thank you very much for your reply.
I can set the printer Emulation ( Line Mode and ESC/POS) and the USB Mode (Printer Class and Vendor Class).
If i remember correctly the current USB Mode is the Vendor Class because in this mode showing as a COM port.
When i get home i will try the Printer Class mode.

I can send commands to the printer even if its not showing as connected in the Serial Monitor with the SerialTest.ino loaded ?
 
When in Vendor Class USB Mode the following Python script is printing:

Code:
import serial

serial_handler = serial.Serial( port = 'COM17', baudrate = 9600, bytesize = serial.EIGHTBITS, parity = serial.PARITY_NONE, stopbits = serial.STOPBITS_ONE, timeout = 1 )

try:
    serial_handler.open()
except Exception as exception_01:
    print( 'Serial port open error: ', exception_01 )

request = [ 0x1b, 0x40, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x1d, 0x56, 0x0 ]

serial_handler.write( request )
serial_handler.close()

I switched to Printer Class USB Mode and the printer under Windows Device Manager showing under Software Device category and not under Ports (COM & LPT).

With the SerialTest.ino running on Teensy 4.1 i have the following debug information:

Code:
USB Host Testing - Serial
USB2 PLL running
 reset waited 6
USBHS_ASYNCLISTADDR = 0
USBHS_PERIODICLISTBASE = 20005000
periodictable = 20005000
port change: 10001803
    connect
port change: 1C001002
    disconnect
port change: 10001803
    connect
  begin reset
port change: 10001005
  port enabled
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 00 00 00 08 19 05 01 00 00 04 00 02 00 01 
    VendorID = 0519, ProductID = 0001, Version = 0400
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
enumeration:
Product: TUP592 (ESP-001)
enumeration:
Config data length = 32
enumeration:
Configuration Descriptor:
  09 02 20 00 01 01 00 C0 05 
    NumInterfaces = 1
    ConfigurationValue = 1
  09 04 00 00 02 07 01 02 00 
    Interface = 0
    Number of endpoints = 2
    Class/Subclass/Protocol = 7 / 1 / 2
  07 05 01 02 40 00 00 
    Endpoint = 1 OUT
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
  07 05 82 02 40 00 00 
    Endpoint = 2 IN
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
enumeration:
USBHub memory usage = 960
USBHub claim_device this=200035E0
USBHub memory usage = 960
USBHub claim_device this=200039A0
USBHub memory usage = 960
USBHub claim_device this=20003D60
USBHub memory usage = 960
USBHub claim_device this=20002E60
USBHub memory usage = 960
USBHub claim_device this=20003220
USBSerial(64)claim this=20002800
vid=519, pid=1, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
09 04 00 00 02 07 01 02 00 07 05 01 02 40 00 00 07 05 82 02 40 00 00 
Descriptor 4 = INTERFACE
USBSerial(64)claim this=20002800
vid=519, pid=1, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0
09 04 00 00 02 07 01 02 00 07 05 01 02 40 00 00 07 05 82 02 40 00 00 
Descriptor 5 = ENDPOINT
Descriptor 5 = ENDPOINT

I tried to send the ESC/POS command from the Teensy 4.1 but without success:

Code:
byte message[] = { 0x1b, 0x40, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x1d, 0x56, 0x0 };
userial.write( message, sizeof( message ) );

At this moment i have the following settings in the SerialTest.ino:

Code:
#define USBBAUD 9600

uint32_t baud = USBBAUD;
uint32_t format = USBHOST_SERIAL_8N1;

USBHost myusb;
USBSerial userial( myusb );

USBDriver *drivers[] = { &userial };
const char * driver_names[ CNT_DEVICES ] = { "USERIAL1" };
bool driver_active[ CNT_DEVICES ] = { false };

This is how i can set the baud rate, bytesize, parity and stopbits ?
 
The the example of USBPrinter_t36 has detected the printer in the Printer Class USB Mode, but the ESC_POS_Printer library examples are not working.

Code:
USB Host Testing - Printer

*** Device RECEIPT1 519:1 - connected ***
  product: TUP592 (ESP-001)
*** Device RECEIPT1 - disconnected ***
 
The example program Printer.ino detects the printer then it creates a pass through between the USB serial port (Serial) and the USB printer port. Open the Arduino Monitor (baud rate does not matter since it is native USB) and type "hello printer". You may have experiment the line ending. Might be '\n' or '\r' or '\n' + '\r'.

When using the printer driver, baud rate is not needed.

If you prefer, modify Printer.ino by adding a line after uprinter.begin() like this. This will print 1 line once. Note use uprinter, not userial.

uprinter.begin();
uprinter.write("hello printer\r\n");
 
Thank you for guiding me.

I modified the Printer.ino like you told me but without success.

Tried also with

byte message[] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x1d, 0x56, 0x0 };

and

char message[] = "Hello\n\n\n\n\n\n\n";

but the printer is not responding.

I wrote a Python code with pyusb library which works with the printer:

Code:
import usb.core

device = usb.core.find( idVendor = 0x0519, idProduct = 0x0001 )
if device is None:
    raise ValueError( 'Device not found' )
else:
    print( device )
    device.write( 0x01, 'Hello\n\n\n\n\n\n\n\x1dV\x00', 0 )

I have the following debug information:

Code:
USB Host Testing - Printer
USB2 PLL running
 reset waited 6
USBHS_ASYNCLISTADDR = 0
USBHS_PERIODICLISTBASE = 20003000
periodictable = 20003000
port change: 10001803
    connect
port change: 1C001002
    disconnect
port change: 10001803
    connect
  begin reset
port change: 10001005
  port enabled
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 00 00 00 08 19 05 01 00 00 04 00 02 00 01 
    VendorID = 0519, ProductID = 0001, Version = 0400
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
enumeration:
Product: TUP592 (ESP-001)
enumeration:
Config data length = 32
enumeration:
Configuration Descriptor:
  09 02 20 00 01 01 00 C0 05 
    NumInterfaces = 1
    ConfigurationValue = 1
  09 04 00 00 02 07 01 02 00 
    Interface = 0
    Number of endpoints = 2
    Class/Subclass/Protocol = 7 / 1 / 2
  07 05 01 02 40 00 00 
    Endpoint = 1 OUT
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
  07 05 82 02 40 00 00 
    Endpoint = 2 IN
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
enumeration:
USBPrinter claim this=20001E20
vid=519, pid=1, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0, type =0
09 04 00 00 02 07 01 02 00 07 05 01 02 40 00 00 07 05 82 02 40 00 00 
    Interface: 0
    Alternate: 0
  Interface is Bi-directional printer
07 05 01 02 40 00 00 
type: 5
     Endpoint: 1
      tx_size = 64
07 05 82 02 40 00 00 
type: 5
     Endpoint: 82
      rx_size = 64
  exited loop rx:2, tx:1
  rx buffer size:196
  tx buffer size:196
new_Pipe
new_Pipe
Control 
*** Device RECEIPT1 519:1 - connected ***
  product: TUP592 (ESP-001)
txtimer
  TX data (7) 48 65 6C 6C 6F 0A 0A 
port change: 1C00100A
    disconnect
disconnect_Device:
USBDriver (available_drivers) list: (empty
USBDriver (dev->drivers) list: 20001E20
disconnect driver 20001E20
USBDriver (available_drivers) list: 20001E20
delete_Pipe 20001F00
  remove QH from async schedule
  Free transfers
    * 536884544
    * 536879328 * remove * free
    * 536884416 * remove * defer free until QH
  Free transfers attached to QH
    * 536884416
    * 536878944
* Delete Pipe completed
delete_Pipe 20001EA0
  remove QH from async schedule
  Free transfers
    * 536884544 * remove * free
  Free transfers attached to QH
    * 536879264
* Delete Pipe completed
delete_Pipe 20003400
  shut down async schedule
  Free transfers
  Free transfers attached to QH
    * 536879136
* Delete Pipe completed
removed Device_t from devlist
  disable
*** Device RECEIPT1 - disconnected ***
 
If i set the printer to Vendor Class USB Mode i can see as a COM port in the Windows Device Manager and i can use a Python script to print.
In the serial.cpp from the USBHost_t36 library there is an array pid_vid_mapping containing pid's and vid's of some serial devices.
I have an USB to Serial adapter which is recognized by the USBHost_t36 library example.
How could i add the printer to the pid_vid_mapping ?
 
I can't help with the vendor specific COM mode. I suggest adding more debug output to see why it is failing.

It has been a while since I last used the printer driver so I tested with Arduino IDE 1.8.13 and Teensyduino 1.53. The driver works on Teensy 3.6 and 4.1 using my printer. I tested with a battery powered mobile receipt printer.

I do not know why your printer is failing in USB printer class mode. Does it work connected to a PC in USB printer class mode?
 
Here is how i tested.

Downloaded and unpacked Arduino 1.8.13.
Installed Teensyduino 1.53 on the unpacked Arduino 1.8.13.
Downloaded and unpacked the USBPrinter_t36 library to Arduino\hardware\teensy\avr\libraries.
Uncommented the USBHOST_PRINT_DEBUG in Arduino\hardware\teensy\avr\libraries\USBHost_t36\USBHost_t36.h
Added this code

Code:
byte message[] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xa, 0xa, 0x1d, 0x56, 0x0 };
uprinter.write( message, sizeof( message ) );

after uprinter.begin(); in the Arduino\hardware\teensy\avr\libraries\USBPrinter_t36\examples\Printer\Printer.ino
Compiled and uploaded to Teensy 4.1.


The board settings are:
Board: Teensy 4.1
USB Type: Serial
CPU Speed: 600 MHz
Optimize: Faster
Keyboard Layout: US English
Port: COM15 Serial (Teensy 4.1)h


In the debug info there is a line where the message is sent but the printer is not responding:
txtimer
TX data (10) 48 65 6C 6C 6F 0A 0A 1D 56 00

After this you have this command:
queue_Data_Transfer(txpipe, p, count, this);
Should i debug this command ?


Code:
USB Host Testing - Printer
USB2 PLL running
 reset waited 6
USBHS_ASYNCLISTADDR = 0
USBHS_PERIODICLISTBASE = 20005000
periodictable = 20005000
port change: 10001803
    connect
  begin reset
port change: 10001005
  port enabled
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 00 00 00 08 19 05 01 00 00 04 00 02 00 01 
    VendorID = 0519, ProductID = 0001, Version = 0400
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
enumeration:
Product: TUP592 (ESP-001)
enumeration:
Config data length = 32
enumeration:
Configuration Descriptor:
  09 02 20 00 01 01 00 C0 05 
    NumInterfaces = 1
    ConfigurationValue = 1
  09 04 00 00 02 07 01 02 00 
    Interface = 0
    Number of endpoints = 2
    Class/Subclass/Protocol = 7 / 1 / 2
  07 05 01 02 40 00 00 
    Endpoint = 1 OUT
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
  07 05 82 02 40 00 00 
    Endpoint = 2 IN
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
enumeration:
USBHub memory usage = 960
USBHub claim_device this=20003DA0
USBHub memory usage = 960
USBHub claim_device this=20004160
HIDParser claim this=20002500
HIDParser claim this=20002B20
HIDParser claim this=20003140
USBPrinter claim this=20003760
vid=519, pid=1, bDeviceClass = 0, bDeviceSubClass = 0, bDeviceProtocol = 0, type =0
09 04 00 00 02 07 01 02 00 07 05 01 02 40 00 00 07 05 82 02 40 00 00 
    Interface: 0
    Alternate: 0
  Interface is Bi-directional printer
07 05 01 02 40 00 00 
type: 5
     Endpoint: 1
      tx_size = 64
07 05 82 02 40 00 00 
type: 5
     Endpoint: 82
      rx_size = 64
  exited loop rx:2, tx:1
  rx buffer size:196
  tx buffer size:196
new_Pipe
new_Pipe
Control 
*** Device RECEIPT1 519:1 - connected ***
  product: TUP592 (ESP-001)
txtimer
  TX data (10) 48 65 6C 6C 6F 0A 0A 1D 56 00 

=============================================================================================

port change: 1C00100A
    disconnect
disconnect_Device:
USBDriver (available_drivers) list: 20003DA0 -> 20004160 -> 20002500 -> 20002B20 -> 20003140
USBDriver (dev->drivers) list: 20003760
disconnect driver 20003760
USBDriver (available_drivers) list: 20003760 -> 20003DA0 -> 20004160 -> 20002500 -> 20002B20 -> 20003140
delete_Pipe 20003840
  remove QH from async schedule
  Free transfers
    * 536892736
    * 536885728 * remove * free
    * 536885536 * remove * defer free until QH
  Free transfers attached to QH
    * 536885536
    * 536892608
* Delete Pipe completed
delete_Pipe 200037E0
  remove QH from async schedule
  Free transfers
    * 536892736 * remove * free
  Free transfers attached to QH
    * 536885792
* Delete Pipe completed
delete_Pipe 20005400
  shut down async schedule
  Free transfers
  Free transfers attached to QH
    * 536885600
* Delete Pipe completed
removed Device_t from devlist
  disable
*** Device RECEIPT1 - disconnected ***


The
txtimer
TX data (10) 48 65 6C 6C 6F 0A 0A 1D 56 00
is exactly the same as the Wireshark capture made when i tested with a Python code ( 48656c6c6f0a0a1d5600 ).


Code:
No.     Time           Source                Destination           Protocol Length Info
      1 0.000000       host                  1.4.0                 USB      36     GET DESCRIPTOR Request STRING

Frame 1: 36 bytes on wire (288 bits), 36 bytes captured (288 bits) on interface wireshark_extcap1844, id 0
USB URB
Setup Data

No.     Time           Source                Destination           Protocol Length Info
      2 0.000298       1.4.0                 host                  USB      32     GET DESCRIPTOR Response STRING

Frame 2: 32 bytes on wire (256 bits), 32 bytes captured (256 bits) on interface wireshark_extcap1844, id 0
USB URB
STRING DESCRIPTOR

No.     Time           Source                Destination           Protocol Length Info
      3 0.000508       host                  1.4.0                 USB      36     GET DESCRIPTOR Request STRING

Frame 3: 36 bytes on wire (288 bits), 36 bytes captured (288 bits) on interface wireshark_extcap1844, id 0
USB URB
Setup Data

No.     Time           Source                Destination           Protocol Length Info
      4 0.001117       1.4.0                 host                  USB      62     GET DESCRIPTOR Response STRING

Frame 4: 62 bytes on wire (496 bits), 62 bytes captured (496 bits) on interface wireshark_extcap1844, id 0
USB URB
STRING DESCRIPTOR

No.     Time           Source                Destination           Protocol Length Info
      5 0.002508       host                  1.4.1                 USB      37     URB_BULK out

Frame 5: 37 bytes on wire (296 bits), 37 bytes captured (296 bits) on interface wireshark_extcap1844, id 0
USB URB
Leftover Capture Data: 48656c6c6f0a0a1d5600

No.     Time           Source                Destination           Protocol Length Info
      6 0.002576       1.4.1                 host                  USB      27     URB_BULK out

Frame 6: 27 bytes on wire (216 bits), 27 bytes captured (216 bits) on interface wireshark_extcap1844, id 0
USB URB


This Python code is working when the printer is in Printer Class USB Mode


Code:
import usb.core

device = usb.core.find( idVendor = 0x0519, idProduct = 0x0001 )
if device is None:
    raise ValueError( 'Device not found' )
else:
    print( device )
    device.write( 0x01, 'Hello\n\n\x1dV\x00', 0 )


The debug info displayed by the Python code:


Code:
DEVICE ID 0519:0001 on Bus 001 Address 004 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x200 USB 2.0
 bDeviceClass           :    0x0 Specified at interface
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x0
 bMaxPacketSize0        :    0x8 (8 bytes)
 idVendor               : 0x0519
 idProduct              : 0x0001
 bcdDevice              :  0x400 Device 4.0
 iManufacturer          :    0x0 
 iProduct               :    0x2 TUP592 (ESP-001)
 iSerialNumber          :    0x0 
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 10 mA ===================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x20 (32 bytes)
   bNumInterfaces       :    0x1
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0xc0 Self Powered
   bMaxPower            :    0x5 (10 mA)
    INTERFACE 0: Printer ===================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x2
     bInterfaceClass    :    0x7 Printer
     bInterfaceSubClass :    0x1
     bInterfaceProtocol :    0x2
     iInterface         :    0x0 
      ENDPOINT 0x1: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x1 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
      ENDPOINT 0x82: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x82 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
 
-

XMOS USB might require proprietary driver check with your manufacturer to see if one is available?

When you switched computers, did you also switch USB cables? Use the cable from your laptop that works, and try it on the desktop.
 
I used the same cable with Teensy 4.1 and the PC.

I will try to run the same Python scripts on a Raspberry to see if the printer is working on Linux.
 
Status
Not open for further replies.
Back
Top