Page 1 of 1

STM32F4 Issue

Posted: Tue Feb 10, 2015 3:21 am
by wilczj
To give some background, I have ported the STM32F4 micropython to windows as an Em::blocks project. So I understand if there might be a build difference but I've done my best to keep everything 1:1.

All seems to be working pretty well, but I run into an odd issue when using the ord() command. The following script, causes an error

Code: Select all

# main.py -- put your code here!
import math
import os

x = ord(os.urandom(1))%100
z = 0
b = 0
n = 0
leds = [pyb.LED(i) for i in range(1,5)]

while x != int(z):
   b=b+1
   z = input("Guess My Number: ")
   if int(z) < x: print("Higher!")
   if int(z) > x: print("Lower!")
   n = (n + 1) % 4
   leds[n].toggle()
print("Correct! " + str(b) + " tries.")
Traceback (most recent call last):
File "main.py", line 5, in <module>
TypeError: ord() expected a character, but string of length 0 found

So it seems to have to due with the ord() command, I can recreate this issue by repeatedly sending this command via REPL...sometimes it works sometimes it has the issue. os.urandom() seems to work just fine all the time, but wrapped in ord() seems to fail randomly.

>>> os.urandom(1)
b'C'
>>>
>>> os.urandom(1)
b'\x99'
>>>
>>> os.urandom(1)
b' '
>>> os.urandom(1)
b'\xad'
>>> os.urandom(1)
b'1'
>>> ord(os.urandom(1))
83
>>> ord(os.urandom(1))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 0 found
>>> ord(os.urandom(1))
32
>>> ord(os.urandom(1))
28
>>> ord(os.urandom(1))
1
>>> ord(os.urandom(1))
84
>>> ord(os.urandom(1))
68
>>> ord(os.urandom(1))
104
>>> ord(os.urandom(1))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 0 found
>>> ord(os.urandom(1))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 0 found
>>> ord(os.urandom(1))
35
>>> ord(os.urandom(1))
31
>>> ord(os.urandom(1))
98
>>> ord(os.urandom(1))
40
>>> ord(os.urandom(1))
122
>>> ord(os.urandom(1))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 0 found
>>> ord(os.urandom(1))
84
>>> ord(os.urandom(1))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 0 found
>>> ord(os.urandom(1))
209
>>> ord(os.urandom(1))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 0 found
>>> ord(os.urandom(1))
239
>>> ord(os.urandom(1))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 0 found
>>> ord(os.urandom(1))

Has anyone seen this before? Or do you think this might be an issue with my port?

Thanks for any help.

Re: STM32F4 Issue

Posted: Tue Feb 10, 2015 5:35 am
by Damien
Try os.urandom(1)[0] that is the better way to get the value. The odd thing is that sometimes urandom returns no bytes at all...

Re: STM32F4 Issue

Posted: Tue Feb 10, 2015 6:23 am
by dhylands
I think that something unicode is happening.

Code: Select all

>>> ord(b'\xa4')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 0 found

Posted: Tue Feb 10, 2015 10:19 am
by Damien
Ord is not really defined for bytes. It's trying to give you the ordinal value of a single character.

Re:

Posted: Tue Feb 10, 2015 4:00 pm
by dhylands
Damien wrote:Ord is not really defined for bytes. It's trying to give you the ordinal value of a single character.
I used that example because that's one of the values I got from urandom(1).

And it works fine under python3:

Code: Select all

2100 >python3
Python 3.4.0 (default, Apr 11 2014, 13:05:11) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> ord(b'\xa4')
164
>>> 
So it looks like the python3 iplementation is slightly more expansive than the docs, and I found references to it being used with bytes:
http://code.activestate.com/recipes/510 ... onversion/

Posted: Tue Feb 10, 2015 8:09 pm
by Damien
Interesting.... But that specific example is written for Py2 (note the print statements).

We'd have to go out of our way (in the code) to take ord of a bytes object.

Re: STM32F4 Issue

Posted: Wed Feb 11, 2015 12:25 am
by dhylands
Right now, it seems the only way I can get the integer value of a byte, is to do:

Code: Select all

import struct
>>> import struct
>>> struct.unpack("i", b'\xff')[0]
255
Oh - that's what you were referring to with the array index?

Code: Select all

>>> val = b'\xff'
>>> val[0]
255
So that's probably the simplest way given that ord doesn't work.

I've never seen urandom return a zero length string. Just the error from ord(b'\xab') returning an error about a string of length zero.

Re: STM32F4 Issue

Posted: Wed Feb 11, 2015 12:36 am
by wilczj
Thank you very much for all of the input. Was just testing some stuff out and stumbled upon this, I like the struct method as an alternative way to convert from byte to int.

Thanks again!

Re: STM32F4 Issue

Posted: Wed Feb 11, 2015 1:32 am
by dhylands
It looks like you can also do:

Code: Select all

>>> int.from_bytes(b'\xab')
171
and the converse:

Code: Select all

>>> (171).to_bytes(1, 'little')
b'\xab'
and also multibyte:

Code: Select all

>>> (0x12345678).to_bytes(4, 'little')
b'xV4\x12'
>>> int.from_bytes(b'xV4\x12', 'little')
305419896
>>> hex(int.from_bytes(b'xV4\x12', 'little'))
'0x12345678'