From ee3343e47fc350ec0343f51a5976e4405e93a466 Mon Sep 17 00:00:00 2001 From: gnxlxnxx Date: Fri, 12 Jun 2026 16:22:54 +0200 Subject: [PATCH] Add ADC Measurements with moving average - remove analog reference - output I, Q, TE11, TE21 - add ADC Reference voltage (VDDA) --- src/main.rs | 95 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 29 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9b0387a..5f2ffb4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,10 @@ use pid_control as _; // global logger + panicking-behavior + memory layout // TODO +// - look into adc hold capacity +// - atomic reference for te11 value -> done // - embedded-cli +// -> this would also make the adc stuff less ugly // - average adc samples -> done? // - uart configurable reference -> done // - fix analog reference -> done @@ -17,6 +20,8 @@ use pid_control as _; // global logger + panicking-behavior + memory layout mod app { use defmt::info; + use core::fmt::Write; + use core::sync::atomic::{AtomicU32, Ordering}; use embedded_cli::{Command, cli::CliBuilder, writer::Writer}; use pid_control::ringbuffer::Ringbuffer; use pid_control::uart_parser::Parser; @@ -39,8 +44,12 @@ mod app { const KI: f32 = 0.5; const KD: f32 = 0f32; + const VDDA: f32 = 3.313; + const AVGBUFSIZE: usize = 5000; + static TE11_AVG: AtomicU32 = AtomicU32::new(0); + // Shared resources go here #[shared] struct Shared { @@ -57,14 +66,19 @@ mod app { p: f32, i: f32, d: f32, - reference: Pin<'C', 2, Analog>, + adc_te21: Pin<'C', 0, Analog>, + adc_q: Pin<'C', 1, Analog>, + adc_i: Pin<'C', 2, Analog>, input: Pin<'C', 3, Analog>, adc1: Adc, adc2: Adc, dac: C1, parser: Parser, freq: hal::time::Hertz, - avgbuffer: Ringbuffer, + avgbuffer_i: Ringbuffer<33>, + avgbuffer_q: Ringbuffer<33>, + avgbuffer_te21: Ringbuffer<33>, + avgbuffer_te11: Ringbuffer, } #[init] @@ -91,18 +105,15 @@ mod app { let gpioa = ctx.device.GPIOA.split(ccdr.peripheral.GPIOA); let gpioc = ctx.device.GPIOC.split(ccdr.peripheral.GPIOC); - let reference = gpioc.pc2.into_analog(); + let adc_i = gpioc.pc2.into_analog(); + let adc_q = gpioc.pc1.into_analog(); + let adc_te21 = gpioc.pc0.into_analog(); let input = gpioc.pc3.into_analog(); let output = gpioa.pa4; let tx = gpioa.pa9.into_alternate(); let rx = gpioa.pa10.into_alternate(); - info!( - "reference input: P{}{}", - (reference.port_id() + b'A') as char, - reference.pin_id() - ); info!( "controller input: P{}{}", (input.port_id() + b'A') as char, @@ -150,18 +161,20 @@ mod app { ); let mut adc1 = adc1.enable(); - adc1.set_resolution(adc::Resolution::TwelveBit); + adc1.set_resolution(adc::Resolution::SixteenBit); + adc1.set_sample_time(hal::adc::AdcSampleTime::T_810); let mut adc2 = adc2.enable(); - adc2.set_resolution(adc::Resolution::TwelveBit); + adc2.set_resolution(adc::Resolution::SixteenBit); + // adc2.set_resolution(adc::Resolution::TwelveBit); info!("----------Setup TIM----------"); - let freq = 10.Hz(); + let freq = 10.kHz(); info!("TIM3:"); - info!("\tfreq: {} Hz", freq.to_Hz()); + info!("\tfreq: {} kHz", freq.to_kHz()); - let timer3 = ctx + let mut timer3 = ctx .device .TIM3 .timer(freq, ccdr.peripheral.TIM3, &ccdr.clocks); @@ -178,7 +191,7 @@ mod app { info!("===========init complete=========="); // Enable interrupts - // timer3.listen(Event::TimeOut); // NOTE: comment for digital reference via uart + timer3.listen(Event::TimeOut); timer2.listen(Event::TimeOut); serial.listen(serial::Event::Rxne); @@ -199,11 +212,14 @@ mod app { // .build() // .ok()?; - let target = 0.7 / 3.3 * 4095f32; + let target = 0.7 / VDDA * 4095f32; let averaging = 50; let config = PIDConfig { averaging }; - let avgbuffer = Ringbuffer::new(averaging); + let avgbuffer_i = Ringbuffer::<33>::new(32); + let avgbuffer_q = Ringbuffer::<33>::new(32); + let avgbuffer_te21 = Ringbuffer::<33>::new(32); + let avgbuffer_te11 = Ringbuffer::new(averaging); ( Shared { @@ -212,13 +228,18 @@ mod app { config, }, Local { - avgbuffer, + avgbuffer_te11, + avgbuffer_i, + avgbuffer_q, + avgbuffer_te21, timer3, timer2, p: 0f32, i: 0f32, d: 0f32, - reference, + adc_te21, + adc_q, + adc_i, input, adc1, adc2, @@ -256,11 +277,9 @@ mod app { let parser = ctx.local.parser; ctx.shared.serial.lock(|serial| { - use core::fmt::Write; while serial.is_rxne() { if let Ok(data) = serial.read() { // echo back - let _ = write!(serial, "{}", data as char); // parse incoming byte if let Some(target) = parser.input_byte(data) { @@ -273,31 +292,49 @@ mod app { }); } - #[task(binds = TIM3, local = [timer3, adc1, reference], shared = [target])] - fn adc_target(mut ctx: adc_target::Context) { + #[task(binds = TIM3, local = [timer3, adc1, adc_i, adc_q, adc_te21, avgbuffer_i, avgbuffer_q, avgbuffer_te21], shared = [target, serial])] + fn adc_print(mut ctx: adc_print::Context) { // Clear interrupt flag ctx.local.timer3.clear_irq(); - let target: u32 = ctx.local.adc1.read(ctx.local.reference).unwrap(); // WHY COMPILER WHY - ctx.shared.target.lock(|t| { - *t = target as f32; + ctx.local + .avgbuffer_i + .push(ctx.local.adc1.read(ctx.local.adc_i).unwrap()); + ctx.local + .avgbuffer_q + .push(ctx.local.adc1.read(ctx.local.adc_q).unwrap()); + ctx.local + .avgbuffer_te21 + .push(ctx.local.adc1.read(ctx.local.adc_te21).unwrap()); + + ctx.shared.serial.lock(|serial| { + let _ = writeln!( + serial, + "I: {},\tQ: {},\tTE11: {},\tTE21: {}\r", + ctx.local.avgbuffer_i.average() as f32 * VDDA / u16::MAX as f32, + ctx.local.avgbuffer_q.average() as f32 * VDDA / u16::MAX as f32, + TE11_AVG.load(Ordering::SeqCst) as f32 * VDDA / u16::MAX as f32, + ctx.local.avgbuffer_te21.average() as f32 * VDDA / u16::MAX as f32, + ); }); } // #[task(binds = TIM2, local = [timer2, p, i, d, input, adc2, dac, freq], shared = [target, serial], priority = 1)] - #[task(binds = TIM2, local = [timer2, p, i, d, input, adc2, dac, freq, avgbuffer], shared = [target, config], priority = 1)] + #[task(binds = TIM2, local = [timer2, p, i, d, input, adc2, dac, freq, avgbuffer_te11], shared = [target, config], priority = 1)] fn pid(mut ctx: pid::Context) { // Clear interrupt flag ctx.local.timer2.clear_irq(); // let config: PIDConfig = ctx.shared.config.lock(|c| *c); - let avgbuffer = ctx.local.avgbuffer; - + let avgbuffer = ctx.local.avgbuffer_te11; let t = 1f32 / (ctx.local.freq.to_kHz() as f32); let input: u32 = ctx.local.adc2.read(ctx.local.input).unwrap(); avgbuffer.push(input); // let input: f32 = input as f32; - let input: f32 = avgbuffer.average() as f32; + let input: u32 = avgbuffer.average(); + TE11_AVG.store(input, Ordering::SeqCst); + + let input: f32 = (input >> 4) as f32; let p = ctx.local.p; let i = ctx.local.i;