| Crates.io | knx-pico |
| lib.rs | knx-pico |
| version | 0.3.0 |
| created_at | 2025-10-23 13:49:00.565487+00 |
| updated_at | 2025-11-08 17:52:27.527943+00 |
| description | KNXnet/IP protocol implementation for embedded systems |
| homepage | https://github.com/cc90202/knx-pico |
| repository | https://github.com/cc90202/knx-pico |
| max_upload_size | |
| id | 1897146 |
| size | 840,922 |
A no_std KNXnet/IP protocol implementation for embedded systems, designed for the Embassy async runtime.
no_std compatible - Runs on bare metal embedded systemsAdd to your Cargo.toml:
[dependencies]
knx-pico = "0.1"
use knx_pico::{GroupAddress, protocol::cemi::CemiFrame, dpt::{Dpt1, DptEncode}};
// Create a group address
let light = GroupAddress::new(1, 2, 3)?;
// Encode a boolean value (DPT 1 - Switch)
let value = Dpt1::new(true);
let encoded = value.encode();
// Create a write request frame
let frame = CemiFrame::write_request(light.into(), &encoded)?;
// 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 macrosembassy-espFor physical KNX testing:
For testing without hardware: Use the included Python KNX simulator (see Testing).
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 |
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
The library provides macros to simplify common operations:
use knx_pico::{ga, knx_write, knx_read, KnxValue};
// Create group addresses with readable notation
let light = ga!(1/2/3);
let temp_sensor = ga!(1/2/10);
// Write values with inline address notation
knx_write!(client, 1/2/3, KnxValue::Bool(true)).await?;
knx_write!(client, 1/2/10, KnxValue::Temperature(21.5)).await?;
// Read values
knx_read!(client, 1/2/10).await?;
// Register multiple DPT types at once
register_dpts! {
client,
1/2/3 => Bool,
1/2/5 => Percent,
1/2/10 => Temperature,
}?;
# Configure WiFi in src/configuration.rs
# Build and flash in one command
cargo flash-example-usb
# Monitor logs via USB serial
screen /dev/tty.usbmodem* 115200
# Build with defmt-rtt
cargo build --release --example pico_knx_async \
--target thumbv8m.main-none-eabihf \
--features embassy-rp
# Flash with probe-rs
probe-rs run --chip RP2350 \
target/thumbv8m.main-none-eabihf/release/examples/pico_knx_async
See .cargo/config.toml for all commands:
# Examples with USB logger
cargo flash-example-usb # Flash pico_knx_async
cargo flash-sniffer-usb-release # Flash knx_sniffer
cargo flash-main-app-usb-release # Flash knx_main_application
# Library checks
cargo check-rp2040 # Check for RP2040 target (defmt)
cargo check-rp2040-usb # Check for RP2040 target (USB logger)
cargo test-host-release # Run host tests (optimized)
# Full verification
./check-all.sh # Run all checks
Use the included Python KNX simulator for development and testing:
# Start simulator
python3 knx_simulator.py
# Run integration tests
python3 test_runner.py
# Or use Make
make test # All tests
make test-unit # Unit tests only
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:
cargo flash-example-usb
Monitor logs:
screen /dev/tty.usbmodem* 115200
See TESTING.md for detailed testing guide.
The library automatically discovers KNX gateways using multicast SEARCH_REQUEST:
use knx_pico::knx_discovery;
use embassy_time::Duration;
// Discover gateway (3 second timeout)
let gateway = knx_discovery::discover_gateway(&stack, Duration::from_secs(3))
.await
.expect("No KNX gateway found");
println!("Found gateway at {}:{}", gateway.ip, gateway.port);
No manual IP configuration needed! See KNX_DISCOVERY.md for details.
| 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.
✅ Production Ready
All core features implemented and tested:
Contributions are welcome! Please:
./check-all.sh to verify all checks passOptimized for embedded systems:
#[inline]// SAFETY: comments)Benchmarked on Raspberry Pi Pico 2 W (RP2350, 150 MHz).
rustup updaterustup target add thumbv8m.main-none-eabihfpicotool is installedprobe-rs is installedSee TESTING.md for detailed troubleshooting guide.
Licensed under either of:
at your option.
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.