Compare commits
15 commits
dcadf16e1c
...
f6e0543627
Author | SHA1 | Date | |
---|---|---|---|
f6e0543627 | |||
7b08c2d61a | |||
a38fa94304 | |||
ee67db98ab | |||
0fa63e0512 | |||
6df844a410 | |||
cc255b77ab | |||
e440b2f72f | |||
8e91a0d950 | |||
d900308c5d | |||
18d0a57583 | |||
77513260a6 | |||
5e31ad2e24 | |||
028458d80b | |||
f7028b3f8c |
25 changed files with 3873 additions and 89 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1 +1 @@
|
||||||
/target
|
*/target
|
||||||
|
|
65
common/Cargo.lock
generated
Normal file
65
common/Cargo.lock
generated
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "common"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
7
common/Cargo.toml
Normal file
7
common/Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "common"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0.219", default-features = false, features = ["serde_derive", "derive"] }
|
18
common/src/lib.rs
Normal file
18
common/src/lib.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#![no_std]
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Default, Clone)]
|
||||||
|
pub struct Command {
|
||||||
|
/// duty cycle, -1.0 - 1.0
|
||||||
|
pub left: f32,
|
||||||
|
/// duty cycle, -1.0 - 1.0
|
||||||
|
pub right: f32,
|
||||||
|
pub ultrasonic_enable: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Default, Clone)]
|
||||||
|
pub struct Telemetry {
|
||||||
|
/// inches, front ultrasonic sensor
|
||||||
|
pub distance: f32,
|
||||||
|
}
|
395
converter/Cargo.lock
generated
Normal file
395
converter/Cargo.lock
generated
Normal file
|
@ -0,0 +1,395 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.98"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-polyfill"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cobs"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "common"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "converter"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"common",
|
||||||
|
"heapless",
|
||||||
|
"postcard",
|
||||||
|
"serde_json",
|
||||||
|
"serialport",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "critical-section"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hash32"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heapless"
|
||||||
|
version = "0.7.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-polyfill",
|
||||||
|
"hash32",
|
||||||
|
"rustc_version",
|
||||||
|
"serde",
|
||||||
|
"spin",
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "io-kit-sys"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys",
|
||||||
|
"mach2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.174"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libudev"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"libudev-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libudev-sys"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mach2"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.26.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "postcard"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c1de96e20f51df24ca73cafcc4690e044854d803259db27a00a461cb3b9d17a"
|
||||||
|
dependencies = [
|
||||||
|
"cobs",
|
||||||
|
"heapless",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.140"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serialport"
|
||||||
|
version = "4.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdb0bc984f6af6ef8bab54e6cf2071579ee75b9286aa9f2319a0d220c28b0a2b"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.1",
|
||||||
|
"cfg-if",
|
||||||
|
"core-foundation",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"io-kit-sys",
|
||||||
|
"libudev",
|
||||||
|
"mach2",
|
||||||
|
"nix",
|
||||||
|
"scopeguard",
|
||||||
|
"unescaper",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unescaper"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c01d12e3a56a4432a8b436f293c25f4808bdf9e9f9f98f9260bba1f1bc5a1f26"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
12
converter/Cargo.toml
Normal file
12
converter/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[package]
|
||||||
|
name = "converter"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serialport = "4.7.2"
|
||||||
|
postcard = "1.1.2"
|
||||||
|
common = { path = "../common" }
|
||||||
|
heapless = "0.7.17"
|
||||||
|
serde_json = "1.0.140"
|
||||||
|
anyhow = "1.0.98"
|
92
converter/src/main.rs
Normal file
92
converter/src/main.rs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
use std::{f32::NAN, io::{BufRead, BufReader, BufWriter, Read, Write}, net::TcpListener, sync::{Arc, Mutex}, thread::sleep, time::Duration};
|
||||||
|
|
||||||
|
use common::{Command, Telemetry};
|
||||||
|
use postcard::to_vec_cobs;
|
||||||
|
use heapless::Vec;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut port = serialport::new("/dev/ttyACM0", 115200)
|
||||||
|
.timeout(Duration::from_secs(1000))
|
||||||
|
.open().expect("port missing");
|
||||||
|
println!("connected over serial");
|
||||||
|
|
||||||
|
let command: Arc<Mutex<Command>> = Arc::new(Mutex::new(Command { left: 0.0, right: 0.0, ultrasonic_enable: true}));
|
||||||
|
let telemetry: Arc<Mutex<Telemetry>> = Arc::new(Mutex::new(Telemetry { distance: f32::NAN }));
|
||||||
|
|
||||||
|
// LabVIEW communication thread
|
||||||
|
{
|
||||||
|
let command = command.clone();
|
||||||
|
let telemetry = telemetry.clone();
|
||||||
|
std::thread::spawn(move || server(command,telemetry));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Telemetry receive thread
|
||||||
|
{
|
||||||
|
let reader = port.try_clone().unwrap();
|
||||||
|
let reader = BufReader::new(reader);
|
||||||
|
let telemetry = telemetry.clone();
|
||||||
|
std::thread::spawn(move || recv_telem(telemetry, reader));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command transmit thread (main)
|
||||||
|
loop {
|
||||||
|
let command = command.lock().unwrap().clone();
|
||||||
|
let encoded: Vec<u8, 20> = to_vec_cobs(&command).unwrap();
|
||||||
|
port.write(&encoded).expect("port write fail");
|
||||||
|
|
||||||
|
sleep(Duration::from_millis(200));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recv_telem<T: Read>(telemetry: Arc<Mutex<Telemetry>>, mut reader: BufReader<T>) {
|
||||||
|
let mut recv_buf = std::vec::Vec::new();
|
||||||
|
loop {
|
||||||
|
let Ok(len) = reader.read_until(0, &mut recv_buf) else {continue;};
|
||||||
|
if let Ok(telem) = postcard::from_bytes_cobs::<Telemetry>(&mut recv_buf[0..len]) {
|
||||||
|
*telemetry.lock().unwrap() = telem;
|
||||||
|
}
|
||||||
|
recv_buf.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn server(command: Arc<Mutex<Command>>, telemetry: Arc<Mutex<Telemetry>>) {
|
||||||
|
let listener = TcpListener::bind("0.0.0.0:4242").unwrap();
|
||||||
|
|
||||||
|
while let Ok((stream, _)) = listener.accept() {
|
||||||
|
println!("connected over IP");
|
||||||
|
let command1 = command.clone();
|
||||||
|
let telemetry1 = telemetry.clone();
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
if let Err(e) = handle_connection(command1, telemetry1, stream) {
|
||||||
|
println!("IP connection dropped: {}", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_connection(command: Arc<Mutex<Command>>, telemetry: Arc<Mutex<Telemetry>>, stream: std::net::TcpStream) -> anyhow::Result<()> {
|
||||||
|
let writer = stream.try_clone().unwrap();
|
||||||
|
let mut writer = BufWriter::new(writer);
|
||||||
|
let mut reader = BufReader::new(stream);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut data_buf = std::vec::Vec::new();
|
||||||
|
let len = reader.read_until(b'\n', &mut data_buf)?;
|
||||||
|
|
||||||
|
let Ok(new_command) = serde_json::from_slice::<Command>(&data_buf[0..len]) else {continue;};
|
||||||
|
|
||||||
|
*command.lock().unwrap() = new_command.clone();
|
||||||
|
println!("received l{} r{}", new_command.left, new_command.right);
|
||||||
|
|
||||||
|
let mut telem = telemetry.lock().unwrap().clone();
|
||||||
|
|
||||||
|
if telem.distance.is_nan() {
|
||||||
|
telem.distance = -1.0;
|
||||||
|
}
|
||||||
|
println!("sent d{}", telem.distance);
|
||||||
|
|
||||||
|
serde_json::to_writer(&mut writer, &telem).unwrap();
|
||||||
|
writer.write(&[b'\r',b'\n'])?;
|
||||||
|
writer.flush()?;
|
||||||
|
}
|
||||||
|
}
|
0
decoder/.cargo/config.toml
Normal file
0
decoder/.cargo/config.toml
Normal file
1
decoder/.gitignore
vendored
Normal file
1
decoder/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
decoderlib.h
|
355
decoder/Cargo.lock
generated
Normal file
355
decoder/Cargo.lock
generated
Normal file
|
@ -0,0 +1,355 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.24.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler2"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.74"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "decoder"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"tokio",
|
||||||
|
"zune-jpeg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.169"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394"
|
||||||
|
dependencies = [
|
||||||
|
"adler2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mio"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.36.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.92"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.38"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signal-hook-registry"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.13.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.42.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"bytes",
|
||||||
|
"libc",
|
||||||
|
"mio",
|
||||||
|
"parking_lot",
|
||||||
|
"pin-project-lite",
|
||||||
|
"signal-hook-registry",
|
||||||
|
"socket2",
|
||||||
|
"tokio-macros",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zune-core"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zune-jpeg"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028"
|
||||||
|
dependencies = [
|
||||||
|
"zune-core",
|
||||||
|
]
|
11
decoder/Cargo.toml
Normal file
11
decoder/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "decoder"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1.42.0", features = ["full"] }
|
||||||
|
zune-jpeg = "0.4.14"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib","lib"]
|
1
decoder/WIZ.txt
Normal file
1
decoder/WIZ.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uint8_t=unsigned __int8;uint16_t=unsigned __int16;uint32_t=unsigned __int32;uint64_t=unsigned __int64;int8_t=__int8;int16_t=__int16;int32_t=__int32;int64_t=__int64
|
16
decoder/justfile
Normal file
16
decoder/justfile
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
build: build-lvheader
|
||||||
|
cargo build --release
|
||||||
|
|
||||||
|
build-win: build-lvheader
|
||||||
|
cargo build --release --target x86_64-pc-windows-gnu
|
||||||
|
|
||||||
|
build-lvheader:
|
||||||
|
cbindgen --crate decoder --lang c --output decoderlib.h
|
||||||
|
sed -i 's/uint64_t/unsigned __int64/g' decoderlib.h
|
||||||
|
sed -i 's/uint32_t/unsigned __int32/g' decoderlib.h
|
||||||
|
sed -i 's/uint16_t/unsigned __int16/g' decoderlib.h
|
||||||
|
sed -i 's/uint8_t/unsigned __int8/g' decoderlib.h
|
||||||
|
|
||||||
|
upload: build-win
|
||||||
|
scp decoderlib.h hz:site/lvrs
|
||||||
|
scp target/x86_64-pc-windows-gnu/release/decoder.dll hz:site/lvrs
|
32
decoder/src/lib.rs
Normal file
32
decoder/src/lib.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
use std::{mem::transmute, slice};
|
||||||
|
|
||||||
|
use zune_jpeg::{zune_core::{colorspace::ColorSpace, options::DecoderOptions}, JpegDecoder};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn add(a: u64, b: u64) -> u64 {
|
||||||
|
a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
/// decode jpeg image of given length
|
||||||
|
///
|
||||||
|
/// image format is 0RGB
|
||||||
|
pub extern "C" fn decode(image: &mut u32, packet: &u8, length: u32) -> u64 {
|
||||||
|
let packet = unsafe {slice::from_raw_parts(packet, length as usize)};
|
||||||
|
let image: &mut [u8; 4*320*240] = unsafe{transmute(image)};
|
||||||
|
|
||||||
|
let options = DecoderOptions::new_fast().jpeg_set_out_colorspace(ColorSpace::RGB);
|
||||||
|
let Ok(mut frame) = JpegDecoder::new_with_options(packet, options).decode() else {
|
||||||
|
return 1; // decoder failure
|
||||||
|
};
|
||||||
|
|
||||||
|
// convert from RGB to 0RGB (and swap endianness)
|
||||||
|
for (buffer, image) in frame.chunks_exact_mut(3).zip(image.chunks_exact_mut(4)) {
|
||||||
|
image[0] = buffer[2];
|
||||||
|
image[1] = buffer[1];
|
||||||
|
image[2] = buffer[0];
|
||||||
|
image[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
0 // success
|
||||||
|
}
|
2055
encoder/Cargo.lock
generated
Normal file
2055
encoder/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
15
encoder/Cargo.toml
Normal file
15
encoder/Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "encoder"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.95"
|
||||||
|
battery = "0.7.8"
|
||||||
|
image = "0.25.5"
|
||||||
|
nokhwa = { version = "0.10.7", features = ["input-native"] }
|
||||||
|
openh264 = "0.6.6"
|
||||||
|
serde = { version = "1.0.217", features = ["derive"] }
|
||||||
|
serde_json = "1.0.134"
|
||||||
|
tokio = { version = "1.42.0", features = ["full", "io-util"] }
|
||||||
|
zune-jpeg = "0.4.14"
|
150
encoder/src/main.rs
Normal file
150
encoder/src/main.rs
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
use std::{array::from_ref, net::SocketAddr, result, sync::Arc, thread::{self}, time::{Duration, SystemTime, UNIX_EPOCH}};
|
||||||
|
|
||||||
|
use battery::Manager;
|
||||||
|
use image::{codecs::jpeg::JpegEncoder, ImageBuffer, Rgb};
|
||||||
|
use nokhwa::{pixel_format::RgbFormat, utils::{ApiBackend, RequestedFormat, RequestedFormatType, Resolution}, Camera};
|
||||||
|
use anyhow::{Context, Ok, Result};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tokio::{io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, net::{TcpListener, TcpStream}, runtime::Runtime, sync::{Notify, RwLock}, task::{JoinHandle, LocalSet}, time::sleep};
|
||||||
|
|
||||||
|
fn main() -> Result<()>{
|
||||||
|
let await_frame = Arc::new(Notify::new());
|
||||||
|
let latest_frame = Arc::new(RwLock::new(Vec::new()));
|
||||||
|
|
||||||
|
{
|
||||||
|
let runtime = Runtime::new()?;
|
||||||
|
let await_frame = await_frame.clone();
|
||||||
|
let latest_frame = latest_frame.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
let local = LocalSet::new();
|
||||||
|
local.block_on(&runtime, camera_manager(await_frame, latest_frame)).unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let runtime = Runtime::new()?;
|
||||||
|
let await_frame = await_frame.clone();
|
||||||
|
let latest_frame = latest_frame.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
let local = LocalSet::new();
|
||||||
|
local.block_on(&runtime, server(await_frame, latest_frame)).unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let runtime = Runtime::new()?;
|
||||||
|
|
||||||
|
runtime.block_on(telemetry_server()).unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Telemetry {
|
||||||
|
battery_level: f32,
|
||||||
|
timestamp: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct Control {
|
||||||
|
data: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn telemetry_server() -> Result<()>{
|
||||||
|
let port = 2994;
|
||||||
|
let listener = TcpListener::bind(format!("0.0.0.0:{port}")).await?;
|
||||||
|
|
||||||
|
while let result::Result::Ok((connection, addr)) = listener.accept().await {
|
||||||
|
println!("telemetry connection from {:?}", addr);
|
||||||
|
let (receiver, mut sender) = connection.into_split();
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut reader = BufReader::new(receiver).lines();
|
||||||
|
while let Some(line) = reader.next_line().await? {
|
||||||
|
//println!("recv: {line}");
|
||||||
|
if let result::Result::Ok(control) = serde_json::from_str::<Control>(&line) {
|
||||||
|
println!("deserialized: data is {}", control.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
let _: JoinHandle<Result<()>> = tokio::spawn(async move {
|
||||||
|
let battery = Manager::new()?.batteries()?.nth(0).context("no battery")??;
|
||||||
|
let full = battery.energy_full();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let time = SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis();
|
||||||
|
let mock = Telemetry { battery_level: (battery.energy()/full).value * 100., timestamp: time as u64 } ;
|
||||||
|
|
||||||
|
let mut send = serde_json::to_vec(&mock)?;
|
||||||
|
send.push(b'\r');
|
||||||
|
send.push(b'\n');
|
||||||
|
|
||||||
|
sender.write_all(&send).await?;
|
||||||
|
|
||||||
|
sleep(Duration::from_millis(20)).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn camera_manager(await_frame: Arc<Notify>, latest_frame: Arc<RwLock<Vec<u8>>>) -> Result<()>{
|
||||||
|
let cameras = nokhwa::query(ApiBackend::Auto)?;
|
||||||
|
|
||||||
|
for cam in &cameras {
|
||||||
|
println!("cam {cam:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
let camera = cameras.get(1).context("no cameras")?;
|
||||||
|
println!("using: {}",camera.human_name());
|
||||||
|
|
||||||
|
let requested = RequestedFormat::new::<RgbFormat>(RequestedFormatType::HighestResolution(Resolution::new(320, 240)));
|
||||||
|
|
||||||
|
let mut camera = Camera::new(camera.index().clone(), requested)?;
|
||||||
|
camera.open_stream()?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let frame = camera.frame()?;
|
||||||
|
let frame: ImageBuffer<Rgb<u8>, Vec<u8>> = frame.decode_image::<RgbFormat>()?;
|
||||||
|
|
||||||
|
let mut output = Vec::new();
|
||||||
|
|
||||||
|
let mut encoder = JpegEncoder::new_with_quality(&mut output, 30);
|
||||||
|
|
||||||
|
encoder.encode_image(&frame)?;
|
||||||
|
|
||||||
|
*latest_frame.write().await = output;
|
||||||
|
await_frame.notify_waiters();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn stream_video(await_frame: Arc<Notify>, latest_frame: Arc<RwLock<Vec<u8>>>, mut client: TcpStream) -> Result<()>{
|
||||||
|
loop {
|
||||||
|
await_frame.notified().await;
|
||||||
|
let data = latest_frame.read().await;
|
||||||
|
println!("len: {}", data.len());
|
||||||
|
|
||||||
|
let len = data.len();
|
||||||
|
|
||||||
|
// holding data across await, likely nonissue
|
||||||
|
client.write_u32(len as u32).await?;
|
||||||
|
client.write(&data).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn server(await_frame: Arc<Notify>, latest_frame: Arc<RwLock<Vec<u8>>>) -> Result<()> {
|
||||||
|
let port = 2993;
|
||||||
|
let listener = TcpListener::bind(format!("0.0.0.0:{port}")).await?;
|
||||||
|
println!("listening on {port}");
|
||||||
|
|
||||||
|
while let result::Result::Ok((client, addr)) = listener.accept().await {
|
||||||
|
println!("connected to {:?}", addr);
|
||||||
|
|
||||||
|
tokio::task::spawn_local(stream_video(await_frame.clone(), latest_frame.clone(), client));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
404
robot-controller/Cargo.lock
generated
Normal file
404
robot-controller/Cargo.lock
generated
Normal file
|
@ -0,0 +1,404 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arduino-hal"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/rahix/avr-hal?rev=fafaf587a32a4500239fd073f89d1b9c36b48092#fafaf587a32a4500239fd073f89d1b9c36b48092"
|
||||||
|
dependencies = [
|
||||||
|
"atmega-hal",
|
||||||
|
"avr-device",
|
||||||
|
"avr-hal-generic",
|
||||||
|
"cfg-if",
|
||||||
|
"embedded-hal 1.0.0",
|
||||||
|
"ufmt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atmega-hal"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/rahix/avr-hal?rev=fafaf587a32a4500239fd073f89d1b9c36b48092#fafaf587a32a4500239fd073f89d1b9c36b48092"
|
||||||
|
dependencies = [
|
||||||
|
"avr-device",
|
||||||
|
"avr-hal-generic",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-polyfill"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "avr-device"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "520f2031240156132bd83639d86aeb5b1907e6a228d9a4b44c3e9699827e6dae"
|
||||||
|
dependencies = [
|
||||||
|
"avr-device-macros",
|
||||||
|
"bare-metal",
|
||||||
|
"cfg-if",
|
||||||
|
"vcell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "avr-device-macros"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47c26fd925156183eb10e821b2ef7e06f8163f5a64a0bbe52fc896be2c6cbd3f"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "avr-hal-generic"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/rahix/avr-hal?rev=fafaf587a32a4500239fd073f89d1b9c36b48092#fafaf587a32a4500239fd073f89d1b9c36b48092"
|
||||||
|
dependencies = [
|
||||||
|
"avr-device",
|
||||||
|
"embedded-hal 0.2.7",
|
||||||
|
"embedded-hal 1.0.0",
|
||||||
|
"embedded-hal-bus",
|
||||||
|
"embedded-storage",
|
||||||
|
"nb 1.1.0",
|
||||||
|
"paste",
|
||||||
|
"ufmt",
|
||||||
|
"unwrap-infallible",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bare-metal"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cobs"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "common"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "critical-section"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-hal"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
|
||||||
|
dependencies = [
|
||||||
|
"nb 0.1.3",
|
||||||
|
"void",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-hal"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-hal-bus"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57b4e6ede84339ebdb418cd986e6320a34b017cdf99b5cc3efceec6450b06886"
|
||||||
|
dependencies = [
|
||||||
|
"critical-section",
|
||||||
|
"embedded-hal 1.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedded-storage"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "723dce4e9f25b6e6c5f35628e144794e5b459216ed7da97b7c4b66cdb3fa82ca"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hash32"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heapless"
|
||||||
|
version = "0.7.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-polyfill",
|
||||||
|
"hash32",
|
||||||
|
"rustc_version",
|
||||||
|
"serde",
|
||||||
|
"spin",
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nb"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
|
||||||
|
dependencies = [
|
||||||
|
"nb 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nb"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "panic-halt"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a513e167849a384b7f9b746e517604398518590a9142f4846a32e3c2a4de7b11"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "paste"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "postcard"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c1de96e20f51df24ca73cafcc4690e044854d803259db27a00a461cb3b9d17a"
|
||||||
|
dependencies = [
|
||||||
|
"cobs",
|
||||||
|
"heapless",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.95"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "robot-controller"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arduino-hal",
|
||||||
|
"avr-device",
|
||||||
|
"common",
|
||||||
|
"embedded-hal 1.0.0",
|
||||||
|
"nb 1.1.0",
|
||||||
|
"panic-halt",
|
||||||
|
"postcard",
|
||||||
|
"serde",
|
||||||
|
"ufmt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.26"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.219"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.104",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.104"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.104",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ufmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a64846ec02b57e9108d6469d98d1648782ad6bb150a95a9baac26900bbeab9d"
|
||||||
|
dependencies = [
|
||||||
|
"ufmt-macros",
|
||||||
|
"ufmt-write",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ufmt-macros"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d337d3be617449165cb4633c8dece429afd83f84051024079f97ad32a9663716"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ufmt-write"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unwrap-infallible"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vcell"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "void"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
|
@ -15,6 +15,10 @@ panic-halt = "1.0.0"
|
||||||
ufmt = "0.2.0"
|
ufmt = "0.2.0"
|
||||||
nb = "1.1.0"
|
nb = "1.1.0"
|
||||||
embedded-hal = "1.0"
|
embedded-hal = "1.0"
|
||||||
|
avr-device = "0.7.0"
|
||||||
|
serde = { version = "1.0.219", default-features = false, features = ["serde_derive", "derive"] }
|
||||||
|
postcard = "1.1.2"
|
||||||
|
common = { path = "../common" }
|
||||||
|
|
||||||
[dependencies.arduino-hal]
|
[dependencies.arduino-hal]
|
||||||
git = "https://github.com/rahix/avr-hal"
|
git = "https://github.com/rahix/avr-hal"
|
||||||
|
@ -32,4 +36,4 @@ panic = "abort"
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
debug = true
|
debug = true
|
||||||
lto = true
|
lto = true
|
||||||
opt-level = "s"
|
opt-level = "z"
|
238
robot-controller/src/main.rs
Normal file
238
robot-controller/src/main.rs
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(abi_avr_interrupt)]
|
||||||
|
|
||||||
|
use core::cell::RefCell;
|
||||||
|
use core::f32;
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
|
|
||||||
|
use arduino_hal::{clock::MHz16, hal::usart::UsartWriter};
|
||||||
|
use arduino_hal::hal::port::*;
|
||||||
|
use arduino_hal::hal::usart::UsartReader;
|
||||||
|
use arduino_hal::pac::USART0;
|
||||||
|
use arduino_hal::port::mode::*;
|
||||||
|
use arduino_hal::prelude::*;
|
||||||
|
use avr_device::interrupt::{self, Mutex};
|
||||||
|
use common::{Command, Telemetry};
|
||||||
|
use panic_halt as _;
|
||||||
|
|
||||||
|
fn shift_out(data_pin: &mut Pin<Output, PB0>, clock_pin: &mut Pin<Output, PD4>, data: &u8) {
|
||||||
|
for i in 0..8 {
|
||||||
|
let n = data & (1 << i);
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
data_pin.set_low();
|
||||||
|
} else {
|
||||||
|
data_pin.set_high();
|
||||||
|
}
|
||||||
|
|
||||||
|
clock_pin.set_high();
|
||||||
|
clock_pin.set_low();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_shift_register(
|
||||||
|
data_pin: &mut Pin<Output, PB0>,
|
||||||
|
latch_pin: &mut Pin<Output, PB4>,
|
||||||
|
clock_pin: &mut Pin<Output, PD4>,
|
||||||
|
data: &u8,
|
||||||
|
) {
|
||||||
|
latch_pin.set_low();
|
||||||
|
|
||||||
|
shift_out(data_pin, clock_pin, data);
|
||||||
|
|
||||||
|
latch_pin.set_high();
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut UART_RX: MaybeUninit<UsartReader<USART0, Pin<Input, PD0>, Pin<Output, PD1>, MHz16>> = MaybeUninit::uninit();
|
||||||
|
|
||||||
|
static INPUT_LINE: Mutex<RefCell<[u8; 20]>> = Mutex::new(RefCell::new([0;20]));
|
||||||
|
|
||||||
|
#[avr_device::interrupt(atmega328p)]
|
||||||
|
unsafe fn USART_RX() {
|
||||||
|
let rx = &mut *UART_RX.as_mut_ptr();
|
||||||
|
|
||||||
|
static mut BUF: [u8; 20] = [0;20];
|
||||||
|
static mut N: usize = 0; // index into line
|
||||||
|
|
||||||
|
if let Ok(val) = rx.read() {
|
||||||
|
if val == b'\0' {
|
||||||
|
|
||||||
|
interrupt::free(|cs| {
|
||||||
|
let mut line = INPUT_LINE.borrow(cs).borrow_mut();
|
||||||
|
*line = BUF;
|
||||||
|
line[N] = b'\0';
|
||||||
|
});
|
||||||
|
|
||||||
|
N = 0;
|
||||||
|
} else {
|
||||||
|
BUF[N] = val;
|
||||||
|
N += 1;
|
||||||
|
if N == 20 {
|
||||||
|
N = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[arduino_hal::entry]
|
||||||
|
fn main() -> ! {
|
||||||
|
let dp = arduino_hal::Peripherals::take().unwrap();
|
||||||
|
let pins = arduino_hal::pins!(dp);
|
||||||
|
|
||||||
|
// shift register
|
||||||
|
let mut data_pin = pins.d8.into_output();
|
||||||
|
let mut clock_pin = pins.d4.into_output();
|
||||||
|
let mut enable_pin = pins.d7.into_output();
|
||||||
|
let mut latch_pin = pins.d12.into_output();
|
||||||
|
|
||||||
|
enable_pin.set_low(); // enable outputs
|
||||||
|
|
||||||
|
pins.d3.into_output(); // right
|
||||||
|
pins.d11.into_output(); // left
|
||||||
|
|
||||||
|
// TCCR2A |= _BV(COM2A1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2a
|
||||||
|
// TCCR2B = freq & 0x7;
|
||||||
|
// OCR2A = 0;
|
||||||
|
let tc2 = dp.TC2;
|
||||||
|
tc2.tccr2a.write(|w| { w
|
||||||
|
.wgm2().pwm_fast()
|
||||||
|
.com2a().match_clear()
|
||||||
|
.com2b().match_clear()
|
||||||
|
});
|
||||||
|
tc2.tccr2b.write(|w| w.cs2().prescale_8().wgm22().clear_bit());
|
||||||
|
tc2.ocr2a.write(|w| w.bits(0));
|
||||||
|
tc2.ocr2b.write(|w| w.bits(0));
|
||||||
|
|
||||||
|
let mut trig = pins.a4.into_output();
|
||||||
|
let echo = pins.a5;
|
||||||
|
|
||||||
|
let ultrasonic_timer = dp.TC1;
|
||||||
|
// 4us per tick
|
||||||
|
ultrasonic_timer.tccr1b.write(|w| w.cs1().prescale_64());
|
||||||
|
|
||||||
|
let mut led = pins.d13.into_output();
|
||||||
|
|
||||||
|
let mut serial = arduino_hal::default_serial!(dp, pins, 115200);
|
||||||
|
|
||||||
|
avr_device::interrupt::disable();
|
||||||
|
serial.listen(arduino_hal::hal::usart::Event::RxComplete);
|
||||||
|
|
||||||
|
let (rx,mut tx) = serial.split();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
UART_RX = MaybeUninit::new(rx);
|
||||||
|
avr_device::interrupt::enable();
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut telem = Telemetry { distance: f32::NAN };
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut shift_register = 0;
|
||||||
|
const LEFT_FWD: u8 = 1 << 5; // 1a
|
||||||
|
const LEFT_REV: u8 = 1 << 4; // 1b
|
||||||
|
const RIGHT_FWD: u8 = 1 << 3; // 2b
|
||||||
|
const RIGHT_REV: u8 = 1 << 6; // 2a
|
||||||
|
|
||||||
|
led.toggle();
|
||||||
|
|
||||||
|
let command = decode_command();
|
||||||
|
|
||||||
|
if command.left > 0. {
|
||||||
|
shift_register |= LEFT_FWD;
|
||||||
|
}
|
||||||
|
if command.left < 0. {
|
||||||
|
shift_register |= LEFT_REV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if command.right > 0. {
|
||||||
|
shift_register |= RIGHT_FWD;
|
||||||
|
}
|
||||||
|
if command.right < 0. {
|
||||||
|
shift_register |= RIGHT_REV;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_pwm(val: f32) -> u8 {
|
||||||
|
(val.abs().min(1.0) * 255.0) as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
// 16/255
|
||||||
|
tc2.ocr2a.write(|w| w.bits(to_pwm(command.left))); // left
|
||||||
|
tc2.ocr2b.write(|w| w.bits(to_pwm(command.right))); // right
|
||||||
|
|
||||||
|
update_shift_register(&mut data_pin, &mut latch_pin, &mut clock_pin, &shift_register);
|
||||||
|
|
||||||
|
if command.ultrasonic_enable {
|
||||||
|
// reset timer
|
||||||
|
ultrasonic_timer.tcnt1.write(|w| w.bits(0));
|
||||||
|
|
||||||
|
// send ultrasonic pulse
|
||||||
|
trig.set_high();
|
||||||
|
arduino_hal::delay_us(10);
|
||||||
|
trig.set_low();
|
||||||
|
|
||||||
|
let mut response = true;
|
||||||
|
|
||||||
|
/// 0.1s/4µs = 25,000
|
||||||
|
const SIGNAL_START_TIMEOUT: u16 = 25000;
|
||||||
|
|
||||||
|
// wait for return signal start
|
||||||
|
while echo.is_low() {
|
||||||
|
if ultrasonic_timer.tcnt1.read().bits() >= SIGNAL_START_TIMEOUT {
|
||||||
|
response = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if response {
|
||||||
|
let remainder = ultrasonic_timer.tcnt1.read().bits();
|
||||||
|
ultrasonic_timer.tcnt1.write(|w| w.bits(0));
|
||||||
|
|
||||||
|
// Wait for the echo to get low again
|
||||||
|
while echo.is_high() {}
|
||||||
|
let counts = ultrasonic_timer.tcnt1.read().bits();
|
||||||
|
let microseconds = counts.saturating_mul(4);
|
||||||
|
|
||||||
|
// inch per 148 microseconds
|
||||||
|
telem.distance = microseconds as f32 / 148.;
|
||||||
|
if microseconds == u16::MAX { telem.distance = f32::NAN };
|
||||||
|
|
||||||
|
// delay for the rest of the return signal timeout if any is left
|
||||||
|
ultrasonic_timer.tcnt1.write(|w| w.bits(SIGNAL_START_TIMEOUT.saturating_sub(remainder + counts)));
|
||||||
|
while ultrasonic_timer.tcnt1.read().bits() <= SIGNAL_START_TIMEOUT {}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
telem.distance = f32::NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// ultrasonic disabled
|
||||||
|
telem.distance = f32::NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut buf = [0;20];
|
||||||
|
let encoded = postcard::to_slice_cobs(&telem, &mut buf).unwrap();
|
||||||
|
|
||||||
|
for word in encoded {
|
||||||
|
let _ = tx.write(*word);
|
||||||
|
let _ = tx.flush();
|
||||||
|
arduino_hal::delay_us(100); // delay to ensure linux can keep up
|
||||||
|
}
|
||||||
|
|
||||||
|
if command.ultrasonic_enable {
|
||||||
|
// wait for the echoes to fade
|
||||||
|
arduino_hal::delay_ms(50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode_command() -> Command {
|
||||||
|
let mut input = interrupt::free(|cs| {
|
||||||
|
INPUT_LINE.borrow(cs).borrow().clone()
|
||||||
|
});
|
||||||
|
|
||||||
|
let Some(length) = input.iter().position(|n| *n == 0) else { return Default::default() };
|
||||||
|
|
||||||
|
postcard::from_bytes_cobs(&mut input[..=length]).unwrap_or(Default::default())
|
||||||
|
}
|
87
src/main.rs
87
src/main.rs
|
@ -1,87 +0,0 @@
|
||||||
#![no_std]
|
|
||||||
#![no_main]
|
|
||||||
|
|
||||||
use arduino_hal::hal::port::*;
|
|
||||||
use arduino_hal::port::mode::*;
|
|
||||||
use embedded_hal::digital::OutputPin;
|
|
||||||
use panic_halt as _;
|
|
||||||
|
|
||||||
fn shift_out(data_pin: &mut Pin<Output, PB0>, clock_pin: &mut Pin<Output, PD4>, data: &u8) {
|
|
||||||
for i in 0..8 {
|
|
||||||
let n = data & (1 << i);
|
|
||||||
|
|
||||||
if n == 0 {
|
|
||||||
data_pin.set_low();
|
|
||||||
} else {
|
|
||||||
data_pin.set_high();
|
|
||||||
}
|
|
||||||
|
|
||||||
clock_pin.set_high();
|
|
||||||
clock_pin.set_low();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_shift_register(
|
|
||||||
data_pin: &mut Pin<Output, PB0>,
|
|
||||||
latch_pin: &mut Pin<Output, PB4>,
|
|
||||||
clock_pin: &mut Pin<Output, PD4>,
|
|
||||||
data: &u8,
|
|
||||||
) {
|
|
||||||
latch_pin.set_low();
|
|
||||||
|
|
||||||
shift_out(data_pin, clock_pin, data);
|
|
||||||
|
|
||||||
latch_pin.set_high();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[arduino_hal::entry]
|
|
||||||
fn main() -> ! {
|
|
||||||
let dp = arduino_hal::Peripherals::take().unwrap();
|
|
||||||
let pins = arduino_hal::pins!(dp);
|
|
||||||
|
|
||||||
// shift register
|
|
||||||
let mut data_pin = pins.d8.into_output();
|
|
||||||
let mut clock_pin = pins.d4.into_output();
|
|
||||||
let mut enable_pin = pins.d7.into_output();
|
|
||||||
let mut latch_pin = pins.d12.into_output();
|
|
||||||
|
|
||||||
enable_pin.set_low(); // enable outputs
|
|
||||||
|
|
||||||
let _ = pins.d3.into_output(); // right
|
|
||||||
let _ = pins.d11.into_output(); // left
|
|
||||||
|
|
||||||
// TCCR2A |= _BV(COM2A1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2a
|
|
||||||
// TCCR2B = freq & 0x7;
|
|
||||||
// OCR2A = 0;
|
|
||||||
let tc2 = dp.TC2;
|
|
||||||
tc2.tccr2a.write(|w| { w
|
|
||||||
.wgm2().pwm_fast()
|
|
||||||
.com2a().match_set()
|
|
||||||
.com2b().match_set()
|
|
||||||
});
|
|
||||||
tc2.tccr2b.write(|w| w.cs2().prescale_8().foc2b().clear_bit().foc2a().clear_bit().wgm22().clear_bit());
|
|
||||||
tc2.ocr2a.write(|w| w.bits(2));
|
|
||||||
tc2.ocr2b.write(|w| w.bits(2));
|
|
||||||
|
|
||||||
let mut led = pins.d13.into_output();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let mut shift_register = 0;
|
|
||||||
const LEFT_FWD: u8 = 1 << 5; // 1a
|
|
||||||
const LEFT_REV: u8 = 1 << 4; // 1b
|
|
||||||
const RIGHT_FWD: u8 = 1 << 3; // 2b
|
|
||||||
const RIGHT_REV: u8 = 1 << 6; // 2a
|
|
||||||
|
|
||||||
led.toggle();
|
|
||||||
|
|
||||||
shift_register |= LEFT_FWD | RIGHT_FWD;
|
|
||||||
|
|
||||||
// /255
|
|
||||||
tc2.ocr2a.write(|w| w.bits(1)); // right
|
|
||||||
tc2.ocr2b.write(|w| w.bits(1)); // left
|
|
||||||
|
|
||||||
update_shift_register(&mut data_pin, &mut latch_pin, &mut clock_pin, &shift_register);
|
|
||||||
|
|
||||||
arduino_hal::delay_ms(1000);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue