最初このクレートを使おうと思いましたが、
https://github.com/trashware/mcp3xxx-rs
開発が5年前で、かなり古くて依存先のrppalの版数が0.11.0までになってます、rppalではspi経由のデータやり取りはコマンドストリームの送信と結果のストリームが全二重で処理できるから、別に直接ビット列を用意すればクレート使わなくても良いわけで、最終的に以下のコードで読み取りできました
Cargo.tomlではrppalは最新版を指定しています
use rppal::spi::{Bus, Mode, SlaveSelect, Spi};
use std::thread;
use std::time::Duration;
const CHANNEL_0: u8 = 0x06 | 0x00; // Command byte for single-ended mode
fn main() {
// Create a SPI object
let spi = Spi::new(Bus::Spi0, SlaveSelect::Ss0, 1_000_000, Mode::Mode0).unwrap();
// Define the buffers for reading and writing
let mut read_buffer = [0u8; 3];
let write_buffer = [CHANNEL_0, 0x00, 0x00];
// Poll the sensor every n seconds
let poll_rate = Duration::from_secs(1);
loop {
// Perform the SPI transfer
spi.transfer(&mut read_buffer, &write_buffer).unwrap();
// Extract the 12-bit ADC value
// Note: MCP3204 returns 12-bit data, but the second byte contains status bit(0) and the MSB of the result.
let msb = (read_buffer[1] & 0x0F) as u16;
let lsb = read_buffer[2] as u16; // Convert third byte to u16
let result = (msb << 8) | lsb;
println!("Sensor value: {}", result);
println!("{:08b}, {:08b}", read_buffer[1], read_buffer[2]);
thread::sleep(poll_rate);
}
}
[dependencies]
rppal = "0.19.0"
spi上のストリーム情報はデバイスの仕様から、SGLモードを使うので1バイト目にはstartビットと合わせて6を指定すれば良いことになります
コードサンプルではch0の読み取りを行なってますが、このビット列を変更することで他のチャネル情報も取得できます
以下は実行した時の様子
$ ./adc_rppal
Sensor value: 2867
00001011, 00110011
Sensor value: 2867
00001011, 00110011
Sensor value: 2867
00001011, 00110011
Sensor value: 2867
00001011, 00110011
Sensor value: 2868
00001011, 00110100
admin