-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add int32_publisher_custom_transport_usbcdc example
This example demonstrates how to enable ROS2 communication via USB CDC and log output on the ESP32-S2. Reviewed-by: Leandro Mendes do Santos <[email protected]> Signed-off-by: Samuel Henrique Guimarães Alencar <[email protected]>
- Loading branch information
1 parent
37d75e8
commit 294bca3
Showing
18 changed files
with
565 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
build | ||
sdkconfig | ||
sdkconfig.old | ||
managed_components | ||
.vscode |
7 changes: 7 additions & 0 deletions
7
examples/int32_publisher_custom_transport_usbcdc/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
cmake_minimum_required(VERSION 3.5) | ||
|
||
set (EXTRA_COMPONENT_DIRS "./../../.") | ||
|
||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
project(int32_publisher) | ||
|
138 changes: 138 additions & 0 deletions
138
examples/int32_publisher_custom_transport_usbcdc/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
|
||
# USB-CDC Custom Transport Example | ||
|
||
| Supported Targets | ESP32-S2 | ESP32-S3 | | ||
|-------------------|----------|----------| | ||
|
||
This example demonstrates how to set up the ESP32-S2/S3 to function as a USB Serial Device (CDC-ACM) and communicate with micro-ROS agent using USB-CDC custom transport. | ||
|
||
The [TinyUSB component](https://components.espressif.com/components/espressif/esp_tinyusb) is used as the USB stack. | ||
|
||
This example is based on the [int32_publisher_custom_transport](https://github.com/micro-ROS/micro_ros_espidf_component/tree/jazzy/examples/int32_publisher_custom_transport), the [TinyUSB Serial Device Example](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb/device/tusb_serial_device), and the [TinyUSB Console Example](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb/device/tusb_console) for log output. | ||
|
||
## How to use example | ||
|
||
This example is configured to use the two interfaces of USB-CDC. One interface is used for the micro-ROS communication, and the other interface is used for the log output. | ||
|
||
### Hardware Required | ||
|
||
This example can be run on any development board that has a USB-CDC interface. | ||
|
||
### Configure the project | ||
|
||
Set the target device in the project configuration: | ||
|
||
```bash | ||
idf.py set-target esp32s2 # or esp32s3 | ||
``` | ||
|
||
If you want to use only the micro-ROS communication interface, you need to turn off log output in menuconfig. Run `idf.py menuconfig` and navigate to `Component config → Log output → Default log verbosity` and set it to `No output`. You should also set `Component config → TinyUSB Stack → Communication Device Class (CDC) → CDC Channel Count` to 1. | ||
|
||
### Build and Flash | ||
|
||
> [!NOTE] | ||
> The ESP32-S2/S3 chip needs to be in bootloader mode before it can be detected as a DFU device and flash. This can be achieved by pulling GPIO0 down (e.g., pressing the BOOT button), pulling RESET down for a moment, and releasing GPIO0. | ||
#### Build the project | ||
|
||
Build DFU image: | ||
|
||
```bash | ||
idf.py dfu | ||
``` | ||
|
||
#### Flash the project | ||
|
||
Put the ESP32-S2/S3 into bootloader mode and run the following command: | ||
|
||
```bash | ||
idf.py dfu-flash | ||
``` | ||
|
||
### Run micro-ROS Agent | ||
|
||
```bash | ||
export ROS_DOMAIN_ID=100 # Set the ROS2 domain ID | ||
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0 | ||
``` | ||
|
||
Output expected: | ||
|
||
```bash | ||
[1724443525.673894] info | TermiosAgentLinux.cpp | init | running... | fd: 3 | ||
[1724443525.674071] info | Root.cpp | set_verbose_level | logger setup | verbose_level: 4 | ||
[1724443529.936542] info | TermiosAgentLinux.cpp | init | running... | fd: 3 | ||
[1724443531.062646] info | Root.cpp | create_client | create | client_key: 0x3E801A05, session_id: 0x81 | ||
[1724443531.062805] info | SessionManager.hpp | establish_session | session established | client_key: 0x3E801A05, address: 0 | ||
[1724443531.107532] info | ProxyClient.cpp | create_participant | participant created | client_key: 0x3E801A05, participant_id: 0x000(1) | ||
[1724443531.137064] info | ProxyClient.cpp | create_topic | topic created | client_key: 0x3E801A05, topic_id: 0x000(2), participant_id: 0x000(1) | ||
[1724443531.167351] info | ProxyClient.cpp | create_publisher | publisher created | client_key: 0x3E801A05, publisher_id: 0x000(3), participant_id: 0x000(1) | ||
[1724443531.237811] info | ProxyClient.cpp | create_datawriter | datawriter created | client_key: 0x3E801A05, datawriter_id: 0x000(5), publisher_id: 0x000(3) | ||
``` | ||
|
||
After connecting the ESP32-S2/S3 and the micro-ROS agent, you can list the topics: | ||
|
||
```bash | ||
export ROS_DOMAIN_ID=100 # Set the ROS2 domain ID | ||
ros2 topic list | ||
``` | ||
|
||
Output expected: | ||
|
||
```bash | ||
/esp32s2/int32_publisher_usbcdc | ||
/parameter_events | ||
/rosout | ||
``` | ||
|
||
And see if the `esp32s2/int32_publisher_usbcdc` topic is available. You can echo the topic to see the messages: | ||
|
||
```bash | ||
export ROS_DOMAIN_ID=100 # Set the ROS2 domain ID | ||
ros2 topic echo esp32s2/int32_publisher_usbcdc | ||
``` | ||
|
||
Output expected: | ||
|
||
```bash | ||
data: 1 | ||
--- | ||
data: 2 | ||
--- | ||
data: 3 | ||
--- | ||
data: 4 | ||
--- | ||
data: 5 | ||
. | ||
. | ||
. | ||
``` | ||
|
||
To see the log output, you can use the following command: | ||
|
||
```bash | ||
minicom -D /dev/ttyACM1 -b 115200 | ||
``` | ||
|
||
Output expected: | ||
|
||
```bash | ||
Welcome to minicom 2.8 | ||
|
||
OPTIONS: I18n | ||
Port /dev/ttyACM1 | ||
Press CTRL-A Z for help on special keys | ||
|
||
I (2688) MAIN: micro-ROS task created | ||
I (2688) main_task: Returned from app_main() | ||
I (3708) TIMER_CALLBACK: Message published: 0 | ||
I (4708) TIMER_CALLBACK: Message published: 1 | ||
I (5708) TIMER_CALLBACK: Message published: 2 | ||
I (6708) TIMER_CALLBACK: Message published: 3 | ||
I (7708) TIMER_CALLBACK: Message published: 4 | ||
I (8708) TIMER_CALLBACK: Message published: 5 | ||
. | ||
. | ||
. | ||
``` |
9 changes: 9 additions & 0 deletions
9
examples/int32_publisher_custom_transport_usbcdc/app-colcon.meta
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"names": { | ||
"rmw_microxrcedds": { | ||
"cmake-args": [ | ||
"-DRMW_UXRCE_TRANSPORT=custom" | ||
] | ||
} | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
.../int32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_logging/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
idf_component_register(SRCS "esp32s2_usbcdc_logging.c" INCLUDE_DIRS ".") |
46 changes: 46 additions & 0 deletions
46
...lisher_custom_transport_usbcdc/components/esp32s2_usbcdc_logging/esp32s2_usbcdc_logging.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#include "esp32s2_usbcdc_logging.h" | ||
|
||
// Initialize USB-CDC logging | ||
esp_err_t esp32s2_usbcdc_logging_init(void) | ||
{ | ||
const tinyusb_config_t tinyusb_config = { | ||
.descriptor = NULL, | ||
.string_descriptor = NULL, | ||
.external_phy = false, | ||
.configuration_descriptor = NULL, | ||
}; | ||
|
||
esp_err_t ret = tinyusb_driver_install(&tinyusb_config); | ||
|
||
if (ret == ESP_ERR_INVALID_ARG || ret == ESP_FAIL) { | ||
return ret; | ||
} | ||
|
||
tinyusb_config_cdcacm_t acm_config = { | ||
.usb_dev = TINYUSB_USBDEV_0, | ||
.cdc_port = TINYUSB_CDC_ACM_1, | ||
.rx_unread_buf_sz = CONFIG_TINYUSB_CDC_RX_BUFSIZE, | ||
.callback_rx = NULL, | ||
.callback_rx_wanted_char = NULL, | ||
.callback_line_state_changed = NULL, | ||
.callback_line_coding_changed = NULL, | ||
}; | ||
|
||
ret = tusb_cdc_acm_init(&acm_config); | ||
|
||
if (ret != ESP_OK) { | ||
return ret; | ||
} | ||
|
||
ret = esp_tusb_init_console(TINYUSB_CDC_ACM_1); | ||
|
||
return ret; | ||
} | ||
|
||
// Deinitialize USB-CDC logging | ||
esp_err_t esp32s2_usbcdc_logging_deinit(void) | ||
{ | ||
esp_err_t ret = esp_tusb_deinit_console(TINYUSB_CDC_ACM_1); | ||
|
||
return ret; | ||
} |
32 changes: 32 additions & 0 deletions
32
...lisher_custom_transport_usbcdc/components/esp32s2_usbcdc_logging/esp32s2_usbcdc_logging.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#ifndef ESP32S2_USBCDC_LOGGING_H | ||
#define ESP32S2_USBCDC_LOGGING_H | ||
|
||
#include "esp_err.h" | ||
#include "tinyusb.h" | ||
#include "tusb_cdc_acm.h" | ||
#include "tusb_console.h" | ||
#include "sdkconfig.h" | ||
|
||
#if (CONFIG_TINYUSB_CDC_COUNT < 2) | ||
#warning "Define CONFIG_TINYUSB_CDC_COUNT to 2 in menuconfig if you want log over USBCDC. Otherwise, disable log output in menuconfig." | ||
#endif | ||
|
||
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) | ||
|
||
#ifdef __cplusplus | ||
extern "C" | ||
{ | ||
#endif | ||
|
||
esp_err_t esp32s2_usbcdc_logging_init(void); | ||
esp_err_t esp32s2_usbcdc_logging_deinit(void); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#else | ||
#error "Logging over USB-CDC is only supported on ESP32-S2 or ESP32-S3 targets" | ||
#endif | ||
|
||
#endif // ESP32S2_USBCDC_LOGGING_H |
6 changes: 6 additions & 0 deletions
6
...t32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_logging/idf_component.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
## IDF Component Manager Manifest File | ||
dependencies: | ||
espressif/esp_tinyusb: "^1.4.4" | ||
## Required IDF version | ||
idf: | ||
version: ">=5.0" |
4 changes: 4 additions & 0 deletions
4
...nt32_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_transport/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
idf_component_register(SRCS "esp32s2_usbcdc_transport.c" | ||
INCLUDE_DIRS "." | ||
REQUIRES micro_ros_espidf_component # include <uxr/client/transport.h> | ||
) |
57 changes: 57 additions & 0 deletions
57
...er_custom_transport_usbcdc/components/esp32s2_usbcdc_transport/esp32s2_usbcdc_transport.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#include "esp32s2_usbcdc_transport.h" | ||
|
||
// Open USB-CDC | ||
bool esp32s2_usbcdc_open(struct uxrCustomTransport* transport) { | ||
const tinyusb_config_t tinyusb_config = { | ||
.device_descriptor = NULL, | ||
.string_descriptor = NULL, | ||
.external_phy = false, | ||
.configuration_descriptor = NULL, | ||
}; | ||
|
||
esp_err_t ret = tinyusb_driver_install(&tinyusb_config); | ||
|
||
if (ret == ESP_ERR_INVALID_ARG || ret == ESP_FAIL) { | ||
return ret; | ||
} | ||
|
||
tinyusb_cdcacm_itf_t* cdc_port = (tinyusb_cdcacm_itf_t*)transport->args; | ||
|
||
tinyusb_config_cdcacm_t acm_cfg = { | ||
.usb_dev = TINYUSB_USBDEV_0, | ||
.cdc_port = *cdc_port, | ||
.rx_unread_buf_sz = CONFIG_TINYUSB_CDC_RX_BUFSIZE, | ||
.callback_rx = NULL, | ||
.callback_rx_wanted_char = NULL, | ||
.callback_line_state_changed = NULL, | ||
.callback_line_coding_changed = NULL | ||
}; | ||
|
||
if (tusb_cdc_acm_init(&acm_cfg) != ESP_OK) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
// Close USB-CDC | ||
bool esp32s2_usbcdc_close(struct uxrCustomTransport* transport) { | ||
tinyusb_cdcacm_itf_t* cdc_port = (tinyusb_cdcacm_itf_t*)transport->args; | ||
return (tusb_cdc_acm_deinit(*cdc_port) == ESP_OK) ? true : false; | ||
} | ||
|
||
// Write to USB-CDC | ||
size_t esp32s2_usbcdc_write(struct uxrCustomTransport* transport, const uint8_t* buf, size_t len, uint8_t* err) { | ||
tinyusb_cdcacm_itf_t* cdc_port = (tinyusb_cdcacm_itf_t*)transport->args; | ||
size_t tx_size = tinyusb_cdcacm_write_queue(*cdc_port, buf, len); | ||
tinyusb_cdcacm_write_flush(*cdc_port, 0); | ||
return tx_size; | ||
} | ||
|
||
// Read from USB-CDC | ||
size_t esp32s2_usbcdc_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err) { | ||
tinyusb_cdcacm_itf_t* cdc_port = (tinyusb_cdcacm_itf_t*)transport->args; | ||
size_t rx_size = 0; | ||
esp_err_t ret = tinyusb_cdcacm_read(*cdc_port, buf, len, &rx_size); | ||
return (ret == ESP_OK) ? rx_size : 0; | ||
} |
29 changes: 29 additions & 0 deletions
29
...er_custom_transport_usbcdc/components/esp32s2_usbcdc_transport/esp32s2_usbcdc_transport.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#ifndef ESP32S2_USBCDC_TRANSPORT_H | ||
#define ESP32S2_USBCDC_TRANSPORT_H | ||
|
||
#include <uxr/client/transport.h> | ||
|
||
#include "tinyusb.h" | ||
#include "tusb_cdc_acm.h" | ||
|
||
#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) | ||
|
||
#ifdef __cplusplus | ||
extern "C" | ||
{ | ||
#endif | ||
|
||
bool esp32s2_usbcdc_open(struct uxrCustomTransport* transport); | ||
bool esp32s2_usbcdc_close(struct uxrCustomTransport* transport); | ||
size_t esp32s2_usbcdc_write(struct uxrCustomTransport* transport, const uint8_t* buf, size_t len, uint8_t* err); | ||
size_t esp32s2_usbcdc_read(struct uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* err); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#else | ||
#error "This transport is only supported on ESP32-S2 or ESP32-S3 targets" | ||
#endif // CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 | ||
|
||
#endif // ESP32S2_USBCDC_TRANSPORT_H |
17 changes: 17 additions & 0 deletions
17
...2_publisher_custom_transport_usbcdc/components/esp32s2_usbcdc_transport/idf_component.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
## IDF Component Manager Manifest File | ||
dependencies: | ||
espressif/esp_tinyusb: "^1.4.4" | ||
## Required IDF version | ||
idf: | ||
version: ">=5.0" | ||
# # Put list of dependencies here | ||
# # For components maintained by Espressif: | ||
# component: "~1.0.0" | ||
# # For 3rd party components: | ||
# username/component: ">=1.0.0,<2.0.0" | ||
# username2/component2: | ||
# version: "~1.0.0" | ||
# # For transient dependencies `public` flag can be set. | ||
# # `public` flag doesn't have an effect dependencies of the `main` component. | ||
# # All dependencies of `main` are public by default. | ||
# public: true |
21 changes: 21 additions & 0 deletions
21
examples/int32_publisher_custom_transport_usbcdc/dependencies.lock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
dependencies: | ||
espressif/esp_tinyusb: | ||
component_hash: f151d680d6847bfcfd5d8eb6d1c3ff926c208e6b963b2e83643a141bc70baa15 | ||
source: | ||
service_url: https://api.components.espressif.com/ | ||
type: service | ||
version: 1.4.4 | ||
espressif/tinyusb: | ||
component_hash: 214989d502fc168241a4a4f83b097d8ac44a93cd6f1787b4ac10069a8b3bebd3 | ||
source: | ||
service_url: https://api.components.espressif.com/ | ||
type: service | ||
version: 0.15.0~10 | ||
idf: | ||
component_hash: null | ||
source: | ||
type: idf | ||
version: 5.1.2 | ||
manifest_hash: 7f60fd8da9b1e2b73aafbc324107a75ce3928aa50666473c15511b764484240c | ||
target: esp32s2 | ||
version: 1.0.0 |
1 change: 1 addition & 0 deletions
1
examples/int32_publisher_custom_transport_usbcdc/main/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
idf_component_register(SRCS main.c INCLUDE_DIRS ".") |
Oops, something went wrong.