Compare commits
2 commits
502afc9a5f
...
5f9e718f86
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f9e718f86 | ||
|
|
7791c55969 |
7 changed files with 366 additions and 46 deletions
Binary file not shown.
135
spinnyboy_rust/Cargo.lock
generated
135
spinnyboy_rust/Cargo.lock
generated
|
|
@ -40,6 +40,12 @@ dependencies = [
|
||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.10.0"
|
version = "2.10.0"
|
||||||
|
|
@ -155,6 +161,38 @@ dependencies = [
|
||||||
"syn 2.0.111",
|
"syn 2.0.111",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "defmt"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"defmt-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "defmt-macros"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e"
|
||||||
|
dependencies = [
|
||||||
|
"defmt-parser",
|
||||||
|
"proc-macro-error2",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "defmt-parser"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "delegate"
|
name = "delegate"
|
||||||
version = "0.13.5"
|
version = "0.13.5"
|
||||||
|
|
@ -227,7 +265,7 @@ dependencies = [
|
||||||
"embedded-io-async 0.6.1",
|
"embedded-io-async 0.6.1",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"heapless",
|
"heapless 0.8.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -241,7 +279,7 @@ dependencies = [
|
||||||
"embedded-io-async 0.6.1",
|
"embedded-io-async 0.6.1",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"heapless",
|
"heapless 0.8.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -366,6 +404,23 @@ dependencies = [
|
||||||
"rlsf",
|
"rlsf",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "esp-backtrace"
|
||||||
|
version = "0.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3318413fb566c7227387f67736cf70cd74d80a11f2bb31c7b95a9eb48d079669"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"defmt",
|
||||||
|
"document-features",
|
||||||
|
"esp-config",
|
||||||
|
"esp-metadata-generated",
|
||||||
|
"esp-println",
|
||||||
|
"heapless 0.9.2",
|
||||||
|
"riscv",
|
||||||
|
"xtensa-lx",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "esp-bootloader-esp-idf"
|
name = "esp-bootloader-esp-idf"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
@ -403,7 +458,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "54786287c0a61ca0f78cb0c338a39427551d1be229103b4444591796c579e093"
|
checksum = "54786287c0a61ca0f78cb0c338a39427551d1be229103b4444591796c579e093"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitfield",
|
"bitfield",
|
||||||
"bitflags",
|
"bitflags 2.10.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"critical-section",
|
"critical-section",
|
||||||
|
|
@ -469,6 +524,18 @@ version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a93e39c8ad8d390d248dc7b9f4b59a873f313bf535218b8e2351356972399e3"
|
checksum = "9a93e39c8ad8d390d248dc7b9f4b59a873f313bf535218b8e2351356972399e3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "esp-println"
|
||||||
|
version = "0.16.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a30e6c9fbcc01c348d46706fef8131c7775ab84c254a3cd65d0cd3f6414d592"
|
||||||
|
dependencies = [
|
||||||
|
"document-features",
|
||||||
|
"esp-metadata-generated",
|
||||||
|
"esp-sync",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "esp-riscv-rt"
|
name = "esp-riscv-rt"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
|
|
@ -662,6 +729,16 @@ dependencies = [
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heapless"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed"
|
||||||
|
dependencies = [
|
||||||
|
"hash32",
|
||||||
|
"stable_deref_trait",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
|
@ -742,6 +819,12 @@ version = "0.2.178"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libm"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked_list_allocator"
|
name = "linked_list_allocator"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
|
|
@ -788,6 +871,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
|
"libm",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -841,6 +925,28 @@ dependencies = [
|
||||||
"toml_edit",
|
"toml_edit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr2"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error2"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr2",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.103"
|
version = "1.0.103"
|
||||||
|
|
@ -1028,9 +1134,12 @@ name = "spinnyboy_rust"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"critical-section",
|
"critical-section",
|
||||||
|
"embedded-hal 1.0.0",
|
||||||
"esp-alloc",
|
"esp-alloc",
|
||||||
|
"esp-backtrace",
|
||||||
"esp-bootloader-esp-idf",
|
"esp-bootloader-esp-idf",
|
||||||
"esp-hal",
|
"esp-hal",
|
||||||
|
"num-traits",
|
||||||
"rtt-target",
|
"rtt-target",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1111,6 +1220,26 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.111",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.7.5+spec-1.1.0"
|
version = "0.7.5+spec-1.1.0"
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,13 @@ esp-hal = { version = "1.0.0", features = ["esp32c6", "unstable"] }
|
||||||
|
|
||||||
esp-bootloader-esp-idf = { version = "0.4.0", features = ["esp32c6"] }
|
esp-bootloader-esp-idf = { version = "0.4.0", features = ["esp32c6"] }
|
||||||
|
|
||||||
critical-section = "1.2.0"
|
critical-section = {version = "1.2.0"}
|
||||||
esp-alloc = "0.9.0"
|
esp-alloc = "0.9.0"
|
||||||
rtt-target = "0.6.2"
|
rtt-target = "0.6.2"
|
||||||
embedded-hal = "1.0.0"
|
embedded-hal = "1.0.0"
|
||||||
esp-backtrace = {version = "0.18.1",features = ["esp32c6","defmt"]}
|
esp-backtrace = {version = "0.18.1",features = ["esp32c6","defmt"]}
|
||||||
|
#esp-hal-dshot = {version = "0.3.1",default-features = false ,features = ["esp32c6"]}
|
||||||
|
num-traits = { version = "0.2.19", default-features = false, features = ["libm"] }
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
# Rust debug is too slow.
|
# Rust debug is too slow.
|
||||||
|
|
|
||||||
207
spinnyboy_rust/src/bin/dc_driver/dshot.rs
Normal file
207
spinnyboy_rust/src/bin/dc_driver/dshot.rs
Normal file
|
|
@ -0,0 +1,207 @@
|
||||||
|
// use embedded_hal_async::delay::DelayNs;
|
||||||
|
use esp_hal::{
|
||||||
|
delay::Delay,
|
||||||
|
gpio::Level,
|
||||||
|
rmt::{Channel, PulseCode, Rx, Tx, TxChannelCreator},
|
||||||
|
};
|
||||||
|
use num_traits::float::FloatCore;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DSHOT_TELEMETRY_CMD {
|
||||||
|
MOTOR_STOP = 0x0,
|
||||||
|
BEEP1 = 0x01,
|
||||||
|
BEEP2 = 0x02,
|
||||||
|
BEEP3 = 0x03,
|
||||||
|
BEEP4 = 0x04,
|
||||||
|
BEEP5 = 0x05,
|
||||||
|
ESC_INFO = 0x06,
|
||||||
|
SPIN_DIRECTION_1 = 0x07,
|
||||||
|
SPIN_DIRECTION_2 = 0x08,
|
||||||
|
MODE_3D_OFF = 0x09,
|
||||||
|
MODE_3D_ON = 0x0A,
|
||||||
|
SETTINGS_REQUEST = 0x0B,
|
||||||
|
SAVE_SETTINGS = 0x0C,
|
||||||
|
EXTENDED_TELEMETRY_ENABLE = 0x0D,
|
||||||
|
EXTENDED_TELEMETRY_DISABLE = 0x0E,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct BitTicks {
|
||||||
|
t0_h: u16,
|
||||||
|
t0_l: u16,
|
||||||
|
t1_h: u16,
|
||||||
|
t1_l: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitTicks {
|
||||||
|
pub fn new(t1_h: u16, t0_h: u16) -> Self {
|
||||||
|
Self {
|
||||||
|
t0_h,
|
||||||
|
t1_h,
|
||||||
|
t0_l: t1_h,
|
||||||
|
t1_l: t0_h,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_clk(clk_speed: u32, clk_divider: u8, bit_times: BitTimes) -> Self {
|
||||||
|
let tick_len = (1. / clk_speed as f32) * (clk_divider as f32) * 1_000_000.;
|
||||||
|
|
||||||
|
let t1_h = (bit_times.t1_h / tick_len).round() as u16;
|
||||||
|
let t0_h = (bit_times.t0_h / tick_len).round() as u16;
|
||||||
|
|
||||||
|
Self::new(t1_h, t0_h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// High and Low Times in µs
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct BitTimes {
|
||||||
|
t0_h: f32,
|
||||||
|
t1_h: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitTimes {
|
||||||
|
pub fn new(t1_h: f32, t0_h: f32) -> Self {
|
||||||
|
Self { t0_h, t1_h }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum DShotSpeed {
|
||||||
|
DShot150,
|
||||||
|
DShot300,
|
||||||
|
DShot600,
|
||||||
|
DShot1200,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DShotSpeed {
|
||||||
|
pub fn bit_period_ns(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
// 6.67µs per bit
|
||||||
|
Self::DShot150 => 6667,
|
||||||
|
// 3.33µs per bit
|
||||||
|
Self::DShot300 => 3333,
|
||||||
|
// 1.67µs per bit
|
||||||
|
Self::DShot600 => 1667,
|
||||||
|
// 0.83µs per bit
|
||||||
|
Self::DShot1200 => 833,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// High and Low Times in µs
|
||||||
|
pub fn bit_times(&self) -> BitTimes {
|
||||||
|
match &self {
|
||||||
|
Self::DShot150 => BitTimes::new(5.00, 2.50),
|
||||||
|
Self::DShot300 => BitTimes::new(2.50, 1.25),
|
||||||
|
Self::DShot600 => BitTimes::new(1.25, 0.625),
|
||||||
|
Self::DShot1200 => BitTimes::new(0.625, 0.313),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// These are for an 80 MHz clock with a clock divider setting of 1
|
||||||
|
pub fn default_bit_ticks(&self) -> BitTicks {
|
||||||
|
match &self {
|
||||||
|
Self::DShot150 => BitTicks::new(400, 200),
|
||||||
|
Self::DShot300 => BitTicks::new(200, 100),
|
||||||
|
Self::DShot600 => BitTicks::new(100, 50),
|
||||||
|
Self::DShot1200 => BitTicks::new(50, 25),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DShot<'a> {
|
||||||
|
rx_channel: &'a mut Channel<'static, esp_hal::Blocking, esp_hal::rmt::Rx>,
|
||||||
|
tx_channel: &'a mut Channel<'static, esp_hal::Blocking, esp_hal::rmt::Tx>,
|
||||||
|
speed: DShotSpeed,
|
||||||
|
bit_ticks: BitTicks,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DShot<'a> {
|
||||||
|
pub fn new(
|
||||||
|
rx_channel: &'a mut Channel<'static, esp_hal::Blocking, esp_hal::rmt::Rx>,
|
||||||
|
tx_channel: &'a mut Channel<'static, esp_hal::Blocking, esp_hal::rmt::Tx>,
|
||||||
|
speed: DShotSpeed,
|
||||||
|
clk_speed: Option<u32>,
|
||||||
|
clk_divider: Option<u8>,
|
||||||
|
) -> Self {
|
||||||
|
let clk_speed = clk_speed.unwrap_or(80_000_000);
|
||||||
|
let clk_divider = clk_divider.unwrap_or(1);
|
||||||
|
|
||||||
|
let bit_ticks = BitTicks::from_clk(clk_speed, clk_divider, speed.bit_times());
|
||||||
|
Self {
|
||||||
|
rx_channel: rx_channel,
|
||||||
|
tx_channel: tx_channel,
|
||||||
|
speed,
|
||||||
|
bit_ticks,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calculate_crc(frame: u16) -> u16 {
|
||||||
|
(frame ^ (frame >> 4) ^ (frame >> 8)) & 0xF
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_frame(value: u16, telemetry: bool) -> u16 {
|
||||||
|
// Mask to 11 bits (0-2047 range) and set telemetry bit
|
||||||
|
let frame = ((value & 0x07FF) << 1) | telemetry as u16;
|
||||||
|
|
||||||
|
let crc = Self::calculate_crc(frame);
|
||||||
|
|
||||||
|
(frame << 4) | crc
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_range_loop)]
|
||||||
|
pub fn create_pulses(&mut self, throttle_value: u16, telemetry: bool) -> [u32; 17] {
|
||||||
|
let frame = Self::create_frame(throttle_value, telemetry);
|
||||||
|
let mut pulses = [0; 17];
|
||||||
|
for i in 0..16 {
|
||||||
|
let bit = (frame >> (15 - i)) & 1;
|
||||||
|
|
||||||
|
pulses[i] = if bit == 1 {
|
||||||
|
PulseCode::new(
|
||||||
|
Level::High,
|
||||||
|
self.bit_ticks.t1_h,
|
||||||
|
Level::Low,
|
||||||
|
self.bit_ticks.t1_l,
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
} else {
|
||||||
|
PulseCode::new(
|
||||||
|
Level::High,
|
||||||
|
self.bit_ticks.t0_h,
|
||||||
|
Level::Low,
|
||||||
|
self.bit_ticks.t0_l,
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add empty pulse to end of pulses frame
|
||||||
|
pulses[16] = 0;
|
||||||
|
pulses
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_throttle(&mut self, throttle: u16, telemetry: bool) -> Result<(), &'static str> {
|
||||||
|
let pulses = self.create_pulses(throttle, telemetry);
|
||||||
|
let tx_chann = self.tx_channel.reborrow();
|
||||||
|
let transaction = tx_chann
|
||||||
|
.transmit(&pulses)
|
||||||
|
.unwrap_or(return Err("Failed to send frame"))
|
||||||
|
.wait()
|
||||||
|
.unwrap_or(return Err("Waiting failed!"));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn arm(&mut self, delay: &mut Delay) -> Result<(), &'static str> {
|
||||||
|
for _ in 0..100 {
|
||||||
|
self.write_throttle(0, false)?;
|
||||||
|
delay.delay_millis(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
pub mod afroesc;
|
pub mod afroesc;
|
||||||
|
pub mod dshot;
|
||||||
pub enum EscState {
|
pub enum EscState {
|
||||||
Starting,
|
Starting,
|
||||||
Running,
|
Running,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
)]
|
)]
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
use esp_hal::uart::{self, Config, Uart};
|
use esp_hal::uart::{Config, Uart};
|
||||||
|
|
||||||
use esp_hal::clock::CpuClock;
|
use esp_hal::clock::CpuClock;
|
||||||
use esp_hal::delay::Delay;
|
use esp_hal::delay::Delay;
|
||||||
|
|
@ -171,7 +171,6 @@ fn main() -> ! {
|
||||||
// pwm_pin.set_timestamp(1000);
|
// pwm_pin.set_timestamp(1000);
|
||||||
// Timer::after_millis(1000).await;
|
// Timer::after_millis(1000).await;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
rprintln!("Hello world!");
|
rprintln!("Hello world!");
|
||||||
delay.delay_millis(3000);
|
delay.delay_millis(3000);
|
||||||
|
|
|
||||||
56
src/main.py
56
src/main.py
|
|
@ -87,6 +87,7 @@ def fafo():
|
||||||
bgr = f.read(3)
|
bgr = f.read(3)
|
||||||
tft._pushcolor(TFTColor(bgr[2],bgr[1],bgr[0]))
|
tft._pushcolor(TFTColor(bgr[2],bgr[1],bgr[0]))
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
tft.fill(TFT.BLACK)
|
||||||
def tftprinttest():
|
def tftprinttest():
|
||||||
tft.fill(TFT.BLACK)
|
tft.fill(TFT.BLACK)
|
||||||
v = 30
|
v = 30
|
||||||
|
|
@ -132,6 +133,7 @@ def start_view(state, rotary):
|
||||||
#print(rotary.value())
|
#print(rotary.value())
|
||||||
|
|
||||||
def draw_edit_menu(state, rotary):
|
def draw_edit_menu(state, rotary):
|
||||||
|
tft.fill(TFT.BLACK)
|
||||||
display.print("Deposit speed:")
|
display.print("Deposit speed:")
|
||||||
display.print("{: >{w}} RPM".format(config["deposit_rpm"], w=5))
|
display.print("{: >{w}} RPM".format(config["deposit_rpm"], w=5))
|
||||||
display.print("Coating speed:")
|
display.print("Coating speed:")
|
||||||
|
|
@ -160,7 +162,6 @@ def draw_rpm(rpm):
|
||||||
|
|
||||||
|
|
||||||
def deposit_view(state, rotary):
|
def deposit_view(state, rotary):
|
||||||
# display.fill_rect(0, 0, 127, 14, 1)
|
|
||||||
display.print("Deposit")
|
display.print("Deposit")
|
||||||
draw_rpm(state["rpm"])
|
draw_rpm(state["rpm"])
|
||||||
display.print("Press to")
|
display.print("Press to")
|
||||||
|
|
@ -176,6 +177,7 @@ def coating_view(state, rotary):
|
||||||
|
|
||||||
#def decode_ESC_telemetry(data, motor_poles=14):
|
#def decode_ESC_telemetry(data, motor_poles=14):
|
||||||
# if len(data) > 10:
|
# if len(data) > 10:
|
||||||
|
# display.fill_rect(0, 0, 127, 14, 1)
|
||||||
# # use latest telemetry
|
# # use latest telemetry
|
||||||
# data = data[-10:]
|
# data = data[-10:]
|
||||||
#
|
#
|
||||||
|
|
@ -190,13 +192,13 @@ def coating_view(state, rotary):
|
||||||
# erpm = int((data[7] << 8) | data[8]) * 100
|
# erpm = int((data[7] << 8) | data[8]) * 100
|
||||||
# rpm = erpm / (motor_poles / 2)
|
# rpm = erpm / (motor_poles / 2)
|
||||||
# crc = data[9]
|
# crc = data[9]
|
||||||
#
|
|
||||||
# print(" Temp (C):", temperature)
|
# print(" Temp (C):", temperature)
|
||||||
# print(" Voltage (V):", voltage)
|
# print(" Voltage (V):", voltage)
|
||||||
# print(" Current (A):", current)
|
# print(" Current (A):", current)
|
||||||
# print("Consumption (mAh):", consumption)
|
# print("Consumption (mAh):", consumption)
|
||||||
# print(" Erpm:", erpm)
|
# print(" Erpm:", erpm)
|
||||||
# print(" RPM:", rpm)
|
# print(" RPM:", rpm)
|
||||||
|
#
|
||||||
# print(" CRC:", crc)
|
# print(" CRC:", crc)
|
||||||
# print()
|
# print()
|
||||||
#
|
#
|
||||||
|
|
@ -207,7 +209,6 @@ async def update_display():
|
||||||
global state
|
global state
|
||||||
global rotary
|
global rotary
|
||||||
while True:
|
while True:
|
||||||
display.print("LOLOLOL")
|
|
||||||
state["view"](state, rotary)
|
state["view"](state, rotary)
|
||||||
await uasyncio.sleep_ms(200)
|
await uasyncio.sleep_ms(200)
|
||||||
|
|
||||||
|
|
@ -263,7 +264,7 @@ def timer_callback(f):
|
||||||
def kill_me(f):
|
def kill_me(f):
|
||||||
state["target_rpm"] = 0
|
state["target_rpm"] = 0
|
||||||
|
|
||||||
def update_motor_pwm():
|
async def update_motor_pwm():
|
||||||
global timer3
|
global timer3
|
||||||
global current_rpm
|
global current_rpm
|
||||||
pwm = PWM(Pin(26))
|
pwm = PWM(Pin(26))
|
||||||
|
|
@ -279,30 +280,14 @@ def update_motor_pwm():
|
||||||
pwm.freq(50)
|
pwm.freq(50)
|
||||||
|
|
||||||
timer3.init(mode=Timer.PERIODIC, period=100, callback=timer_callback)
|
timer3.init(mode=Timer.PERIODIC, period=100, callback=timer_callback)
|
||||||
pwm.duty_ns(1055*10**3)
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
print((current_rpm*60)/COILS)
|
|
||||||
pwm.duty_ns(1055*10**3)
|
|
||||||
|
|
||||||
#pwm.duty_ns(1200*10**3)
|
|
||||||
#global rpm_counter
|
|
||||||
#rpm_counter= 0
|
|
||||||
#time.sleep(10)
|
|
||||||
|
|
||||||
# time.sleep(10) # keep low signal to arm
|
|
||||||
# # for i in range(1060,1800):
|
|
||||||
# # pwm.duty_u16(i*3)
|
|
||||||
# # time.sleep(1)
|
|
||||||
# pwm.duty_ns(1070*10**3)
|
|
||||||
# pwm.duty_u16(1700)
|
|
||||||
# time.sleep(200)
|
|
||||||
pwm.duty_ns(1060*10**3)
|
pwm.duty_ns(1060*10**3)
|
||||||
state["target_rpm"] = 5000
|
time.sleep(3)
|
||||||
timer2.init(mode=Timer.PERIODIC, period=10000, callback=kill_me)
|
print((current_rpm*60)/COILS)
|
||||||
|
state["target_rpm"] = 4000
|
||||||
|
coating_time = config["coating_time"]*1000
|
||||||
|
timer2.init(mode=Timer.PERIODIC, period=coating_time, callback=kill_me)
|
||||||
|
|
||||||
while(True):
|
while(True):
|
||||||
|
|
||||||
print(f'target RPM:{state["target_rpm"]}')
|
print(f'target RPM:{state["target_rpm"]}')
|
||||||
rpm_pid.setpoint = state["target_rpm"]
|
rpm_pid.setpoint = state["target_rpm"]
|
||||||
|
|
||||||
|
|
@ -323,15 +308,14 @@ def update_motor_pwm():
|
||||||
if state["target_rpm"] == 0:
|
if state["target_rpm"] == 0:
|
||||||
print("Killing Coater!")
|
print("Killing Coater!")
|
||||||
throttle = 0
|
throttle = 0
|
||||||
rpm_pid.reset()
|
|
||||||
#pwm.duty_ns(1800*10**3)
|
|
||||||
#time.sleep(3)
|
|
||||||
#return
|
|
||||||
print(throttle)
|
|
||||||
if throttle !=0:
|
if throttle !=0:
|
||||||
new_duty = 1060+(int(660*throttle))
|
# print(throttle)
|
||||||
|
new_duty = 1055+(int(665*throttle))
|
||||||
|
print(new_duty)
|
||||||
pwm.duty_ns(new_duty*10**3)
|
pwm.duty_ns(new_duty*10**3)
|
||||||
else:
|
else:
|
||||||
|
print("KILLED!")
|
||||||
new_duty = 1055
|
new_duty = 1055
|
||||||
pwm.duty_ns(new_duty*10**3)
|
pwm.duty_ns(new_duty*10**3)
|
||||||
timer2.deinit()
|
timer2.deinit()
|
||||||
|
|
@ -392,7 +376,6 @@ def on_button_press(p):
|
||||||
if state["view"] == edit_coating_rpm_view:
|
if state["view"] == edit_coating_rpm_view:
|
||||||
state["view"] = edit_coating_time_view
|
state["view"] = edit_coating_time_view
|
||||||
rotary.set(
|
rotary.set(
|
||||||
max_val=1000,
|
|
||||||
min_val=0,
|
min_val=0,
|
||||||
max_val=9999,
|
max_val=9999,
|
||||||
range_mode=RotaryIRQ.RANGE_BOUNDED,
|
range_mode=RotaryIRQ.RANGE_BOUNDED,
|
||||||
|
|
@ -521,14 +504,15 @@ tft.fill(TFT.BLACK)
|
||||||
|
|
||||||
# splash()
|
# splash()
|
||||||
fafo()
|
fafo()
|
||||||
|
tft.fill(TFT.BLACK)
|
||||||
# for ff in fonts:
|
# for ff in fonts:
|
||||||
# display.set_font(ff)
|
# display.set_font(ff)
|
||||||
# display.print(text)
|
# display.print(text)
|
||||||
update_motor_pwm()
|
#update_motor_pwm()
|
||||||
event_loop = uasyncio.get_event_loop()
|
event_loop = uasyncio.get_event_loop()
|
||||||
# event_loop.create_task(update_display())
|
event_loop.create_task(update_display())
|
||||||
|
update_display()
|
||||||
# #event_loop.create_task(update_motor_pwm())
|
#event_loop.create_task(update_motor_pwm())
|
||||||
#event_loop.run_forever()
|
#event_loop.run_forever()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue