Rust ESP Development boardにはI2Cで接続できる温湿度センサ(SHTC3)が搭載されているのでこれにアクセスしてみる
I2Cサンプルは以下
esp-idf-hal/i2c_ssd1306.rs at master · esp-rs/esp-idf-hal · GitHub
作ったソースは以下
use log::*; use esp_idf_hal::delay::{FreeRtos, BLOCK}; use esp_idf_hal::i2c::*; use esp_idf_hal::peripherals::Peripherals; use esp_idf_hal::prelude::*; fn main() -> anyhow::Result<()> { esp_idf_sys::link_patches(); esp_idf_svc::log::EspLogger::initialize_default(); info!("Hello, world!"); let peripherals = Peripherals::take().unwrap(); let i2c = peripherals.i2c0; let sda = peripherals.pins.gpio10; let scl = peripherals.pins.gpio8; let config = I2cConfig::new().baudrate(5.kHz().into()); let mut i2c = I2cDriver::new(i2c, sda, scl, &config)?; // wake up i2c.write(0x70, &[0x35, 0x17], BLOCK)?; // read temp i2c.write(0x70, &[0x78, 0x66], BLOCK)?; let buf = &mut[0u8; 6]; loop{ _ = i2c.read(0x70, buf, 10); for n in 0..6 { print!("[{:x}]",buf[n]); } println!("\n"); let temp = -45.0 + 175.0 * (((buf[0] as i32) << 8 | (buf[1] as i32)) as f32) / (0x10000 as f32); println!("temp:{}", temp); FreeRtos::delay_ms(1000); } }
出力結果は以下
[0][0][0][0][0][0] temp:-45 [6a][a4][2][62][85][82] temp:27.898865 [6a][a4][2][62][85][82] temp:27.898865 [6a][a4][2][62][85][82] temp:27.898865
試作していて分かり切らない点
- i2c0の0って何か? I2CのHWチャンネルか?
- 関数最後の?とは何か? error handlingだったような
- [xx]は配列だとして、&[xx]はアドレスか??
- anyhowはエラーと値を渡すマクロ?だったように覚えているが詳細忘れた
今後の取り組み:
SPIバスは試していないが、I2Cと同様の方法で制御できると期待して、次はWi-Fi接続、MQTT通信に移りたい。
■雑感
Python/MicroPythonは言語仕様がシンプルでREPLも使えて気楽に試せるけど、Rustはコンパイル言語なので試行錯誤はあまりできない。勉強途中なので細かい仕様は分かり切らない。だけど、Rustでコードを書いていると、なんかシビレル。なぜシビレルのか分からないが。
■参考URL
GitHub - esp-rs/esp-rust-board: Open Hardware with ESP32-C3 compatible with Feather specification designed in KiCad
ESP Rust Board上の温湿度センサの値を読む - chakokuのブログ(rev4)