Working with sh1106 module to display temp and some averaging
This commit is contained in:
15
Cargo.lock
generated
15
Cargo.lock
generated
@@ -339,6 +339,7 @@ dependencies = [
|
||||
"panic-probe",
|
||||
"rp2040-boot2",
|
||||
"rp2040-hal",
|
||||
"sh1106-pico-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -516,6 +517,20 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "sh1106-pico-rs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cortex-m",
|
||||
"cortex-m-rt",
|
||||
"defmt",
|
||||
"defmt-rtt",
|
||||
"embedded-hal 1.0.0",
|
||||
"panic-probe",
|
||||
"rp2040-boot2",
|
||||
"rp2040-hal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.1"
|
||||
|
||||
@@ -13,6 +13,7 @@ embedded_hal_0_2 = {package = "embedded-hal", version = "0.2.5", features = ["un
|
||||
panic-probe = { version = "1.0.0", features = [ "print-rtt" ]}
|
||||
rp2040-boot2 = "0.3.0"
|
||||
rp2040-hal = "0.11.0"
|
||||
sh1106-pico-rs = { path = "../sh1106-pico-rs" }
|
||||
|
||||
[features]
|
||||
logging = []
|
||||
148
src/main.rs
148
src/main.rs
@@ -21,11 +21,13 @@ use rp2040_hal as hal;
|
||||
// A shorter alias for the Peripheral Access Crate, which provides low-level
|
||||
// register access
|
||||
use hal::pac;
|
||||
use hal::fugit::RateExtU32;
|
||||
|
||||
use sh1106_pico_rs::{sh1106::SH1106Dev, graphics::GraphicsBuf};
|
||||
|
||||
// Some traits we need
|
||||
use embedded_hal::delay::DelayNs;
|
||||
use embedded_hal::digital::OutputPin;
|
||||
use embedded_hal_0_2::adc::OneShot;
|
||||
use embedded_hal_0_2::{adc::OneShot, digital::v2::ToggleableOutputPin};
|
||||
|
||||
/// The linker will place this boot block at the start of our program image. We
|
||||
/// need this to help the ROM bootloader get our code up and running.
|
||||
@@ -57,6 +59,7 @@ const SIXTY_C: u16 = 3200;
|
||||
fn main() -> ! {
|
||||
// Grab our singleton objects
|
||||
let mut pac = pac::Peripherals::take().unwrap();
|
||||
let core = pac::CorePeripherals::take().unwrap();
|
||||
|
||||
// Set up the watchdog driver - needed by the clock setup code
|
||||
let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);
|
||||
@@ -73,8 +76,7 @@ fn main() -> ! {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut timer = rp2040_hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks);
|
||||
|
||||
let mut delay = cortex_m::delay::Delay::new(core.SYST, 133_000_000u32);
|
||||
// The single-cycle I/O block controls our GPIO pins
|
||||
let sio = hal::Sio::new(pac.SIO);
|
||||
|
||||
@@ -88,22 +90,82 @@ fn main() -> ! {
|
||||
|
||||
// Configure GPIO25 as an output
|
||||
let mut led_pin = pins.gpio25.into_push_pull_output();
|
||||
led_pin.set_high().unwrap();
|
||||
|
||||
let mut adc = hal::Adc::new(pac.ADC, &mut pac.RESETS);
|
||||
|
||||
let mut adc_pin = hal::adc::AdcPin::new(pins.gpio26).unwrap();
|
||||
let mut adc_pin = hal::adc::AdcPin::new(pins.gpio26.into_pull_down_input()).unwrap();
|
||||
|
||||
adc.free_running(&adc_pin);
|
||||
let mut adc_fifo = adc.build_fifo().clock_divider(40000, 0).set_channel(&mut adc_pin).start();
|
||||
// adc.free_running(&adc_pin);
|
||||
|
||||
let mut adc_samps = [0u16;30];
|
||||
let mut adc_samp_i = 0usize;
|
||||
|
||||
let mut test_val = 0u16;
|
||||
|
||||
loop {
|
||||
led_pin.set_high().unwrap();
|
||||
timer.delay_ms(300);
|
||||
// Create the I²C drive
|
||||
let mut i2c = hal::I2C::i2c0(
|
||||
pac.I2C0,
|
||||
pins.gpio8.reconfigure(),
|
||||
pins.gpio9.reconfigure(),
|
||||
400.kHz(),
|
||||
&mut pac.RESETS,
|
||||
&clocks.system_clock,
|
||||
);
|
||||
|
||||
let sh1106_dev = SH1106Dev::new(&mut delay, &mut i2c);
|
||||
let mut gfx_buf = GraphicsBuf::new();
|
||||
|
||||
println!("Graphics ready");
|
||||
led_pin.set_low().unwrap();
|
||||
timer.delay_ms(300);
|
||||
let adc_val = adc.read(&mut adc_pin).unwrap();
|
||||
println!("ADC {=u16}, samp {=u16}", adc_val, test_val);
|
||||
|
||||
loop {
|
||||
gfx_buf.clear();
|
||||
|
||||
println!("{} samples", adc_fifo.len());
|
||||
for _ in 0..adc_fifo.len() {
|
||||
adc_samps[adc_samp_i] = adc_fifo.read();
|
||||
adc_samp_i += 1;
|
||||
if adc_samp_i >= 30 {
|
||||
adc_samp_i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
let mut adc_hi = 0u16;
|
||||
let mut adc_lo = 0xFFFFu16;
|
||||
|
||||
adc_samps.iter().for_each(|v| {
|
||||
if adc_hi < *v {
|
||||
adc_hi = *v;
|
||||
}
|
||||
if adc_lo > *v {
|
||||
adc_lo = *v;
|
||||
}
|
||||
});
|
||||
|
||||
let mut accepted_samps = 0u32;
|
||||
let mut adc_avg = 0u32;
|
||||
|
||||
adc_samps.iter().for_each(|v| {
|
||||
if *v >= adc_hi {
|
||||
return;
|
||||
}
|
||||
if *v <= adc_lo {
|
||||
return;
|
||||
}
|
||||
accepted_samps += 1;
|
||||
adc_avg += *v as u32;
|
||||
});
|
||||
|
||||
if accepted_samps < 10 {
|
||||
println!("Not enough accepted samples, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
let adc_val = (adc_avg / accepted_samps) as u16;
|
||||
|
||||
println!("ADC {=u16}, samps {}", adc_val, accepted_samps);
|
||||
|
||||
let deg = match adc_val {
|
||||
..ZERO_DEG_C => 0f32,
|
||||
@@ -118,12 +180,66 @@ fn main() -> ! {
|
||||
};
|
||||
|
||||
let deg = (deg * 10.) as u32;
|
||||
let deg = (deg as f32) / 10.;
|
||||
let mut itoa_result = itoa(deg);
|
||||
|
||||
println!("Deg? {=f32}", deg);
|
||||
|
||||
test_val += 1;
|
||||
let deg_buf = &mut itoa_result.buf;
|
||||
for i in 1..10usize {
|
||||
deg_buf[i-1] = deg_buf[i];
|
||||
}
|
||||
|
||||
deg_buf[9] = b'.';
|
||||
itoa_result.len += 1;
|
||||
|
||||
let deg_str = itoa_result.as_str();
|
||||
|
||||
println!("tenths of a deg {}, deg {}", deg, deg_str);
|
||||
gfx_buf.draw_textfield(10, 10, 100, 60, deg_str);
|
||||
|
||||
gfx_buf.sprites[0].y = 40 + ((test_val as i32) / 4) % 2;
|
||||
|
||||
gfx_buf.redraw();
|
||||
sh1106_dev.blit_framebuffer(&mut i2c, &mut gfx_buf);
|
||||
|
||||
test_val = test_val.wrapping_add(1);
|
||||
delay.delay_ms(30);
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
||||
// Can't return str without a ref to a lifetime somewhere else,
|
||||
// so instead return a buffer of the maximum i32 length
|
||||
pub struct ItoaResult {
|
||||
pub buf: [u8; 11],
|
||||
pub len: usize,
|
||||
}
|
||||
|
||||
impl ItoaResult {
|
||||
pub fn new() -> Self {
|
||||
Self { buf: [0u8; 11], len: 0 }
|
||||
}
|
||||
|
||||
fn push(&mut self, c: u8) {
|
||||
self.len += 1;
|
||||
self.buf[11usize.checked_sub(self.len).unwrap()] = c;
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &str {
|
||||
core::str::from_utf8(&self.buf[11usize.checked_sub(self.len).unwrap()..]).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn itoa(mut value: u32) -> ItoaResult {
|
||||
let mut result = ItoaResult::new();
|
||||
|
||||
loop {
|
||||
result.push(b'0' + u8::try_from(value % 10).unwrap());
|
||||
value /= 10;
|
||||
// check at end of loop, so 0 prints to "0"
|
||||
if value == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user