send telemetry over UART
This commit is contained in:
parent
e58faf354f
commit
0748cb2517
4 changed files with 50 additions and 10 deletions
|
@ -4,7 +4,7 @@
|
||||||
use nalgebra::Vector3;
|
use nalgebra::Vector3;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
/// Forward, clockwise
|
/// Forward, clockwise
|
||||||
Twist(f32,f32),
|
Twist(f32,f32),
|
||||||
|
@ -18,14 +18,14 @@ pub enum Command {
|
||||||
Disable,
|
Disable,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
enabled: bool,
|
pub enabled: bool,
|
||||||
sensor_data: Option<SensorData>,
|
pub sensor_data: Option<SensorData>,
|
||||||
uptime_micros: u64,
|
pub uptime_micros: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub enum SensorData {
|
pub enum SensorData {
|
||||||
/// degrees per second
|
/// degrees per second
|
||||||
Gyro(Vector3<f32>),
|
Gyro(Vector3<f32>),
|
||||||
|
|
1
southbridge/Cargo.lock
generated
1
southbridge/Cargo.lock
generated
|
@ -1368,6 +1368,7 @@ dependencies = [
|
||||||
"embedded-io-async",
|
"embedded-io-async",
|
||||||
"embedded-storage",
|
"embedded-storage",
|
||||||
"framed 0.4.3 (git+https://git.ank.dev/ank/framed-rs)",
|
"framed 0.4.3 (git+https://git.ank.dev/ank/framed-rs)",
|
||||||
|
"heapless 0.8.0",
|
||||||
"log",
|
"log",
|
||||||
"mpu6050",
|
"mpu6050",
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
|
|
|
@ -30,3 +30,4 @@ serde = { version = "1.0.203", default-features = false, features = ["derive"] }
|
||||||
postcard = "1.0.0"
|
postcard = "1.0.0"
|
||||||
static_cell = "2.1"
|
static_cell = "2.1"
|
||||||
portable-atomic = { version = "1.5", features = ["critical-section"] }
|
portable-atomic = { version = "1.5", features = ["critical-section"] }
|
||||||
|
heapless = "0.8"
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
|
|
||||||
use core::{panic::PanicInfo, sync::atomic::Ordering};
|
use core::{panic::PanicInfo, sync::atomic::Ordering};
|
||||||
|
|
||||||
use common::Command;
|
use common::{Command, Response, SensorData};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::{bind_interrupts, peripherals::{UART0, UART1, USB}, pwm::{self, Pwm}, uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}, usb::Driver};
|
use embassy_rp::{bind_interrupts, peripherals::{UART0, UART1, USB}, pwm::{self, Pwm}, uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx, Config}, usb::Driver};
|
||||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel};
|
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel};
|
||||||
use embassy_time::{with_deadline, with_timeout, Duration, Instant, Timer};
|
use embassy_time::{with_deadline, with_timeout, Duration, Instant, Timer};
|
||||||
|
use embedded_io::Write;
|
||||||
use embedded_io_async::{BufRead, Read};
|
use embedded_io_async::{BufRead, Read};
|
||||||
use framed::{bytes, FRAME_END_SYMBOL};
|
use framed::{bytes, FRAME_END_SYMBOL};
|
||||||
use log::{error, info, trace, warn};
|
use log::{error, info, trace, warn};
|
||||||
|
@ -22,6 +23,7 @@ bind_interrupts!(struct Irqs {
|
||||||
});
|
});
|
||||||
|
|
||||||
pub static COMMANDS: Channel<CriticalSectionRawMutex, Command, 5> = Channel::new();
|
pub static COMMANDS: Channel<CriticalSectionRawMutex, Command, 5> = Channel::new();
|
||||||
|
pub static SENSOR_DATA: Channel<CriticalSectionRawMutex, SensorData, 5> = Channel::new();
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn logger_task(driver: Driver<'static, USB>) {
|
async fn logger_task(driver: Driver<'static, USB>) {
|
||||||
|
@ -59,14 +61,18 @@ async fn main(spawner: Spawner) {
|
||||||
|
|
||||||
let uart = BufferedUart::new(p.UART1, Irqs, p.PIN_20, p.PIN_21, tx_buf, rx_buf, Config::default());
|
let uart = BufferedUart::new(p.UART1, Irqs, p.PIN_20, p.PIN_21, tx_buf, rx_buf, Config::default());
|
||||||
|
|
||||||
let (mut tx,rx) = uart.split();
|
let (tx,rx) = uart.split();
|
||||||
|
|
||||||
spawner.spawn(decoder(rx)).unwrap();
|
spawner.spawn(decoder(rx)).unwrap();
|
||||||
|
|
||||||
let enabled = AtomicBool::new(false);
|
static ENABLED: AtomicBool = AtomicBool::new(false);
|
||||||
|
spawner.spawn(telemetry(tx, &ENABLED)).unwrap();
|
||||||
|
|
||||||
|
let enabled = &ENABLED;
|
||||||
let mut enable_watchdog = Instant::now();
|
let mut enable_watchdog = Instant::now();
|
||||||
let enable_watchdog_time = Duration::from_millis(50);
|
let enable_watchdog_time = Duration::from_millis(50);
|
||||||
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if !enabled.load(Ordering::Acquire) {
|
if !enabled.load(Ordering::Acquire) {
|
||||||
// stop all motors
|
// stop all motors
|
||||||
|
@ -142,6 +148,38 @@ async fn decoder(mut rx: BufferedUartRx<'static, UART1>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Receive data from channel and send it over UART
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn telemetry(mut tx: BufferedUartTx<'static, UART1>, enabled: &'static AtomicBool) {
|
||||||
|
info!("Reading...");
|
||||||
|
let mut codec = framed::bytes::Config::default().to_codec();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let data = with_timeout(Duration::from_millis(20), SENSOR_DATA.receive()).await.ok();
|
||||||
|
|
||||||
|
let packet = Response {
|
||||||
|
enabled: enabled.load(Ordering::Acquire),
|
||||||
|
sensor_data: data,
|
||||||
|
uptime_micros: Instant::now().as_micros(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(serialized) = postcard::to_vec::<_, 1024>(&packet) else {
|
||||||
|
error!("serialization error");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut buf = [0u8; 1024];
|
||||||
|
let Ok(len) = codec.encode_to_slice(&serialized, &mut buf) else {
|
||||||
|
error!("encoding error");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = tx.write_all(&buf[..len]) {
|
||||||
|
error!("transport error {e:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// -1 to 1
|
/// -1 to 1
|
||||||
fn calc_speed(speed: f32) -> u16 {
|
fn calc_speed(speed: f32) -> u16 {
|
||||||
const COUNTS_PER_MS: f32 = 3125.;
|
const COUNTS_PER_MS: f32 = 3125.;
|
||||||
|
|
Loading…
Reference in a new issue