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.
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