M5StackC plusとラズパイ Model B+をつなぐ

いずれMyfareカードリーダーのアプリはラズパイで動かすので、つないでみた。まずはUSBがtype-Aで物理的に接続の簡単なラズパイ Model B+でつないでみます。最初I2Sのオーディオ拡張ボード挿入したままだと電源入らずラズパイも起動しないから、拡張ボードを外すと起動できました。

外部電源が不足か、ラズパイ本体から電力供給できないかのどちらかですが、USB type-Aにはmini-Bの5Vから直接供給しているので外部電源の容量不足のようです。

ラズパイからの見え方は、

$ lsusb
Bus 001 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Device 005が該当で、当然ながらMacで読んだ値と同じで、

port.VID == “0403” && port.PID == “6001”

となります。

他の要因もあるから、Macでクロスコンパイルしたバイナリがそのまま動くかどうか?

 

admin

GolangとNode.jsでmifareカード使ってチェックイン表示

Mifareカードリーダーを使ったチェックインシステムを
GolangとNode.js使って雛形もどきを作ってみた。Node.jsはwebアプリ雛形作成のexpress-generatorを使っています。

GolangでSQLite3のデータベーステーブル作成とアップデート、Node.jsはwebサーバー起動してviewを作成しています。

・index.js:データベースのテーブルから読み出したチェックイン情報を読み出して、ページ(view)の必要情報を用意します。データベース読み込みは非同期処理なので、async/awaitで同期化します。

・index.pug:index.html作成のテンプレートです。pugファイルにはJavaScriptの記述もできて繰り返し処理が簡単にできるから便利です。

・style.css:スタイルシート、本来のディレクトリから一個上の階層に移動してあります。GitHubへの転送がそうしないとうまくできなかったから。

・serial.go:M5StackC plusからのカード読み取り情報を受け取りjsonのuidと名前対応情報から手ブルを作成。テーブル名は年号と1月1日からの経過日を組み合わせたものにしています。

コードは分散していますが以下のリンクから、

https://github.com/chateight/golang/tree/master/serial

P.S. 2023/4/1

Unmarshalは簡単に使えてこのケースなら別に問題もないですが、巨大なファイルになるとメモリ大量に消費するだろうから効率考えたらストリームとして処理するのが良いようです。

 

*_tool.jsはデバッグ用のコードです。

カードリーダーのM5StackC plusのコードなどの情報は、

https://github.com/chateight/rfid

 

admin

M5StackC plusとGolangでシリアル通信する

M5StackC plusからのMyfareカードのUID情報をUSBシリアル使ってGoで受信してみます。

参考は、

https://zenn.dev/nnabeyang/articles/d54f18cc39dc4a654c7a

USBシリアルのVID/PIDをMacBook Airからシステム情報/USBで引くと、以下のように見える。USB経由でファイル(USBストレージ)とシリアルインターフェースが見えるようになっています。

0x403と0x6001を使うが、これでは該当するポートが見つからないと言われる。

VID/PIDを調べるために取得スクリプトを、

https://pkg.go.dev/go.bug.st/serial/enumerator

のexampleから引っ張ってくる。参考までにPortDetails構造体の中身見ると、型が数値ではなく文字列だから16進表記じゃだめです。まあ、元々が文字列じゃないか、

if port.IsUSB {
fmt.Printf("   USB ID     %s:%s\n", port.VID, port.PID)
fmt.Printf("   USB serial %s\n", port.SerialNumber)


-->
   USB ID     0403:6001
   USB serial AD5232ED16
type PortDetails struct {
	Name         string
	IsUSB        bool
	VID          string
	PID          string
	SerialNumber string

	// Product is an OS-dependent string that describes the serial port, it may
	// be not always available and it may be different across OS.
	Product string
}

VID/PIDの文字列をそのまま使って、

package main

import (
	"bufio"
	"errors"
	"fmt"
	"log"
	"os"

	"go.bug.st/serial"
	"go.bug.st/serial/enumerator"
)

func getPortName() (string, error) {
	ports, error := enumerator.GetDetailedPortsList()
	if error != nil {
		return "", error
	}
	for _, port := range ports {
		/*
			if port.IsUSB {
				fmt.Printf("   USB ID     %s:%s\n", port.VID, port.PID)
				fmt.Printf("   USB serial %s\n", port.SerialNumber)
		*/

		if port.IsUSB && port.VID == "0403" && port.PID == "6001" {
			return port.Name, nil
		}
	}
	return "", errors.New("M5Stack cplus is not conntected")
}

func main() {
	portName, err := getPortName()
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	mode := &serial.Mode{
		BaudRate: 115200,
	}
	port, err := serial.Open(portName, mode)
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
	scanner := bufio.NewScanner(port)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}
}

これでちゃんと読めた。

 

admin

Mifare cardでの参加者表示アプリ作成

これを使って、USBシリアル経由でProcessingでカード情報を受け取り、UIDと参加者の対応表からカードをタッチした参加者は出席とSQLiteのテーブルに書き込み、デスクトップ画面に表示をするようなアプリです。

M5Stickc plusとProcessingのコードは以下のリンクから、

https://github.com/chateight/rfid

注意点はserialEvent()は割り込み処理なので、この中で共通リソースを変更すると、他で使用中のコードからは意図しない(不規則な)変更に見えるので、この中では共通リソースの書き込み処理を行ってはいけない。具体的にはdbTableUpdate()の呼び出しをserialEvent()中で行っていたら、draw()からの呼び出し中にString[] membersの配列を破壊してパニックが発生しました。dbTableUpdate()の実行中に配列を書き換えなければ問題ないのでそれで対応。

10人分の登録をしたらこんな画面になります。

 

admin

M5Stickc plus

https://isehara-3lv.sakura.ne.jp/blog/2023/02/17/mifareカードリーダー/

M5StackでRFカードリーダーのアプリ作ろうと思っていましたが、カードリーダー専用ならばM5Stackである必要性はないので、より小型のM5Stickc plusを使ってみました。

サイズの差、

動かしてみたところ、

M5StackとM5Stickc plusにはいくつか差分がありますが、以下はM5Stickc plus用のコードです。

主な違いを列挙すると、

    1. ライブラリは別です、PlatformIO使うときにM5Stack用のソースから書き換えにはplatforio.iniの書き換えが必要です。
    2. 画面はローテーションしないと幅が狭すぎて使いづらいので横方向で使います。
    3. 内蔵の赤LEDをカード読み取り信号として使っています。
    4. 内蔵のブザーも同じ目的で使っています。

5. 電源オンオフは、M5」と書かれたボタンを正面に見て左側にあるボタンを6秒長押しすると電源が切れます。電源ONは同じボタンを押します

    6. リセットは対応するボタンがないので、ネット情報を参考にBボタンに割り当てています。
    7. 本体の取り付けは2mmネジです(現物合わせ)、長すぎると本体を破壊しそうですが、係りはおよそ3mmぐらいです。ネジ穴センター間の距離は実測で15.8mmでした。
    1. -> P.S. たまたま目にした図面によると、ネジ穴センター間の距離は16mmのようです。
/*
to change for the M5stickc-plus 2023/2/23
*******************************************************************************
* Copyright (c) 2022 by M5Stack
*                  Equipped with M5Core sample source code
*                          配套  M5Core 示例源代码
* Visit for more information: https://docs.m5stack.com/en/core/gray
* 获取更多资料请访问: https://docs.m5stack.com/zh_CN/core/gray
*
* Describe: RFID.
* Date: 2021/8/19
*******************************************************************************
  Please connect to Port A(22、21),Use the RFID Unit to read the Fudan card ID
and display the ID on the screen. 请连接端口A(22、21),使用RFID Unit
读取ID卡并在屏幕上显示。
*/

#include <m5stickcplus.h>

#include "MFRC522_I2C.h"

MFRC522 mfrc522(0x28);  // Create MFRC522 instance.  创建MFRC522实例

void setup() {
    M5.begin();             // Init M5Stack.  初始化M5Stack
    //M5.Power.begin();       // Init power  初始化电源模块
    M5.Lcd.setRotation(3);
    M5.lcd.setTextSize(2);  // Set the text size to 2.  设置文字大小为2
    M5.Lcd.println("MFRC522 RFC reader");
    Wire.begin();  // Wire init, adding the I2C bus.  Wire初始化, 加入i2c总线
    Serial.begin(115200);

    mfrc522.PCD_Init();  // Init MFRC522.  初始化 MFRC522
    M5.Lcd.println("Please put the card\n\nUID:");
    // LED port as output & set to "OFF"
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);
}

void loop() {
    // reset by B button push
    if(M5.BtnB.wasPressed()){
        esp_restart();
    }
    M5.update();

    M5.Lcd.setCursor(40, 47);
    if (!mfrc522.PICC_IsNewCardPresent() ||
        !mfrc522.PICC_ReadCardSerial()) {  //如果没有读取到新的卡片
        delay(200);
        return;
    }
    M5.Lcd.fillRect(42, 47, 240, 20, BLACK);
    for (byte i = 0; i < mfrc522.uid.size;
         i++) {  // Output the stored UID data.  将存储的UID数据输出
        M5.Lcd.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
        M5.Lcd.print(mfrc522.uid.uidByte[i], HEX);
        Serial.print(mfrc522.uid.uidByte[i], HEX);
        // beep & LED on for 50ms    
        M5.Beep.tone(880);
        digitalWrite(10, LOW);
        delay(50);
        M5.Beep.mute();
        digitalWrite(10, HIGH);
    }
    M5.Lcd.println("");
    Serial.println("");
}

M5Stackファミリーも後から出てくるハードの方が進化しています。

 

admin