Rustでspi経由でmcp3204からのデータを読み取る

最初このクレートを使おうと思いましたが、

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

カテゴリーRust