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)