beedaddy
Posts: 14
Joined: Fri Mar 04, 2016 11:13 am

[Solved] Send/receive bytes via USB

Thu Feb 15, 2024 3:43 pm

I would like to communicate via USB serial connection with. The idea is, that a desktop program sends command bytes to the Pico, which reacts and replies with some feedback. I'm new to USB programming but I think the buzzword is CDC. I had a look at TinyUSB examples, but they are somewhat overwhelming. Perhaps someone knows some example code for simply send/receive some bytes over USB? A link to a howto or similar would be great.
Last edited by beedaddy on Wed Feb 28, 2024 5:58 pm, edited 1 time in total.

danjperron
Posts: 4743
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Send/receive bytes via USB

Thu Feb 15, 2024 3:50 pm

It is quite simple.

On the pico just send the data via the USB port . just use printf and set the stdout to the usb.

On the computer it is just a serial usb port. then just read the line.


Just check my high sample ADC transfer via USB with the pico.
https://github.com/danjperron/picoADC_UDP

In the picoADC_USB I transfer data in base64 but nothing prevent you to send in pure ASCII.
On the Pi I use a small python script to read back the data.

B.T.W. it could be bidirectional. you send command and receive data.

beedaddy
Posts: 14
Joined: Fri Mar 04, 2016 11:13 am

Re: Send/receive bytes via USB

Fri Feb 16, 2024 10:51 am

Thanks a lot for that hint!

But… doesn't that interfere with writing some debug lines or so with printf?

I wonder if this is the usual/recommended way. In any case, I am still very interested in a TinyUSB version.

arg001
Posts: 640
Joined: Tue Jan 23, 2018 10:06 am

Re: Send/receive bytes via USB

Fri Feb 16, 2024 12:33 pm

This is one of those things that, once you've got it sorted out, you look at and think it's actually quite straightforward, but getting there is hard work.

First thing to say is that if you are currently using printf() for debuging over USB (pico_enable_stdio_usb(my_executable 1) in yor CMakelists.txt) then you are already using TinyUSB and a CDC instance - the SDK has set this up for you behind the scenes.

So if you want to have a separate CDC instance to give you a clean byte stream interface for your application data, you need a TinyUSB configuration with two CDC interfaces in it - one for the stdio (printf()) output, and one for your own use.

You might then think that if you add TinyUSB explicitly to your project, that will clash with the TinyUSB that the SDK has already included; fortunately that doesn't happen, as the SDK has been designed to detect this: if you build a TinyUSB configuration with two CDCs, the SDK will take the first one for printf() and leave the second one alone. However, you do have to take responsibility for the TinyUSB initialisation and polling that the SDK was previously doing for you.

In your CMakelists.txt you need tusb_device in your target_link_libraries() - alongside all the SDK components like hardware_pio or hardware_uart that you probably already have. You also need this so that it can find the tusb_config.h that you are about to create:

Code: Select all

# Make sure TinyUSB can find tusb_config.h
target_include_directories(my_executable PUBLIC
        ${CMAKE_CURRENT_LIST_DIR})
You then need to create your tusb_config.h and usb_descriptors.c, which you can probably crib from this example:
https://github.com/hathach/tinyusb/tree ... _ports/src
The usb_descriptors.c needs to be added to the CMakelists.txt along with your own C files.

Your application must calltud_init(BOARD_TUD_RHPORT); during initialisation, then in the foreground main loop, call tud_task() frequently (previously the SDK was taking care of this for you via a timer).

That much on its own should get you back to having printf() working.

To actually make use of your CDCs, you then need code in your main loop similar to the cdc_task() in the example program - but ignore interface zero as the SDK is taking care of that, where the example code has for (itf = 0; itf < CFG_TUD_CDC; itf++) you just need to deal with the case of itf=1.

beedaddy
Posts: 14
Joined: Fri Mar 04, 2016 11:13 am

Re: Send/receive bytes via USB

Sat Feb 17, 2024 1:02 pm

Thanks @arg001, I will give it try.

danjperron
Posts: 4743
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Send/receive bytes via USB

Sat Feb 17, 2024 1:16 pm

You could also use the serial port for debugging

beedaddy
Posts: 14
Joined: Fri Mar 04, 2016 11:13 am

Re: Send/receive bytes via USB

Wed Feb 28, 2024 5:58 pm

@arg001 In the meantime, I was able to set tinyusb up according to your tips. Works lika a charm. Thanks!

Return to “SDK”