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 serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum Command {
|
||||
/// Forward, clockwise
|
||||
Twist(f32,f32),
|
||||
|
@ -18,14 +18,14 @@ pub enum Command {
|
|||
Disable,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Response {
|
||||
enabled: bool,
|
||||
sensor_data: Option<SensorData>,
|
||||
uptime_micros: u64,
|
||||
pub enabled: bool,
|
||||
pub sensor_data: Option<SensorData>,
|
||||
pub uptime_micros: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum SensorData {
|
||||
/// degrees per second
|
||||
Gyro(Vector3<f32>),
|
||||
|
|
1
southbridge/Cargo.lock
generated
1
southbridge/Cargo.lock
generated
|
@ -1368,6 +1368,7 @@ dependencies = [
|
|||
"embedded-io-async",
|
||||
"embedded-storage",
|
||||
"framed 0.4.3 (git+https://git.ank.dev/ank/framed-rs)",
|
||||
"heapless 0.8.0",
|
||||
"log",
|
||||
"mpu6050",
|
||||
"nalgebra",
|
||||
|
|
|
@ -30,3 +30,4 @@ serde = { version = "1.0.203", default-features = false, features = ["derive"] }
|
|||
postcard = "1.0.0"
|
||||
static_cell = "2.1"
|
||||
portable-atomic = { version = "1.5", features = ["critical-section"] }
|
||||
heapless = "0.8"
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
|
||||
use core::{panic::PanicInfo, sync::atomic::Ordering};
|
||||
|
||||
use common::Command;
|
||||
use common::{Command, Response, SensorData};
|
||||
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_time::{with_deadline, with_timeout, Duration, Instant, Timer};
|
||||
use embedded_io::Write;
|
||||
use embedded_io_async::{BufRead, Read};
|
||||
use framed::{bytes, FRAME_END_SYMBOL};
|
||||
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 SENSOR_DATA: Channel<CriticalSectionRawMutex, SensorData, 5> = Channel::new();
|
||||
|
||||
#[embassy_executor::task]
|
||||
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 (mut tx,rx) = uart.split();
|
||||
let (tx,rx) = uart.split();
|
||||
|
||||
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 enable_watchdog_time = Duration::from_millis(50);
|
||||
|
||||
|
||||
loop {
|
||||
if !enabled.load(Ordering::Acquire) {
|
||||
// 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
|
||||
fn calc_speed(speed: f32) -> u16 {
|
||||
const COUNTS_PER_MS: f32 = 3125.;
|
||||
|
|
Loading…
Reference in a new issue