how to use usb port for user data

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
miltmobley
Posts: 30
Joined: Mon Mar 07, 2016 11:44 pm

how to use usb port for user data

Post by miltmobley » Mon Apr 04, 2016 6:56 pm

I want to forward sensor data to a pc host, and thought it would be possible to use the usb port to do so.
But there are problems:

repl apparently owns the usb port, at least if i open /dev/ttyACM0 on the host.

If i run one of the leds tutorials that loops with short delays, the repl output is not updated,
and ctrl-D doesn't work while the program is running.

Is there a simple way to prevent repl from running when I open /dev/ttyACM0 on the host?

Or is there a way to make a user program yield to repl?

Alternative solutions:

Use uart with usb to serial cable to transfer the data.

Run the card in HID mode and convert the date to "HID Sensor" format. This would also presumably
require writing some app code on the linux side.

Comments?

miltmobley
Posts: 30
Joined: Mon Mar 07, 2016 11:44 pm

Re: how to use usb port for user data

Post by miltmobley » Mon Apr 04, 2016 8:11 pm

Would something like this work?

import pyb
import select

sensor = Sensor() # I have to implement this

def push_up(usb, sensor):
usb.setinterrupt(-1)
while True:
select.select([usb, sensor], [], [])
if usb.any():
sensor.write(usb.read(256)) # pass command to sensor
if sensor.any():
usb.write(sensor.read(256)) # push data to host

push_up(pyb.USB_VCP(), sensor)

Presumably I would have to provide a program on the host to send commands and receive data.

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

Re: how to use usb port for user data

Post by dhylands » Mon Apr 04, 2016 8:33 pm

miltmobley wrote:I want to forward sensor data to a pc host, and thought it would be possible to use the usb port to do so.
But there are problems:

repl apparently owns the usb port, at least if i open /dev/ttyACM0 on the host.

If i run one of the leds tutorials that loops with short delays, the repl output is not updated,
and ctrl-D doesn't work while the program is running.
Control-D only works from the REPL. You can use Control-C to kill the currently running program (this only works from the USB REPL) and then use Control-D.
Is there a simple way to prevent repl from running when I open /dev/ttyACM0 on the host?
Whether the REPL runs or not has nothing to do with whether you open /dev/ttyACM0 on the host.

Here's an example program which you could use:

Code: Select all

#
# Example which runs forever until you press a button
#

import pyb

button = pyb.Switch()

counter = 0
last_incr = pyb.millis()

while not button():
    if pyb.elapsed_millis(last_incr) > 1000:
        print('Counter =', counter)
        counter += 1
        last_incr = pyb.millis()
    
print('Button press detected - exiting')
If you made that be your main.py then it will run and when you press the USR button it will stop running and the REPL will be entered.

You could also save it to a file (I used run_till_button.py) and from the REPL import it and it will behave the same way:

Code: Select all

>>> import run_till_button
Counter = 0
Counter = 1
Counter = 2
Counter = 3
Counter = 4
Button press detected - exiting
>>> 
The sequence of execution (in micropython) goes something like this:

Code: Select all

while True:
    exec boot.py
    exec main.py
    run the REPL
If you provide a main.py that doesn't exit, then the REPL won't run. As soon as main.py stops running, the REPL will run.

The way that I do this is to have main.py run the program I want, and then have a host side program that opens the /dev/ttyACM0 and communicates with the program running on the pyboard. If you make it so that the host initiates the communication then you can also not use main.py, and enter the REPL, run a terminal program and do your:

Code: Select all

import my_program
which starts your program running. Then you quit the terminal program and start your host program which talks to your program.

A project where I did this can be found here: https://github.com/dhylands/bioloid3
The pico_io_adapter.py is the main program

For debugging, I normally use os.dupterm to replicate the REPL on a UART. That way I can see tracebacks. I also typically run a little mening/status system on the UART so I can leave the USB to host for high-speed comms.

The pico_io_adapter sends and receives binary packets over the USB interface (called host_uart in the code), and forwards those packets out a serial port at 1 Mbit/sec (called device_uart) and sets up logging/debug menu on another UART.
Or is there a way to make a user program yield to repl?
You just need to exit your main.py to return to the REPL. You can also simulate a Control-D programmatically by doing:

Code: Select all

raise SystemExit
from within your python code.

You can also use raise KeyboardInterrupt to simulate Control-C. In my pico_io_adapter.py I look for a button press in the main loop and use that to trigger a Control-C.

miltmobley
Posts: 30
Joined: Mon Mar 07, 2016 11:44 pm

Re: how to use usb port for user data

Post by miltmobley » Tue Apr 05, 2016 2:40 am

Thanks for your help, I will try the options you suggested.

My actual goal is to have the pyboard control the sample rate of an attached sensor, possibly
filter the data and push it to subscribers. I first thought of using the usb port for testing at least,
but the eventual device would be autonomous, i.e. not connected to a pc, and be able to publish
data via bluetooth or wifi as well. So I think I do not want repl to be running during normal operations.

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

Re: how to use usb port for user data

Post by dhylands » Tue Apr 05, 2016 4:39 am

The REPL won't be running during "normal" operations. The REPL only runs when nothing else is running, regardless of whether USB is connected or not.

Post Reply