diff --git a/pmme-device/rust-version/src/main.rs b/pmme-device/rust-version/src/main.rs index 70dc6e3..f192b6e 100644 --- a/pmme-device/rust-version/src/main.rs +++ b/pmme-device/rust-version/src/main.rs @@ -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::::None, + Option::::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();