Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Как прочитать UID RFID-карты с Raspberry Pi Pico во встраиваемом Rust

Теперь, когда проводка готова, перейдём к части с кодом. Будем делать просто: сначала обнаружим RFID-карту и прочитаем её UID. Аутентификацию и доступ к данным пока не рассматриваем.

В этом разделе мы выведем UID с помощью отладочного зонда. Логирование выполняется через defmt, а вывод появляется в консоли компьютера через RTT. Если у вас есть отладочный зонд, это самый простой способ вывести и изучить результат.

Important

В следующем разделе мы прочитаем тот же UID, но выведем его через USB Serial. Это полезно, если у вас нет отладочного зонда и вы хотите выводить данные в системную консоль. Вы не ограничены этими двумя способами. Можно также вывести UID на OLED-экран.

Драйвер mfrc522

Для связи с RFID-считывателем RC522 мы будем использовать крейт mfrc522. Он предоставляет основные функции, необходимые для обнаружения карт и чтения их UID. Крейт ещё находится в разработке, но для возможностей, которые нам нужны в этой главе, его достаточно.

Проект из шаблона

Начнём с создания нового проекта из шаблона.

cargo generate --git https://github.com/ImplFerris/pico2-template.git --tag v0.3.2

Когда появится запрос, введите имя проекта, например «print-uid», и выберите «Embassy» в качестве HAL. Обязательно включите «defmt» для логирования.

Требуемые дополнительные крейты

Добавьте в Cargo.toml необходимые крейты вместе с существующими зависимостями. Набор крейтов зависит от того, как выводятся данные.

mfrc522 = "0.8.0"
embedded-hal-bus = "0.3.0"

Крейт mfrc522 предоставляет драйвер для связи с RFID-считывателем RC522 и отвечает за обнаружение карт и чтение UID. Крейт embedded-hal-bus позволяет совместно использовать шину SPI через обёртку ExclusiveDevice, которая нужна драйверу mfrc522.

Дополнительные импорты

Добавьте эти импорты в файл main.rs:

#![allow(unused)]
fn main() {
// Для SPI
use embassy_rp::spi::Spi;
use embassy_rp::spi;
use embassy_time::Delay;
use embedded_hal_bus::spi::ExclusiveDevice;

// Для вывода CS
use embassy_rp::gpio::{Level, Output};

// Драйвер для MFRC522
use mfrc522::{Mfrc522, comm::blocking::spi::SpiInterface};
}

Настройка SPI для RFID-считывателя

Настроим шину SPI и выводы, подключённые к считывателю. В этом примере используется SPI0:

#![allow(unused)]
fn main() {
let miso = p.PIN_0;
let cs_pin = Output::new(p.PIN_1, Level::High);
let clk = p.PIN_2;
let mosi = p.PIN_3;

let mut config = spi::Config::default();
config.frequency = 1000_000;

let spi_bus = Spi::new_blocking(p.SPI0, clk, mosi, miso, config);
}

Мы настраиваем шину SPI на работу с частотой 1 МГц, что обеспечивает надёжную связь с RFID-считывателем. Вывод выбора микросхемы (chip select) стартует в высоком уровне — это состояние покоя для SPI-устройств.

Получение SpiDevice из шины SPI

Драйвер mfrc522 ожидает SpiDevice, а не «голую» шину SPI. Чтобы создать такое устройство, используем крейт embedded-hal-bus:

#![allow(unused)]
fn main() {
let spi = ExclusiveDevice::new(spi_bus, cs_pin, Delay).expect("Failed to get exclusive device");
}

Мы используем ExclusiveDevice, поскольку в нашей схеме на шине SPI только одно устройство. Эта обёртка объединяет шину SPI и вывод CS, автоматически управляя линией chip select при каждой операции чтения или записи. Параметр задержки обеспечивает контроль времени.

Инициализация mfrc522

Когда устройство SPI готово, можно инициализировать RFID-считыватель.

#![allow(unused)]
fn main() {
let itf = SpiInterface::new(spi);
let mut rfid = Mfrc522::new(itf)
    .init()
    .expect("failed to initialize the RFID reader");
}

Чтение UID и вывод

Главный цикл постоянно проверяет наличие RFID-карт поблизости. Когда карта обнаружена, мы читаем её UID и выводим его:

#![allow(unused)]
fn main() {
loop {
    if let Ok(atqa) = rfid.reqa() {
        if let Ok(uid) = rfid.select(&atqa) {
            defmt::info!("UID: {:02x}", uid.as_bytes());
            Timer::after_millis(500).await;
        }
    }
}
}

Метод reqa отправляет команду Request, чтобы обнаружить карты поблизости. Когда карта отвечает своим ATQA (Answer To Request), мы вызываем select, чтобы выполнить протокол антиколлизии и получить UID. Байты UID форматируются в шестнадцатеричном виде и отправляются через defmt в консоль RTT.

Клонируйте существующий проект

Можно клонировать проект, который я создал, и перейти в папку print-uid.

git clone https://github.com/ImplFerris/pico2-embassy-projects
cd pico2-embassy-projects/rfid/print-uid/

Как запустить?

Не забудьте использовать команду cargo embed --release для прошивки вместо cargo flash --release, если вы используете отладочный зонд. В шаблоне уже настроено открытие RTT при прошивке, поэтому вы должны увидеть вывод defmt.

Теперь поднесите RFID-метку к считывателю. В консоли RTT вы должны увидеть байты UID в шестнадцатеричном формате.

Вывод UID через defmt