📟 pmme-device: UartDriver now reads PM data from sensor

This commit is contained in:
Joseph Ferano 2025-06-10 18:56:01 +07:00
parent 9e3ae56aa1
commit 8e6fc96e4d

View File

@ -1,14 +1,17 @@
use anyhow::{bail, Result, Context, anyhow};
use anyhow::{Result, anyhow};
use esp_idf_svc::hal::gpio;
use esp_idf_svc::hal::delay::FreeRtos;
use esp_idf_svc::hal::i2c::{I2cConfig, I2cDriver};
use esp_idf_svc::hal::peripherals::Peripherals;
use esp_idf_svc::hal::delay::BLOCK;
use esp_idf_svc::hal::prelude::FromValueType;
use esp_idf_svc::hal::units::Hertz;
use esp_idf_svc::hal::uart::{config, UartDriver};
use embedded_graphics::{
mono_font::{
ascii::{FONT_10X20, FONT_5X8, FONT_6X12, FONT_9X15},
MonoTextStyle, MonoTextStyleBuilder,
ascii::{FONT_10X20},
MonoTextStyle,
},
image::{Image, ImageRaw},
pixelcolor::BinaryColor,
@ -21,9 +24,7 @@ use ssd1306::mode::DisplayConfig;
use std::thread;
use log::info;
const SSD1306_ADDRESS: u8 = 0x3c;
fn oled_task(mut i2c: I2cDriver) -> Result<()> {
fn oled_task(i2c: I2cDriver) -> Result<()> {
info!("Staring OLED Task");
let interface = I2CDisplayInterface::new(i2c);
@ -51,6 +52,43 @@ fn oled_task(mut i2c: I2cDriver) -> Result<()> {
}
}
fn send_pms7003_command(uart: &UartDriver, cmd: u8, datah: u8, datal: u8) -> Result<()> {
let mut command = [0x42u8, 0x4D, cmd, datah, datal, 0, 0];
let mut checksum: u16 = 0;
for i in 0..5 {
checksum += command[i] as u16;
}
command[5] = ((checksum >> 8) & 0xFF) as u8;
command[6] = (checksum & 0xFF) as u8;
uart.write(&command)?;
Ok(())
}
fn pm_sensor_task(uart: &UartDriver) -> Result<()> {
info!("Staring UART PM Sensor Task");
send_pms7003_command(uart, 0xE1, 0x00, 0x00)?;
let mut buf = [0_u8; 32];
loop {
send_pms7003_command(uart, 0xE2, 0x00, 0x00)?;
let len = uart.read(&mut buf, BLOCK)?;
if len > 0 {
info!("Read some bytes! {}", len);
for i in 0..len {
info!("0x{:02x}", buf[i]);
}
} else {
info!("No bytes read");
}
uart.clear_rx()?;
FreeRtos::delay_ms(5000);
}
}
fn main() -> Result<()> {
// It is necessary to call this function once. Otherwise some patches to the runtime
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
@ -69,15 +107,30 @@ fn main() -> Result<()> {
let config = I2cConfig::new().baudrate(100.kHz().into());
let i2c = I2cDriver::new(i2c, sda, scl, &config)?;
let tx = peripherals.pins.gpio17;
let rx = peripherals.pins.gpio16;
let config = config::Config::new().baudrate(Hertz(9600));
let uart = UartDriver::new(
peripherals.uart2,
tx,
rx,
Option::<gpio::Gpio0>::None,
Option::<gpio::Gpio1>::None,
&config,
)?;
let handles = vec! [
thread::spawn(move || {
if let Err(e) = oled_task(i2c) {
log::error!("OLED Task Error: {:?}", e);
}
}),
// thread::spawn(move || {
// }),
thread::spawn(move || {
if let Err(e) = pm_sensor_task(&uart) {
log::error!("PM Sensor Task Error: {:?}", e);
}
}),
];
for h in handles {
h.join().unwrap();