1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RaspberryPi + PN532 NFC RFID module + Waveshare C プログラムを使って Mifare を読む

Last updated at Posted at 2022-03-24

(Felica/Mifare/NFC チャレンジシリーズ) その他の記事はこちら 「Felica/Mifare/NFC でいろいろ実験」
https://qiita.com/nanbuwks/items/1f416d6e45a87250ee0a


「RaspberryPi + PN532 NFC RFID module + Waveshare Python プログラムを使って Mifare を読む」
https://qiita.com/nanbuwks/items/ccc5c89f8f22d7249d16

では Waveshare の PN532HAT 用ライブラリを、PN532 NFC RFID module で使ってみました。

Waveshare ライブラリは、 Arduino , Raspberry Pi , STM32 用に提供されています。Raspberry Pi 用には Python と C が用意され、先の記事は Python で試したものでした。

今回は C で試してみます。

ライセンス

先に試した RaspberryPi 用の Python ライブラリは MIT ライセンスでしたが、その他のものは BSD ライセンスらしいです。

環境

また、Raspberry Pi 3 でも同様に利用できることが確認できました。

インストール

「RaspberryPi + PN532 NFC RFID module + Waveshare Python プログラムを使って Mifare を読む」
https://qiita.com/nanbuwks/items/ccc5c89f8f22d7249d16

の記事の通り行っています。ライブラリ自体はダウンロードして展開するだけですが、Raspberry Pi 上で C のライブラリを使うには WiringPi をインストールしておく必要がありました。以下の記事の通りインストールしています。

「WiringPi インストール方法」
https://qiita.com/nanbuwks/items/f70005772133bf54f4d3

この記事上の 「2.52のインストール」のとおり行いました。

waveshare/raspberrypi/c/examples

には、以下のサンプルがあります。


-rw-r--r-- 1 pi pi  369 Jun 29  2019 Makefile
-rw-r--r-- 1 pi pi 1.9K Jul 10  2019 rpi_dump_mifare.c
-rw-r--r-- 1 pi pi 1.6K Jul 10  2019 rpi_dump_ntag2.c
-rw-r--r-- 1 pi pi 1.1K Jul 10  2019 rpi_get_uid.c
-rw-r--r-- 1 pi pi  954 Jul 10  2019 rpi_read_gpio.c
-rw-r--r-- 1 pi pi 2.7K Jul 10  2019 rpi_rw_mifare.c
-rw-r--r-- 1 pi pi 1.9K Jul 10  2019 rpi_rw_ntag2.c
-rw-r--r-- 1 pi pi 1.4K Jul 10  2019 rpi_write_gpio.c

make すると、


$ make
make: *** No rule to make target '../../pn532.c', needed by 'pn532.o'.  Stop.

Makefile が不適切らしいです。


CC = gcc
DLIBS = -lwiringPi
INC_DIR = ../../
SRCS = $(wildcard *.c)
all: $(SRCS:.c=.exe)
.PHONY: clean
%.exe: %.o pn532.o pn532_rpi.o
	$(CC) -Wall -o $@ $^ $(DLIBS)
%.o: %.c
	$(CC) -Wall -c $^ $(DLIBS) -I$(INC_DIR)
pn532.o pn532_rpi.o: $(INC_DIR)pn532.c $(INC_DIR)pn532_rpi.c
	$(CC) -Wall -c $(INC_DIR)pn532.c
	$(CC) -Wall -c $(INC_DIR)pn532_rpi.c
clean:
	rm *.o *.exe

となっているのを書き直します。


INC_DIR = ../../


INC_DIR = ../

$ make

すると実行ファイルができました。


drwx------ 2 pi pi 4.0K Mar 24 14:39 .
drwx------ 3 pi pi 4.0K Mar 23 10:04 ..
-rw-r--r-- 1 pi pi  366 Mar 24 14:39 Makefile
-rw-r--r-- 1 pi pi 6.6K Mar 24 14:39 pn532.o
-rw-r--r-- 1 pi pi 7.2K Mar 24 14:39 pn532_rpi.o
-rw-r--r-- 1 pi pi 1.9K Jul 10  2019 rpi_dump_mifare.c
-rwxr-xr-x 1 pi pi  19K Mar 24 14:39 rpi_dump_mifare.exe
-rw-r--r-- 1 pi pi 1.6K Jul 10  2019 rpi_dump_ntag2.c
-rwxr-xr-x 1 pi pi  19K Mar 24 14:39 rpi_dump_ntag2.exe
-rwxr-xr-x 1 pi pi  19K Mar 22 09:15 rpi_get_uid
-rw-r--r-- 1 pi pi 1.1K Mar 22 09:11 rpi_get_uid.c
-rwxr-xr-x 1 pi pi  19K Mar 24 14:39 rpi_get_uid.exe
-rw-r--r-- 1 pi pi  954 Jul 10  2019 rpi_read_gpio.c
-rwxr-xr-x 1 pi pi  19K Mar 24 14:39 rpi_read_gpio.exe
-rw-r--r-- 1 pi pi 2.7K Mar 22 08:30 rpi_rw_mifare.c
-rwxr-xr-x 1 pi pi  23K Mar 24 14:39 rpi_rw_mifare.exe
-rw-r--r-- 1 pi pi 1.9K Jul 10  2019 rpi_rw_ntag2.c
-rwxr-xr-x 1 pi pi  23K Mar 24 14:39 rpi_rw_ntag2.exe
-rw-r--r-- 1 pi pi 1.4K Jul 10  2019 rpi_write_gpio.c
-rwxr-xr-x 1 pi pi  19K Mar 24 14:39 rpi_write_gpio.exe

実行ファイルが .exe となっているのが気持ち悪いですが、実行してみます。


$ ./rpi_rw_mifare.exe
Hello!
Failed to detect the PN532

と出たので、 rpi_rw_mifare.c を書き換えます。


    //PN532_SPI_Init(&pn532);
    PN532_I2C_Init(&pn532);
    //PN532_UART_Init(&pn532);

となっているのを、UARTに変更しました。


    //PN532_SPI_Init(&pn532);
    //PN532_I2C_Init(&pn532);
    PN532_UART_Init(&pn532);

UARTのポートは ../pn532_raspi.c で指定されています。


    fd = serialOpen("/dev/ttyS0", 115200);

となっているので RaspberryPi3より前のモデルを使っている場合は
/dev/ttyAMA0 に変更します。

再度make してから、実行します。


$ ./rpi_rw_mifare.exe
Hello!
Found PN532 with firmware version: 1.6
Waiting for RFID/NFC card...
...................................

Found card with UID: f3 3c 53 1c 
Write block 6 successfully

書き込めたみたいです。

プログラム作ってみる

rpi_rw_mifare.c を書き換えて、特定のセクターをキー付きで読むプログラムを作ってみます。


/**
  * This example shows connecting to the PN532 and writing an Mifare Classic
  * type RFID tag
  */
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include "pn532.h"
#include "pn532_rpi.h"

int main(int argc, char** argv) {
    uint8_t buff[255];
    uint8_t uid[MIFARE_UID_MAX_LENGTH];
    uint8_t key_a[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    uint32_t pn532_error = PN532_ERROR_NONE;
    int32_t uid_len = 0;
//    printf("Hello!\n");
    PN532 pn532;
    //PN532_SPI_Init(&pn532);
    //PN532_I2C_Init(&pn532);
    PN532_UART_Init(&pn532);
    if (PN532_GetFirmwareVersion(&pn532, buff) == PN532_STATUS_OK) {
      printf("Found PN532 with firmware version: %d.%d\n", buff[1], buff[2]);
    } else {
        return -1;
    }
    PN532_SamConfiguration(&pn532);
    printf("Waiting for RFID/NFC card...\n");
    while (1)
    {

        // Check if a card is available to read
        uid_len = PN532_ReadPassiveTarget(&pn532, uid, PN532_MIFARE_ISO14443A, 1000);
        if (uid_len == PN532_STATUS_ERROR) {
            printf(".");
            fflush(stdout);
        } else {
            printf("Found card with UID: "); 
            for (uint8_t i = 0; i < uid_len; i++) {
                printf("%02x ", uid[i]);
            }
            printf("\n");
            break;
        }
    }
    //  read block #5 
    uint8_t block_number = 5;
    uint8_t DATA[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    pn532_error = PN532_MifareClassicAuthenticateBlock(&pn532, uid, uid_len,
            block_number, MIFARE_CMD_AUTH_A, key_a);
    if (pn532_error) {
        printf("Error: 0x%02x\n", pn532_error);
        return -1;
    }
    pn532_error = PN532_MifareClassicReadBlock(&pn532, DATA, block_number);
    if (pn532_error) {
        printf("Error: 0x%02x\n", pn532_error);
        return -1;
    }
    DATA[10]=0;
    printf("data= ");
    for (uint8_t i = 0; i < sizeof(DATA); i++) {
            printf("%02X ", DATA[i]);
    }
    printf("\n");
    // printf("%s\n", DATA);
}


コンパイルは手作業でやってみました。


$ cc read5withkey.c ../pn532.c ../pn532_rpi.c -I../ -lwiringPi -o read5withkey 

実行してみます

 $ ./read5withkey
Found PN532 with firmware version: 1.6
Waiting for RFID/NFC card...
....Found card with UID: 53 e6 64 1c 
data= 00 01 02 03 04 05 06 07 08 00 00 00 00 00 00 00 

感想

今回、 Python と C で使ってみましたが低レイヤのプログラムはやはりCが直感的に書けた感があります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?