USB Serial Communication
In this section, we'll explore how to establish communication between the Pico 2 W and a computer. We'll demonstrate how to send strings from the device to the computer and receive input from the computer to control the Pico.
CDC ACM Overview
The Communication Device Class (CDC) is a standard USB device class defined by the USB Implementers Forum. The Abstract Control Model (ACM) in CDC allows a device to act like a traditional serial port (like old COM ports). When you flash USB serial code, the Pico appears as /dev/ttyACM0 on Linux.
Required Crates
[dependencies]
usb-device = "0.3.2"
usbd-serial = "0.2.2"These crates provide a USB stack for embedded devices and implement the USB CDC-ACM serial port class respectively.
Basic USB Serial Setup
use usb_device::{class_prelude::*, prelude::*};
use usbd_serial::SerialPort;
// Set up USB driver
let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new(
pac.USB,
pac.USB_DPRAM,
clocks.usb_clock,
true,
&mut pac.RESETS,
));
// Create serial port
let mut serial = SerialPort::new(&usb_bus);
// Create USB device
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
.strings(&[StringDescriptors::default()
.manufacturer("implRust")
.product("Pico 2 W")
.serial_number("TEST")])
.unwrap()
.device_class(2) // CDC class
.build();Sending Data to PC
if !said_hello && timer.get_counter().ticks() >= 2_000_000 {
said_hello = true;
let _ = serial.write(b"Hello, Rust!\r\n");
}Receiving Data from PC
if usb_dev.poll(&mut [&mut serial]) {
let mut buf = [0u8; 64];
if let Ok(count) = serial.read(&mut buf) {
for &byte in &buf[..count] {
// Process received byte
if byte == b'r' {
led.set_high().unwrap();
} else {
led.set_low().unwrap();
}
}
}
}Pico 2 W Considerations
LED Control on Pico 2 W
The onboard LED on Pico 2 W is controlled by the wireless chip (CYW43), not directly via GPIO25. For simple LED control examples with USB serial, use an external LED on a free GPIO pin, or use the cyw43 driver for onboard LED.
Using on Linux
Connect to the Pico using tio or minicom:
# Install tio
sudo apt install tio
# Connect to Pico
tio /dev/ttyACM0Then flash your code in another terminal with cargo run. You'll see output from the Pico in the tio terminal, and you can type to send data to the Pico.