knx-pico
A no_std KNXnet/IP protocol implementation for embedded systems, designed for the Embassy async runtime.
Features
- 🚀
no_stdcompatible - Runs on bare metal embedded systems - ⚡ Zero-copy parsing - Efficient memory usage for resource-constrained devices
- 🔄 Async/await - Full Embassy async runtime integration
- 🎯 Type-safe addressing - Strong types for Individual and Group addresses
- 🔌 KNXnet/IP tunneling - Reliable point-to-point communication
- 📊 Datapoint Types (DPT) - Support for DPT 1, 3, 5, 7, 9, 13
- 🔍 Gateway auto-discovery - Automatic KNX gateway detection via multicast
- 🛡️ Production-ready - Thoroughly tested with hardware and simulator
Quick Start
Installation
Add to your Cargo.toml:
[]
= "0.1"
Basic Example
use ;
// Create a group address
let light = new?;
// Encode a boolean value (DPT 1 - Switch)
let value = new;
let encoded = value.encode;
// Create a write request frame
let frame = write_request?;
// The frame can now be sent over KNXnet/IP tunnel
// (requires Embassy runtime and network stack - see examples on GitHub)
For complete examples with Embassy runtime and Raspberry Pi Pico 2 W, see the examples directory on GitHub:
pico_knx_async.rs- Complete working example for Pico 2 Wknx_sniffer.rs- Interactive testing tool with convenience macros
Hardware Support
Tested Platforms
- ✅ Raspberry Pi Pico 2 W (RP2350) - Primary development platform
- 🔜 ESP32-C3/C6 - Planned support via
embassy-esp
Required Hardware
For physical KNX testing:
- Raspberry Pi Pico 2 W (or compatible RP2350 board)
- KNX/IP Gateway (e.g., Gira X1, MDT SCN-IP000.03)
- WiFi network
For testing without hardware: Use the included Python KNX simulator (see Testing).
Architecture
Layer Overview
KNX communication uses three nested protocol layers:
┌─────────────────────────────────────────────────┐
│ KNXnet/IP FRAME (UDP transport) │
│ ┌───────────────────────────────────────────┐ │
│ │ CEMI (KNX command) │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ DPT (encoded value) │ │ │
│ │ │ e.g., true → [0x01] │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
| Layer | Purpose | Example |
|---|---|---|
| DPT | Encode values | 21.5°C → \[0x0C, 0x1A\] |
| CEMI | KNX commands | "Write to 1/2/3: [0x01]" |
| KNXnet/IP | IP transport | UDP to 192.168.1.10:3671 |
Module Structure
knx-pico/
├── addressing/ # KNX addressing (Individual & Group)
├── protocol/ # KNXnet/IP protocol implementation
│ ├── frame.rs # Layer 1: KNXnet/IP frames
│ ├── cemi.rs # Layer 2: CEMI messages
│ ├── services.rs # Tunneling service builders
│ ├── tunnel.rs # Typestate tunneling client
│ └── async_tunnel.rs # Async wrapper for Embassy
├── dpt/ # Layer 3: Datapoint Types (DPT)
│ ├── dpt1.rs # Boolean (switches, buttons)
│ ├── dpt3.rs # 3-bit control (dimming, blinds)
│ ├── dpt5.rs # 8-bit unsigned (percentage, angle)
│ ├── dpt7.rs # 16-bit unsigned (counter, brightness)
│ ├── dpt9.rs # 2-byte float (temperature, humidity)
│ └── dpt13.rs # 32-bit signed (energy, flow)
├── knx_discovery.rs # Gateway auto-discovery
├── knx_client.rs # High-level client API
├── error.rs # Comprehensive error types
└── lib.rs # Public API
Convenience Macros
The library provides macros to simplify common operations:
use ;
// Create group addresses with readable notation
let light = ga!;
let temp_sensor = ga!;
// Write values with inline address notation
knx_write!.await?;
knx_write!.await?;
// Read values
knx_read!.await?;
// Register multiple DPT types at once
register_dpts! ?;
Building and Flashing
For Raspberry Pi Pico 2 W
Option 1: USB Logger (Recommended - No probe needed)
# Configure WiFi in src/configuration.rs
# Build and flash in one command
# Monitor logs via USB serial
Option 2: defmt Logger (Requires debug probe)
# Build with defmt-rtt
# Flash with probe-rs
Available Commands
See .cargo/config.toml for all commands:
# Examples
# Library checks
# Full verification
Testing
Without Physical Hardware
Use the included Python KNX simulator for development and testing:
# Start simulator
# Run integration tests
# Or use Make
With Physical Hardware
-
Configure WiFi credentials in
src/configuration.rs:pub const CONFIG: &str = r#" WIFI_NETWORK=Your_WiFi_SSID WIFI_PASSWORD=Your_WiFi_Password "#; -
Flash to hardware:
-
Monitor logs:
See TESTING.md for detailed testing guide.
Gateway Auto-Discovery
The library automatically discovers KNX gateways using multicast SEARCH_REQUEST:
use knx_discovery;
use Duration;
// Discover gateway (3 second timeout)
let gateway = discover_gateway
.await
.expect;
println!;
No manual IP configuration needed! See KNX_DISCOVERY.md for details.
Supported Datapoint Types (DPT)
| DPT | Type | Description | Example |
|---|---|---|---|
| 1.xxx | Boolean | Switches, buttons, binary sensors | true/false |
| 3.007 | 3-bit | Dimming control (increase/decrease) | +4 steps |
| 3.008 | 3-bit | Blinds control (up/down) | down 2 steps |
| 5.001 | 8-bit | Percentage (0-100%) | 75% |
| 5.010 | 8-bit | Unsigned value (0-255) | 192 |
| 7.001 | 16-bit | Counter, pulses (0-65535) | 5000 lux |
| 9.001 | 2-byte float | Temperature (°C) | 21.5°C |
| 9.004 | 2-byte float | Illuminance (lux) | 5000 lux |
| 9.007 | 2-byte float | Humidity (%) | 65% |
| 13.xxx | 32-bit | Energy, flow rate, long counters | 500000 Wh |
See src/dpt/ for implementation details.
Documentation
- TESTING.md - Testing guide with simulator setup
- KNX_DISCOVERY.md - Gateway discovery details
- PRE_PUBLISH_GUIDE.md - Pre-publish checklist
- examples/README.md - Example documentation
- API Documentation - Full API reference
Project Status
✅ Production Ready
All core features implemented and tested:
- ✅ KNXnet/IP protocol (Frame, CEMI, Services)
- ✅ Datapoint Types (DPT 1, 3, 5, 7, 9, 13)
- ✅ Tunneling client with typestate pattern
- ✅ Embassy + RP2040 integration (Pico 2 W)
- ✅ Gateway auto-discovery via multicast
- ✅ High-level client API with macros
- ✅ Comprehensive testing (unit, integration, hardware)
- ✅ CI/CD automation (GitHub Actions)
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Run
./check-all.shto verify all checks pass - Submit a pull request
Performance
Optimized for embedded systems:
- Zero-copy parsing - Minimal memory allocations
- Inline hot paths - Critical functions marked
#[inline] - Unsafe optimizations - Bounds checks eliminated where safe (documented with
// SAFETY:comments) - ~10% performance gain on parsing hot paths
- Fire-and-forget pattern - Optimized command sending for stability
Benchmarked on Raspberry Pi Pico 2 W (RP2350, 150 MHz).
Troubleshooting
Gateway not found during discovery
- Verify gateway is powered on and connected to network
- Check that multicast is enabled on your WiFi network
- Increase discovery timeout to 5 seconds
- Ensure your WiFi network allows multicast traffic (224.0.23.12)
Connection timeouts
- Verify gateway IP and port (usually 3671)
- Check firewall settings (UDP port 3671 must be open)
- Ensure only one client connects to gateway at a time
Compilation errors
- Update Rust toolchain:
rustup update - Install RP2040 target:
rustup target add thumbv8m.main-none-eabihf - For USB logger: ensure
picotoolis installed - For defmt: ensure
probe-rsis installed
See TESTING.md for detailed troubleshooting guide.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.