Raw REPL not receiving output

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
markusc90
Posts: 4
Joined: Tue Jun 23, 2015 9:23 pm

Raw REPL not receiving output

Post by markusc90 » Wed Aug 17, 2016 12:16 am

Hi all,

When I run a script on CPython to communicate with the pyboard using pyboard.py, I'm not receiving the return value from the function on the micropython side.

For example purposes, I have a module on the pyboard, ayo.py, containing:

Code: Select all

def getInt():
    return 23
	
def getList():
    return [1, 2, 3]
	
def getBytes():
    return bytearray([1, 2, 3])
The only purpose it serves is to provide some kind of object to return.

And my script on CPython (2.7):

Code: Select all

import pyboard

pybo = pyboard.Pyboard('COM5')

pybo.enter_raw_repl()

pybo.exec_("import ayo")
print pybo.exec_("ayo.getInt()")
print pybo.exec_("ayo.getList()")
print pybo.exec_("ayo.getBytes()")

pybo.exit_raw_repl()
pybo.close()
Unfortunately it doesn't seem to be printing anything. Is there a reason why the pyboard isn't returning anything from the exec_ function? It's not throwing any errors or anything.

Thanks,
Markus
Last edited by markusc90 on Wed Aug 17, 2016 4:53 pm, edited 1 time in total.

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

Re: Raw REPL not receiving output

Post by dhylands » Wed Aug 17, 2016 3:10 am

You need to print your object on the raw repl and then collect and exec that in CPython on the host.

That's essentially how rshell works. rshell takes a function on the CPython side, gets the source code for it, sends it to the pyboard using the raw repl, executes it and prints the output of running the function. See: https://github.com/dhylands/rshell/blob ... 1155-L1162

That output is then used "as-is" or eval'd depending on the usage.

Upon closer examination, I think I see that the problem might be. It's intended that you enter raw repl, send across the code you want to execute and then it actually compiles and executes the code you sent.

Calling exec_ winds up calling exec_no_follow which means it doesn't wait for the output of the executed script on the pyboard. You need to do a follow someplace to ensure that you get the output.

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

Re: Raw REPL not receiving output

Post by dhylands » Wed Aug 17, 2016 3:27 am

Here's a script I wrote that sets the RTC on the pyboard, using the raw repl:
https://github.com/dhylands/upy-example ... ync_rtc.py

markusc90
Posts: 4
Joined: Tue Jun 23, 2015 9:23 pm

Re: Raw REPL not receiving output

Post by markusc90 » Wed Aug 17, 2016 5:28 pm

Thank you for the reply.

I will try to use your remote function. I see that it calls enter_raw_repl and exit_raw_repl in the function itself, which in turn causes a soft reboot. In my project that would be unfavorable so I will try an edited version.

Regarding what you said about following on exec_, it calls exec_raw which in turn calls exec_raw_no_follow like you said, but it also returns follow immediately after. However, it seems that the follow function is only returning the string " ". Do I have to call follow again immediately after exec_(), even though it is called within that function already?

Code: Select all

def exec_(self, command):
        ret, ret_err = self.exec_raw(command)
        if ret_err:
            raise PyboardError('exception', ret, ret_err)
        return ret
        
def exec_raw(self, command, timeout=10, data_consumer=None):
        self.exec_raw_no_follow(command);
        return self.follow(timeout, data_consumer)

markusc90
Posts: 4
Joined: Tue Jun 23, 2015 9:23 pm

Re: Raw REPL not receiving output

Post by markusc90 » Wed Aug 17, 2016 6:12 pm

I've got it working, somewhat.

When sending the command over exec_(), to get the output, I have to print the result. For example, a command would look like this:

Code: Select all

exec_("print(getInt())"
It will then return the value in string form. To get the literal python evaluation of it, I can cast it to whatever the original datatype was. However, in the case of a list, you can use the following:

Code: Select all

import ast
output = exec_("print(getList())")
output = ast.literal_eval(output)
Unfortunately, my original datatype was a bytearray and the above doesn't work for that, so I had to cast my bytearray to a list on the micropython side to receive the data.

I still feel there should be a better way to receive the literal python interpretation of the code. Also, needing to print the output of every function doesn't seem like the way it was designed to work. For now this works for my project, but please let me know if there is a better way to do this.

Thanks,
Markus

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

Re: Raw REPL not receiving output

Post by dhylands » Wed Aug 17, 2016 6:31 pm

Well, you have to do something with it.

You can print it as ASCII (which is probably the simplest). Instead of just using print you can use repr which will try to print a parsable representation of the object.

I've got some code written someplace which send binary packets back and forth which have JSON objects in them.

You can do something else.

It really depends on what you're trying to accomplish. But there isn't anything that happens "automagically".

Post Reply