Rust+RaspberryPi Pico でキャラクタディスプレイを描画する

ラズパイ
この記事は約5分で読めます。

よくあるキャラクタディスプレイを描画してみるよ

キャラクタディスプレイ

一般的なグラフィカル液晶と違って文字描画しかできないLCDですね。

多分近いものはこれ

403- 現在メンテナンス中です。

以前Arduinoで使ったことがあります

[Arduino]I2CでLCDを繋げてみる
早速LCDを繋げてみようと思いますArduinoについてきたケーブルって短いし、硬いので取り回しが. . .

今回はArduinoではなくRaspberryPi PicoとRustの組み合わせで動かしてみたいと思います

前回はアドレス検索もしていましたがそのまま使います(多分デフォが0x27だと思う)

配線

今回はI2Cが使えるGPIO16,17を使います

プログラム

#![no_std]
#![no_main]

use defmt::*;
use defmt_rtt as _;
use embedded_hal::delay::DelayNs;
use panic_probe as _;
use rp2040_hal as hal;

use hal::pac;

use hd44780_driver::HD44780; // HD44780 互換 LCD ドライバ
use fugit::RateExtU32;  // ファイルの先頭に追加


#[link_section = ".boot2"]
#[used]
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_GENERIC_03H;

const XTAL_FREQ_HZ: u32 = 12_000_000u32;

#[rp2040_hal::entry]
fn main() -> ! {
    info!("Program start!");
    let mut pac = pac::Peripherals::take().unwrap();

    let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);

    let clocks = hal::clocks::init_clocks_and_plls(
        XTAL_FREQ_HZ,
        pac.XOSC,
        pac.CLOCKS,
        pac.PLL_SYS,
        pac.PLL_USB,
        &mut pac.RESETS,
        &mut watchdog,
    )
    .ok()
    .unwrap();

    let mut timer = rp2040_hal::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks);

    let sio = hal::Sio::new(pac.SIO);

    let pins = hal::gpio::Pins::new(
        pac.IO_BANK0,
        pac.PADS_BANK0,
        sio.gpio_bank0,
        &mut pac.RESETS,
    );


    let sda_pin = pins.gpio16.into_pull_up_input().into_function::<hal::gpio::FunctionI2C>();
    let scl_pin = pins.gpio17.into_pull_up_input().into_function::<hal::gpio::FunctionI2C>();
    
    // I2C0 の初期化(400kHz)
    let i2c = hal::I2C::i2c0(
        pac.I2C0,
        sda_pin,
        scl_pin,
        400_000u32.Hz(),
        &mut pac.RESETS,
        &clocks.system_clock,
    );

    // PCF8574 バックライト付き LCD の I2C アドレス
    let lcd_address = 0x27;

    let mut lcd = HD44780::new_i2c(i2c, lcd_address, &mut timer)
        .unwrap_or_else(|_| core::panic!("LCD init error!"));

    loop {
        timer.delay_ms(2000);

        lcd.clear(&mut timer).unwrap();

        lcd.write_str("Hello, Pico", &mut timer).unwrap();
    
        lcd.set_cursor_pos(40, &mut timer).unwrap();
        lcd.write_str("Rust on RP2040.", &mut timer).unwrap();

        timer.delay_ms(1000);

        lcd.clear(&mut timer).unwrap();

        // test
        lcd.write_bytes(
            &[0x74, 0x65, 0x73, 0x74]
            , &mut timer).unwrap();
        
    }
}

ほとんどが前回の初期化作業と一緒です。

それと必要なクレートを追加します

cargo add hd44780-driver fugit

ドライバーとi2cでの動作速度を指定しているところ(400_000u32.Hz()のHzのところ)の依存ライブラリですね

出力は文字列指定するかバイト列を指定できます

そして動作させるとこちら

良い感じに動きましたね(無駄に4K)

小話

I2CピンのSDA,ACLがどのモードで初期化すれば良いか分からなくて困りました。

それにしてもCursor便利ですねー

エラーの箇所を修正してーと命令(右クリメニュー)すればよしなにプロンプトも作って修正案を出してくれます。
たまにハルシネーションを起こしますがまぁそこは人間側がよしなにしてあげましょう。

次は小さいですが液晶ディスプレイやOLED ディスプレイを動かしてみたいと思います。

 

 

コメント