CanWeeb

English

This English section was translated with GPT-5.4. It may contain minor inaccuracies compared with the Japanese section below.

CanWeeb is a node-to-node communication system for robotics, sensors, tools, and interactive applications. It provides reliable control messaging, fast telemetry distribution, stream transfer, a built-in web API, real-time WebSocket updates, peer discovery, Wi-Fi control, and Raspberry Pi hardware integration through CmdLib.

Repository Overview

What You Can Do

Communication Model

Traffic ClassPurpose
controlReliable commands, events, and state changes with acknowledgment and persistence.
telemetryLow-overhead sensor and status updates with latest-value caching.
streamChunked transfer for larger binary payloads.

Messages can be sent to a single node, multiple nodes, or broadcast across the mesh.

Web API

CanWeeb includes a built-in HTTP and WebSocket interface for integration, debugging, and monitoring.

RouteFunction
/api/statusRead runtime state, queue counts, inbox counts, and peer status.
/api/messagesSend a new message.
/api/inboxList received control messages.
/api/inbox/:message_idRead one inbox item in detail.
/api/topicsList cached telemetry topics.
/api/topic?name=...Read one telemetry topic.
/api/streamsList completed streams.
/api/streams/:stream_idRead one completed stream.
/api/peer-policiesRead or update peer policy.
/api/wifi/statusRead Wi-Fi state.
/api/wifi/apply-modeApply Wi-Fi mode.
/api/wifi/connectConnect to Wi-Fi.
/api/wifi/disconnectDisconnect Wi-Fi.
/api/wifi/hotspot/startStart hotspot mode.
/api/wifi-direct/runRun a direct wpa_cli command.
/ws/inboxReceive live inbox updates.
/ws/topicsReceive live telemetry updates.
/ws/streamsReceive live completed-stream updates.

Message Example

{
  "target": "node:peer-a",
  "traffic_class": "control",
  "topic": "example/topic",
  "subject": "example_event",
  "content_type": "application/json",
  "text": "{\"hello\":true}"
}

Node Runtime

A node can listen for incoming connections, connect to configured peers, discover peers over UDP broadcast, report status, dispatch outgoing messages, and clean up old state.

Storage

CmdLib

CmdLib (canweeb_cmdlib) is a Rust library that provides hardware control APIs for Raspberry Pi. It runs entirely on the Pi without any external microcontroller, using /dev/gpiochip0 (gpio-cdev) and standard system commands.

DtOverlay — Device Tree Overlay Management

Load, unload, and inspect Raspberry Pi Device Tree Overlays via the dtoverlay command.

MethodDescription
DtOverlay::load(name, params)Load an overlay with optional key=value parameters.
DtOverlay::unload(name)Unload a named overlay.
DtOverlay::list()Return a list of currently loaded overlays.
DtOverlay::is_loaded(name)Check whether an overlay is currently active.
DtOverlay::load("rotary-encoder", &[("relative_axis", "1"), ("steps-per-period", "1")])?;
DtOverlay::unload("rotary-encoder")?;

pinctrl — Pin Mode and Pull Configuration

Configure Raspberry Pi GPIO pin function and pull resistor state via the pinctrl utility.

MethodDescription
pinctrl_set(pin, mode, pull)Set a pin to input/output and configure pull-up/pull-down/none.
pinctrl_get(pin)Read the current function and level of a pin.
pinctrl_set(17, PinMode::Input, Pull::Up)?;
let state = pinctrl_get(17)?;

GpioUltrasonicSensor — HC-SR04 Distance Measurement

Measure distance using an HC-SR04 ultrasonic sensor directly wired to GPIO pins. Applies median filtering over multiple samples and discards outliers.

ParameterDescription
trigger_pinGPIO pin connected to HC-SR04 TRIG.
echo_pinGPIO pin connected to HC-SR04 ECHO.
samplesNumber of measurements to take for median filtering.
let sensor = GpioUltrasonicSensor::new(23, 24, 5)?;
let distance_cm = sensor.measure_cm()?;

GpioRotaryEncoder3Pin — Quadrature Rotary Encoder

Read a 3-pin quadrature rotary encoder directly from GPIO. Supports software debounce and atomic position reading from a background thread.

ParameterDescription
pin_a, pin_bTwo quadrature signal pins.
pin_swOptional push-button switch pin.
debounce_usMinimum pulse width in microseconds to accept as valid.
let enc = GpioRotaryEncoder3Pin::new(17, 27, 22, 500)?;
let position = enc.position(); // i64, updated by background thread

PwmOutput — PWM Motor and Servo Control

Generate PWM signals for motors, servos, and other PWM-controlled devices via the Arduino-compatible backend abstraction.

MethodDescription
PwmOutput::new(pin)Create a PWM output on a pin (default 25 kHz).
.frequency(hz)Set PWM frequency.
.range(min%, max%)Clamp duty cycle range.
.set_duty(percent)Apply duty cycle (0.0–100.0).
let mut pwm = PwmOutput::new(12).frequency(50);
pwm.set_duty(7.5)?; // 7.5% = servo center

RemoteExec — Child Program Execution

Define and spawn child-side programs through CmdLib. Useful for running sensor reader binaries managed by the CanWeeb runtime.

let child = RemoteExec::new("sensor-reader", &["/usr/bin/sensor-reader", "--port", "/dev/ttyUSB0"]);
child.spawn()?;

Runtime — Async Task Integration

CmdLib provides a Runtime handle to integrate hardware polling loops into a Tokio async runtime alongside the CanWeeb mesh tasks.

Examples

Marrio

marrio/input/jump
marrio/input/move

loli

*Note: Some student engineers in Japan jokingly refer to rotary encoders as `lolicon`.*
loli/encoder/position

Configuration

SectionPurpose
[node]Node identity, role, and tags.
[storage]Storage location and retention.
[web]HTTP and WebSocket bind address.
[transport]Network or USB listeners and timing.
[discovery]Automatic peer discovery.
[wifi]Wi-Fi interface, mode, and fallback networks.
[[peers]]Known peer definitions.
[node]
node_id = "parent"
role = "parent"

[storage]
root = "./data/parent"

[web]
bind = "0.0.0.0:8080"

[transport]
network_listen = "0.0.0.0:7002"

Getting Started from Clone

git clone https://github.com/rintaro-s/CanWeeb.git
cd CanWeeb

cargo run --release --bin canweeb -- --config config/parent.toml

The main executable is canweeb. If you omit --config, the default config path in code is config/example.toml.

To start a second node with another configuration:

cargo run --release --bin canweeb -- --config config/child.toml

Repository Layout

CanWeeb/
- src/          # runtime, config, protocol, storage, web, wifi
- CmdLib/       # Raspberry Pi control library
- config/       # example node configurations
- examples/     # application examples including Marrio and loli
- docs/         # public documentation

日本語

CanWeeb は、ロボティクス、センサー、ツール、インタラクティブアプリケーション向けのノード間通信システムです。信頼性の高い制御メッセージ配送、高速な telemetry 配信、stream 転送、内蔵 Web API、リアルタイム WebSocket 更新、ピア discovery、Wi-Fi 制御、そして CmdLib による Raspberry Pi ハードウェア統合を提供します。

リポジトリ概要

何ができるか

通信モデル

トラフィッククラス用途
controlACK と永続化を伴う、コマンド、イベント、状態変更向けの信頼性重視通信です。
telemetry最新値キャッシュ付きの、軽量なセンサー・状態更新向け通信です。
stream大きなバイナリペイロード向けの分割転送です。

メッセージは単一ノード、複数ノード、またはメッシュ全体へのブロードキャストに送れます。

Web API

CanWeeb には、統合、デバッグ、監視のための HTTP / WebSocket インターフェースが内蔵されています。

ルート機能
/api/statusランタイム状態、キュー数、inbox 数、ピア状態を取得します。
/api/messages新しいメッセージを送信します。
/api/inbox受信済み control メッセージを一覧します。
/api/inbox/:message_id1 件の inbox 詳細を取得します。
/api/topicsキャッシュ済み telemetry を一覧します。
/api/topic?name=...1 件の telemetry topic を取得します。
/api/streams完了済み stream を一覧します。
/api/streams/:stream_id1 件の完了済み stream を取得します。
/api/peer-policiesピアポリシーを取得または更新します。
/api/wifi/statusWi-Fi 状態を取得します。
/api/wifi/apply-modeWi-Fi モードを適用します。
/api/wifi/connectWi-Fi に接続します。
/api/wifi/disconnectWi-Fi を切断します。
/api/wifi/hotspot/startホットスポットモードを開始します。
/api/wifi-direct/runwpa_cli を直接実行します。
/ws/inboxinbox のリアルタイム更新を受信します。
/ws/topicstelemetry のリアルタイム更新を受信します。
/ws/streams完了済み stream の更新を受信します。

メッセージ送信例

{
  "target": "node:peer-a",
  "traffic_class": "control",
  "topic": "example/topic",
  "subject": "example_event",
  "content_type": "application/json",
  "text": "{\"hello\":true}"
}

ノードランタイム

ノードは、受信接続の待受、設定済みピアへの接続、UDP ブロードキャストによるピア検出、状態レポート、送信メッセージ配送、古い状態のクリーンアップを行えます。

ストレージ

CmdLib

CmdLib (canweeb_cmdlib) は、Raspberry Pi のハードウェアを制御するための Rust ライブラリです。外部マイコンは不要で、/dev/gpiochip0(gpio-cdev)とシステムコマンドのみで動作します。

DtOverlay — Device Tree Overlay 管理

dtoverlay コマンド経由で Raspberry Pi の DTOverlay をロード・アンロード・確認します。

メソッド説明
DtOverlay::load(name, params)オーバーレイを key=value パラメータ付きでロードします。
DtOverlay::unload(name)指定オーバーレイをアンロードします。
DtOverlay::list()現在ロード済みのオーバーレイ一覧を返します。
DtOverlay::is_loaded(name)オーバーレイがアクティブかどうかを確認します。
DtOverlay::load("rotary-encoder", &[("relative_axis", "1"), ("steps-per-period", "1")])?;
DtOverlay::unload("rotary-encoder")?;

pinctrl — ピンモード・プル設定

pinctrl ユーティリティを使って GPIO ピンの機能とプル抵抗設定を行います。

関数説明
pinctrl_set(pin, mode, pull)ピンを入力/出力に設定し、プルアップ/プルダウン/なしを指定します。
pinctrl_get(pin)現在のピン機能とレベルを読み取ります。
pinctrl_set(17, PinMode::Input, Pull::Up)?;
let state = pinctrl_get(17)?;

GpioUltrasonicSensor — HC-SR04 超音波距離測定

HC-SR04 超音波センサを GPIO に直結して距離を測定します。複数サンプルの中央値フィルタと外れ値除去を適用します。

パラメータ説明
trigger_pinHC-SR04 の TRIG に接続した GPIO ピン番号。
echo_pinHC-SR04 の ECHO に接続した GPIO ピン番号。
samples中央値フィルタのサンプル数。
let sensor = GpioUltrasonicSensor::new(23, 24, 5)?;
let distance_cm = sensor.measure_cm()?;

GpioRotaryEncoder3Pin — クアドラチャロータリーエンコーダ

3 ピンのクアドラチャロータリーエンコーダを GPIO 直結で読み取ります。ソフトウェアデバウンスとバックグラウンドスレッドによるアトミック位置更新に対応します。

パラメータ説明
pin_a, pin_bクアドラチャの 2 信号ピン。
pin_swプッシュスイッチのピン(省略可)。
debounce_us有効と判定する最小パルス幅(マイクロ秒)。
let enc = GpioRotaryEncoder3Pin::new(17, 27, 22, 500)?;
let position = enc.position(); // i64、バックグラウンドスレッドが更新

PwmOutput — PWM モーター・サーボ制御

Arduino 互換の backend 抽象化を通じて、モーター・サーボ等の PWM デバイスを制御します。

メソッド説明
PwmOutput::new(pin)指定ピンに PWM 出力を作成します(デフォルト 25 kHz)。
.frequency(hz)PWM 周波数を設定します。
.range(min%, max%)デューティ比の範囲を制限します。
.set_duty(percent)デューティ比を適用します(0.0〜100.0)。
let mut pwm = PwmOutput::new(12).frequency(50);
pwm.set_duty(7.5)?; // 7.5% = サーボ中央

RemoteExec — 子プログラム実行

CmdLib のヘルパーを使って子側プログラムを定義・起動します。CanWeeb ランタイムが管理するセンサーリーダーバイナリの実行に使用します。

let child = RemoteExec::new("sensor-reader", &["/usr/bin/sensor-reader", "--port", "/dev/ttyUSB0"]);
child.spawn()?;

Runtime — 非同期タスク統合

CmdLib は Runtime ハンドルを提供し、ハードウェアポーリングループを CanWeeb メッシュタスクと同じ Tokio 非同期ランタイムに統合できます。

サンプル

Marrio

marrio/input/jump
marrio/input/move

loli

loli/encoder/position

設定

セクション用途
[node]ノード識別、役割、タグです。
[storage]保存先と保持期間です。
[web]HTTP・WebSocket の待受アドレスです。
[transport]ネットワーク・USB 待受とタイミングです。
[discovery]自動ピア検出です。
[wifi]Wi-Fi インターフェース、モード、fallback 設定です。
[[peers]]既知ピア定義です。
[node]
node_id = "parent"
role = "parent"

[storage]
root = "./data/parent"

[web]
bind = "0.0.0.0:8080"

[transport]
network_listen = "0.0.0.0:7002"

クローンから始める

git clone https://github.com/rintaro-s/CanWeeb.git
cd CanWeeb

cargo run --release --bin canweeb -- --config config/parent.toml

メイン実行ファイルは canweeb です。--config を省略した場合、コード上のデフォルトは config/example.toml です。

別設定で 2 台目のノードを起動する場合:

cargo run --release --bin canweeb -- --config config/child.toml

リポジトリ構成

CanWeeb/
- src/          # runtime, config, protocol, storage, web, wifi
- CmdLib/       # Raspberry Pi control library
- config/       # example node configurations
- examples/     # application examples including Marrio and loli
- docs/         # public documentation