Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #28077 > unrolled thread

Re: Sending USB commands with Python

Started byDennis Lee Bieber <wlfraed@ix.netcom.com>
First post2012-08-29 18:56 -0400
Last post2012-08-31 08:47 +1000
Articles 8 — 4 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Sending USB commands with Python Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-08-29 18:56 -0400
    Re: Sending USB commands with Python "Adam W." <AWasilenko@gmail.com> - 2012-08-29 16:45 -0700
    Re: Sending USB commands with Python MRAB <python@mrabarnett.plus.com> - 2012-08-30 01:53 +0100
    Re: Sending USB commands with Python Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-08-29 22:07 -0400
      Re: Sending USB commands with Python Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-08-30 00:55 -0400
        Re: Sending USB commands with Python "Adam W." <AWasilenko@gmail.com> - 2012-08-30 05:51 -0700
          Re: Sending USB commands with Python Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-08-30 14:24 -0400
          Re: Sending USB commands with Python Cameron Simpson <cs@zip.com.au> - 2012-08-31 08:47 +1000

#28077 — Re: Sending USB commands with Python

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2012-08-29 18:56 -0400
SubjectRe: Sending USB commands with Python
Message-ID<mailman.3947.1346280975.4697.python-list@python.org>
On Thu, 30 Aug 2012 08:29:32 +1000, Cameron Simpson <cs@zip.com.au>
declaimed the following in gmane.comp.python.general:

> On 29Aug2012 17:57, Dennis Lee Bieber <wlfraed@ix.netcom.com> wrote:
> | On Wed, 29 Aug 2012 14:21:30 -0700 (PDT), "Adam W."
> | <AWasilenko@gmail.com> declaimed the following in
> | gmane.comp.python.general:
> | > You are correct about the 2 being the number of bytes written.  However when I issue a read command I get:
> | > 
> | > >>> ep.write('\x1BA')
> | > 4
> | 
> | 	That's interesting -- as if each byte you send is expanding into a
> | pair of bytes.
> 
> UTF-16? ISTR that Windows often uses big endian UTF-16 for filenames and
> text data; could there be some default encoding in ep.write getting in
> your way?
> 
> Disclaimer: I'm really not a Windows guy.

	I know W9x has both "normal" and "wide" entry points in the system,
and I think WinXP and later default to the "wide" points, but I'd expect
any third party DLL would document what it expects to receive for a
device write operation.

	BUT you do give a possible clue. Is the OP using a 3.x Python where
strings are Unicode -- in which case the above may need to be explicitly
declared as a "byte string" rather than text (unicode) string.

	I've only recently upgraded my desktop to Python 2.7 (and had to
make sure that copying the old "CherryTemplate" from 2.5 was still
functional -- I don't have time to rework a program that builds a set of
static web pages from database information), so can't really check on
sizes.
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
        wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [next] | [standalone]


#28081

From"Adam W." <AWasilenko@gmail.com>
Date2012-08-29 16:45 -0700
Message-ID<mailman.3950.1346283912.4697.python-list@python.org>
In reply to#28077
On Wednesday, August 29, 2012 6:56:16 PM UTC-4, Dennis Lee Bieber wrote:
>
> 	BUT you do give a possible clue. Is the OP using a 3.x Python where
> 
> strings are Unicode -- in which case the above may need to be explicitly
> 
> declared as a "byte string" rather than text (unicode) string.
> 

Huzzah!  I am indeed using 3.x, and slapping on an .encode('utf-8') made my printer try to spit paper at me! Progress.

Also, astute observation about the endpoint needing to be an input, with the following modification I get:

>>> ep.write('\x1BA'.encode('utf-8'))
2
>>> ep = usb.util.find_descriptor(
    intf,
    custom_match = \
    lambda e: \
        usb.util.endpoint_direction(e.bEndpointAddress) == \
        usb.util.ENDPOINT_IN
)
>>> ep.read(1)
array('B', [163])
>>> 

Anyone want to venture a guess on how I should interpret that?  It seems the [163] is the byte data the manual is talking about, but why is there a 'B' there?  If I put paper in it and try again I get: array('B', [3])

Thanks for all your help guys, just about ready to stared coding the fun part!

[toc] | [prev] | [next] | [standalone]


#28083

FromMRAB <python@mrabarnett.plus.com>
Date2012-08-30 01:53 +0100
Message-ID<mailman.3951.1346288000.4697.python-list@python.org>
In reply to#28077
On 30/08/2012 00:45, Adam W. wrote:
> On Wednesday, August 29, 2012 6:56:16 PM UTC-4, Dennis Lee Bieber wrote:
>>
>> 	BUT you do give a possible clue. Is the OP using a 3.x Python where
>>
>> strings are Unicode -- in which case the above may need to be explicitly
>>
>> declared as a "byte string" rather than text (unicode) string.
>>
>
> Huzzah!  I am indeed using 3.x, and slapping on an .encode('utf-8') made my printer try to spit paper at me! Progress.
>
> Also, astute observation about the endpoint needing to be an input, with the following modification I get:
>
>>>> ep.write('\x1BA'.encode('utf-8'))
> 2
>>>> ep = usb.util.find_descriptor(
>      intf,
>      custom_match = \
>      lambda e: \
>          usb.util.endpoint_direction(e.bEndpointAddress) == \
>          usb.util.ENDPOINT_IN
> )
>>>> ep.read(1)
> array('B', [163])
>>>>
>
> Anyone want to venture a guess on how I should interpret that?  It seems the [163] is the byte data the manual is talking about, but why is there a 'B' there?  If I put paper in it and try again I get: array('B', [3])
>
> Thanks for all your help guys, just about ready to stared coding the fun part!
>
The result is an array of bytes ('B'). I think the value means:

0b10100011
          ^Ready
         ^Top of form
     ^No paper
   ^Printer error

The error is that it's out of paper.

[toc] | [prev] | [next] | [standalone]


#28084

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2012-08-29 22:07 -0400
Message-ID<mailman.3952.1346292474.4697.python-list@python.org>
In reply to#28077
On Wed, 29 Aug 2012 16:45:10 -0700 (PDT), "Adam W."
<AWasilenko@gmail.com> declaimed the following in
gmane.comp.python.general:

> 
> Huzzah!  I am indeed using 3.x, and slapping on an .encode('utf-8') made my printer try to spit paper at me! Progress.
> 
> Also, astute observation about the endpoint needing to be an input, with the following modification I get:
> 
> >>> ep.write('\x1BA'.encode('utf-8'))
> 2

	I'm a tad curious if using the notation

		b'\x1bA'

without the .encode() would work.

	My concern is that you may encounter some "string" of data for
printing which the .encode() ends up /changing/ (don't UTF-8 strings use
a high-bit to signal a multi-byte encoding of what had been a single
character?). A pure byte string shouldn't have that problem.

> >>> ep = usb.util.find_descriptor(
>     intf,
>     custom_match = \
>     lambda e: \
>         usb.util.endpoint_direction(e.bEndpointAddress) == \
>         usb.util.ENDPOINT_IN
> )

	Seems tedious to keep swapping -- does USB support bidirectional
connections?

> >>> ep.read(1)
> array('B', [163])
> >>> 
> 
> Anyone want to venture a guess on how I should interpret that?  It seems the [163] is the byte data the manual is talking about, but why is there a 'B' there?  If I put paper in it and try again I get: array('B', [3])

	Per documentation (section 8.6 in Python 2.7.2 library) of "array"
module:

'b' signed char int 1 
'B' unsigned char int 1 


>>> import array
>>> array.array("B", "\x1bB")
array('B', [27, 66])
>>> 
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
        wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#28088

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2012-08-30 00:55 -0400
Message-ID<mailman.3957.1346302513.4697.python-list@python.org>
In reply to#28084
On Wed, 29 Aug 2012 20:53:48 -0700 (PDT), "Adam W."
<AWasilenko@gmail.com> declaimed the following in
gmane.comp.python.general:

> Your notation does work, and I was just coming around to reevaluating the use of the encode because I am getting really odd results when trying to print lines.
> 
> For example I set the byte length to 10 and sent this 500 times or so expecting to get a solid black bar:
> ep.write('\x16FFFFFFFFFF'.encode('utf-8'))

	How many bytes did it claim to send?
> 
> But what I got was a weird stripped pattern...  I feel like a lot of my commands are working by chance, I can't explain to myself why the A in \x1bA isn't being treated as part of the hex.  This stuff always confuses me.
>
	That's the easy one -- \x in a string introduces an 8-bit byte value
-- so only two hex digits well be read. The "A" is interpreted as
regular text.
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
        wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#28111

From"Adam W." <AWasilenko@gmail.com>
Date2012-08-30 05:51 -0700
Message-ID<20c77648-7b1f-4a45-82de-c8721c834394@googlegroups.com>
In reply to#28088
On Thursday, August 30, 2012 12:55:14 AM UTC-4, Dennis Lee Bieber wrote:
>
> 	How many bytes did it claim to send?
> 
11, which is what I expected.  But I changed the byte value to 16 (because I was having trouble getting single digit hex values working in the command) and sent this command:
>>> for x in range(0,500):
	ep.write(b'\x16\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF')

it respond with 500 17's and prints a black bar!  So it looks like whatever concern you had with using encode was coming to fruition.

> 
> 	That's the easy one -- \x in a string introduces an 8-bit byte value
> 
> -- so only two hex digits well be read. The "A" is interpreted as
> 
> regular text.

Interesting, so what if I only wanted to send 4bits as a hex value?  Also can I somehow throw in some binary alongside of hex?  At some point in my program I'm going to need to send some commands preferably in hex along with the binary image data.

[toc] | [prev] | [next] | [standalone]


#28139

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2012-08-30 14:24 -0400
Message-ID<mailman.3982.1346351050.4697.python-list@python.org>
In reply to#28111
On Thu, 30 Aug 2012 05:51:56 -0700 (PDT), "Adam W."
<AWasilenko@gmail.com> declaimed the following in
gmane.comp.python.general:


> 
> Interesting, so what if I only wanted to send 4bits as a hex value?  Also can I somehow throw in some binary alongside of hex?  At some point in my program I'm going to need to send some commands preferably in hex along with the binary image data.

	You will never be able to send something less than 8-bits. I suspect
the printer treats each byte as one column of dots, so you'd probably be
sending \xF0 or \x0F depending on which bit is "top" or "bottom" -- this
would give a half column of ink and the other half would be blank.

	\x??	is the Python notation to represent a binary value in a
string/byte LITERAL.

	Your previous attempt with the "F" was sending ASCII F characters,
hex value 46 (01000110) [was your striped layout one skinny stripe, and
three widths lower a double-width stripe?].

	As long as your image data is in on/off (B/W) bytes (unsigned, or to
simplify, integers in the range 0..255), it should be no problem. 

>>> import random
>>> data = [random.randint(0, 255) for i in range(32)]
>>> data
[25, 134, 166, 159, 253, 121, 114, 110, 18, 122, 197, 233, 127, 216,
188, 89, 10, 201, 250, 32, 231, 32, 99, 7, 227, 122, 166, 172, 21, 78,
17, 166]
>>> bar = bytearray(data)
>>> bar
bytearray(b'\x19\x86\xa6\x9f\xfdyrn\x12z\xc5\xe9\x7f\xd8\xbcY\n\xc9\xfa
\xe7 c\x07\xe3z\xa6\xac\x15N\x11\xa6')
>>> bytes(bar)
'\x19\x86\xa6\x9f\xfdyrn\x12z\xc5\xe9\x7f\xd8\xbcY\n\xc9\xfa \xe7
c\x07\xe3z\xa6\xac\x15N\x11\xa6'
>>> 
>>> bbar = bytes(bar)
>>> for b in bbar:
... 	print "Decimal: %4.4s:\tHex: \\x%2.2X\t%s" % (ord(b), ord(b), b)
... 	
Decimal:   25:	Hex: \x19	
Decimal:  134:	Hex: \x86	?
Decimal:  166:	Hex: \xA6	?
Decimal:  159:	Hex: \x9F	?
Decimal:  253:	Hex: \xFD	??
Decimal:  121:	Hex: \x79	y
Decimal:  114:	Hex: \x72	r
Decimal:  110:	Hex: \x6E	n
Decimal:   18:	Hex: \x12	
Decimal:  122:	Hex: \x7A	z
Decimal:  197:	Hex: \xC5	?
Decimal:  233:	Hex: \xE9	?
Decimal:  127:	Hex: \x7F	
Decimal:  216:	Hex: \xD8	?
Decimal:  188:	Hex: \xBC	?
Decimal:   89:	Hex: \x59	Y
Decimal:   10:	Hex: \x0A	

Decimal:  201:	Hex: \xC9	?
Decimal:  250:	Hex: \xFA	??
Decimal:   32:	Hex: \x20	 
Decimal:  231:	Hex: \xE7	?
Decimal:   32:	Hex: \x20	 
Decimal:   99:	Hex: \x63	c
Decimal:    7:	Hex: \x07	
Decimal:  227:	Hex: \xE3	?
Decimal:  122:	Hex: \x7A	z
Decimal:  166:	Hex: \xA6	?
Decimal:  172:	Hex: \xAC	°
Decimal:   21:	Hex: \x15	
Decimal:   78:	Hex: \x4E	N
Decimal:   17:	Hex: \x11	
Decimal:  166:	Hex: \xA6	?
>>> 

	You might be able to go directly:

bbar = bytes(data)

based on the documentation for Python 3.2.3. I can't even find bytes()
in the 2.7 documentation.

	I suspect your biggest problem will be in converting your image
format (at the minimum, it may be row oriented and you need to generate
columns of 8-rows at a time)


	Try:

data = [		22,	
			0,	1,	3,	7,	15,	31,	63,	127,	255,
			127,	63,	31,	15,	7,	3,	1,	0	]
bbar = bytes(data)

	Set data length to 17, and send bbar...

	If my guess is right, this should put up an equilateral triangle.


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
        wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#28148

FromCameron Simpson <cs@zip.com.au>
Date2012-08-31 08:47 +1000
Message-ID<mailman.3992.1346366887.4697.python-list@python.org>
In reply to#28111
On 30Aug2012 05:51, Adam W. <AWasilenko@gmail.com> wrote:
| On Thursday, August 30, 2012 12:55:14 AM UTC-4, Dennis Lee Bieber wrote:
| > 	How many bytes did it claim to send?
|
| 11, which is what I expected.  But I changed the byte value to 16
| (because I was having trouble getting single digit hex values working
| in the command) and sent this command:
|
| >>> for x in range(0,500):
| 	ep.write(b'\x16\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF')
| 
| it respond with 500 17's and prints a black bar!  So it looks like whatever concern you had with using encode was coming to fruition.

Yeah. Try 'iso8859-1' instead of 'utf-8'. You want to be not translating
the byte values at all. UTF-8 encodes character values over 127 as multibyte
sequences. ISO8859-1 is a 256 code set that does no translation -
character codes in go directly to byte values out.

You're speaking a binary protocol, not text, so you want a one to one
mapping. Better still would be to be using a bytes I/O layer instead of
one with a text->byte translation; I do not know if the USB library
you're using offers such. So try 'iso8859-1'; at least the translation
is a no-op.

Cheers,
-- 
Cameron Simpson <cs@zip.com.au>

B1FF is an archetype, and all you're showing us is one of the more amusing of
his many instantiations.        - Howard E. Motteler <motteler@umbc.edu>
Ah, perhaps Arthur Clarke anticipated this in his celebrated short story,
"The Nine Million Names Of B1FF"? - Nosy <ataylor@nmsu.edu>

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web