STM32F4 Issue

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
wilczj
Posts: 2
Joined: Tue Feb 10, 2015 3:13 am

STM32F4 Issue

Post by wilczj » Tue Feb 10, 2015 3:21 am

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.

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: STM32F4 Issue

Post by Damien » Tue Feb 10, 2015 5:35 am

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...

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: STM32F4 Issue

Post by dhylands » Tue Feb 10, 2015 6:23 am

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

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Post by Damien » Tue Feb 10, 2015 10:19 am

Ord is not really defined for bytes. It's trying to give you the ordinal value of a single character.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re:

Post by dhylands » Tue Feb 10, 2015 4:00 pm

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/

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Post by Damien » Tue Feb 10, 2015 8:09 pm

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.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: STM32F4 Issue

Post by dhylands » Wed Feb 11, 2015 12:25 am

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.

wilczj
Posts: 2
Joined: Tue Feb 10, 2015 3:13 am

Re: STM32F4 Issue

Post by wilczj » Wed Feb 11, 2015 12:36 am

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!

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: STM32F4 Issue

Post by dhylands » Wed Feb 11, 2015 1:32 am

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'

Post Reply