Skip to content

RPi Pico 2 Example Code

Note: These are legacy C reference examples. For new development, use the Rust SDK examples with the Rust SDK instead.

C example code for using the Xylolabs API on the RPi Pico 2 (RP2350).

File Structure

File Description
xmbp.h XMBP protocol encoding header (reusable)
continuous_stream.c Continuous sensor streaming example
periodic_sampling.c Periodic sampling example (10s every 5 minutes)
audio_upload.c Audio streaming upload example (I2S + chunked HTTP)

Design Principles

Zero-Copy

All examples construct XMBP packets directly in static buffers. There is no intermediate buffer copying.

Sensor -> Static buffer (XMBP encoding) -> HTTP/WebSocket transmission
             ^ No intermediate copies

Static Memory

No malloc/free is used. All buffer sizes are determined at compile time. The RPi Pico 2 has approximately 520KB of SRAM, and the example code uses 16-50KB of memory.

LTE-M1 Optimization

  • Batch size tuned to LTE-M1 bandwidth (~47KB/s)
  • Exponential backoff retransmission
  • PSM (Power Save Mode) utilization
  • Local storage fallback on connection failure

Legacy C Build

These examples use the Pico SDK. LTE-M1 modem control code must be implemented according to the modem module in use.

# Add to CMakeLists.txt
add_executable(continuous_stream continuous_stream.c)
target_link_libraries(continuous_stream pico_stdlib hardware_adc)

add_executable(periodic_sampling periodic_sampling.c)
target_link_libraries(periodic_sampling pico_stdlib hardware_adc)

add_executable(audio_upload audio_upload.c)
target_link_libraries(audio_upload pico_stdlib hardware_i2s hardware_dma)

LTE-M1 Modem Reference

Network functions such as http_post_binary() and ws_send() are provided as stubs in the examples. The actual implementation varies depending on the LTE-M1 modem in use.

Common LTE-M1 Modems

Modem Interface AT Command Set
Quectel BG770A/BG95 UART AT 3GPP + Quectel extensions
u-blox SARA-R4/R5 UART AT 3GPP + u-blox extensions
Nordic nRF9160 SPI/UART AT or native SDK
Sierra Wireless HL7812 UART AT 3GPP + Sierra extensions

API Key Validation (Ping)

Before starting a session, validate the API key with a GET request to /api/v1/ping:

// Quick API key check -- returns {"pong":true,...} on success, 401 on failure
at_send("AT+QHTTPCFG=\"contextid\",1");
at_send("AT+QHTTPCFG=\"custom_header\",\"X-Api-Key: xk_a1b2...\"");
at_send("AT+QHTTPURL=46,80");
at_send_raw("https://api.xylolabs.com/api/v1/ping", 46);
at_send("AT+QHTTPGET=60");  // 60s timeout
// Check response: 200 = key valid, 401 = key invalid

AT Command Based HTTP POST Example (Quectel BG770A)

// 1. HTTP configuration
at_send("AT+QHTTPCFG=\"contextid\",1");
at_send("AT+QHTTPCFG=\"custom_header\",\"X-Api-Key: xk_a1b2...\"");
at_send("AT+QHTTPCFG=\"custom_header\",\"Content-Type: application/octet-stream\"");

// 2. Set URL
char cmd[256];
snprintf(cmd, sizeof(cmd), "AT+QHTTPURL=%d,80", strlen(url));
at_send(cmd);
at_send_raw(url, strlen(url));

// 3. POST transmission (send xmbp_buf directly -- zero-copy)
snprintf(cmd, sizeof(cmd), "AT+QHTTPPOST=%d,80,80", packet_len);
at_send(cmd);
at_send_raw(xmbp_buf, packet_len);  // Direct transmission without buffer copy

API Documentation Reference

  • API Reference -- XMBP protocol, ingest sessions, audio uploads, API key management, device management