#![no_std]
#![no_main]
use dht_hal_drv::{
dht_split_init,
dht_split_read,
DhtError,
DhtType,
DhtValue
};
use embedded_graphics::{
mono_font::{
ascii::{FONT_6X10, FONT_9X18_BOLD},
MonoTextStyleBuilder,
},
pixelcolor::BinaryColor,
prelude::*,
text::{Alignment, Text},
primitives::{Circle, PrimitiveStyleBuilder},
};
use esp32_hal::{
clock::ClockControl,
pac::Peripherals,
i2c::I2C,
gpio::IO,
prelude::*,
timer::TimerGroup,
Rtc,
Delay
};
// use Dht;
use esp_backtrace as _;
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
use xtensa_lx_rt::entry;
pub mod write_to {
use core::cmp::min;
use core::fmt;
pub struct WriteTo<'a> {
buffer: &'a mut [u8],
// on write error (i.e. not enough space in buffer) this grows beyond
// `buffer.len()`.
used: usize,
}
impl<'a> WriteTo<'a> {
pub fn new(buffer: &'a mut [u8]) -> Self {
WriteTo { buffer, used: 0 }
}
pub fn as_str(self) -> Option<&'a str> {
if self.used <= self.buffer.len() {
// only successful concats of str - must be a valid str.
use core::str::from_utf8_unchecked;
Some(unsafe { from_utf8_unchecked(&self.buffer[..self.used]) })
} else {
None
}
}
}
impl<'a> fmt::Write for WriteTo<'a> {
fn write_str(&mut self, s: &str) -> fmt::Result {
if self.used > self.buffer.len() {
return Err(fmt::Error);
}
let remaining_buf = &mut self.buffer[self.used..];
let raw_s = s.as_bytes();
let write_num = min(raw_s.len(), remaining_buf.len());
remaining_buf[..write_num].copy_from_slice(&raw_s[..write_num]);
self.used += raw_s.len();
if write_num < raw_s.len() {
Err(fmt::Error)
} else {
Ok(())
}
}
}
pub fn show<'a>(buffer: &'a mut [u8], args: fmt::Arguments) -> Result<&'a str, fmt::Error> {
let mut w = WriteTo::new(buffer);
fmt::write(&mut w, args)?;
w.as_str().ok_or(fmt::Error)
}
}
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();
let mut system = peripherals.DPORT.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
// Disable the RTC and TIMG watchdog timers
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks);
let mut wdt1 = timer_group1.wdt;
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();
// Set GPIO15 as an output, and set its state high initially.
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let mut led = io.pins.gpio15.into_push_pull_output();
// Create a new peripheral object with the described wiring
// and standard I2C clock speed
let i2c = I2C::new(
peripherals.I2C0,
io.pins.gpio32,
io.pins.gpio33,
100u32.kHz(),
&mut system.peripheral_clock_control,
&clocks,
)
.unwrap();
led.set_high().unwrap();
// Initialize the Delay peripheral, and use it to toggle the LED state in a
// loop.
let mut delay = Delay::new(&clocks);
// Initialize display
let interface = I2CDisplayInterface::new(i2c);
let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
.into_buffered_graphics_mode();
display.init().unwrap();
// Specify different text styles
let text_style = MonoTextStyleBuilder::new()
.font(&FONT_9X18_BOLD)
.text_color(BinaryColor::On)
.build();
/*
let fill = PrimitiveStyle::with_fill(BinaryColor::On);
Rectangle::new(Point::new(0, 0), Size::new(16, 16))
.into_styled(fill)
.draw(&mut display)
.unwrap();
*/
// let style = PrimitiveStyleBuilder::new()
// .stroke_width(1)
// .stroke_color(BinaryColor::On)
// .build();
// Circle::new(Point::new(10, 20), 30)
// .into_styled(style)
// .draw(&mut display).unwrap();
// Write buffer to display
// display.flush().unwrap();
// let sensor = Dht::new();
let mut pin_out = io.pins.gpio2.into_push_pull_output();
let mut delay_us = |d| delay.delay_us(d);
// dht_split_init(&mut pin_out, &mut delay_us);
let mut pin_in = pin_out.into_pull_down_input();
let mut readings;
let mut temp: f32;
loop {
display.clear();
pin_out = pin_in.into_push_pull_output();
dht_split_init(&mut pin_out, &mut delay_us);
pin_in = pin_out.into_pull_down_input();
readings = dht_split_read(DhtType::DHT22, &mut pin_in, &mut delay_us);
match readings {
Ok(res) => {
temp = res.temperature();
}
_ => {
temp = 0.0;
}
};
let mut buf = [0u8; 64];
let temps: &str = write_to::show(&mut buf, format_args!("{}", temp) ).unwrap();
Text::with_alignment(
temps,
display.bounding_box().center(),
text_style,
Alignment::Center,
).draw(&mut display).unwrap();
display.flush().unwrap();
led.toggle().unwrap();
// delay.delay_ms(250u32);
}
}