2024年12月19日 星期四

113 學年度第 1 學期 RFID應用課程 Arduino程式

113 學年度第 1 學期 RFID應用課程 Arduino程式


https://www.mediafire.com/file/zr0h0p3iosq12jw/MFRC522+(2).7z/file

內含修改過後的 MFRC522 程式庫 (原程式有錯誤)


//定義MFRC522 RFID read 與 ESP32 介面 接腳連接Pin assign

/* Wiring RFID RC522 module  

==============================================================

GND     = GND   3.3V    = 3.3V

The following table shows the typical pin layout used:

 *             MFRC522      ESP32     

 *             Reader/PCD             

 * Signal      Pin          Pin         

 * -----------------------------------

 * RST/Reset   RST          GPIO27   

 * SPI SS      SDA(SS)      GPIO5     

 * SPI MOSI    MOSI         GPIO23    

 * SPI MISO    MISO         GPIO19    

 * SPI SCK     SCK          GPIO18    

 *

[1] (1, 2) Configurable, typically defined as RST_PIN in sketch/program.

[2] (1, 2) Configurable, typically defined as SS_PIN in sketch/program.

[3] The SDA pin might be labeled SS on some/older MFRC522 boards

=============================================================

*/

// Wifi 與 MQttClient 程式庫

#include <ArduinoMqttClient.h>

#include <WiFi.h>

//#include "arduino_secrets1.h"


//MFRC522 程式庫

#include <SPI.h>

#include <MFRC522.h>


//GPIO 2 D1 Build in LED


//#define LED 13           //定義LED接腳

int LED = 13;

///////please enter your sensitive data in the Secret tab/arduino_secrets.h

//char ssid[] = "TOTOLINK_A3002MU";    // your network SSID (name)

//char pass[] = "24063173";    // your network password (use for WPA, or use as key for WEP)

// WiFi SSID password , SSID 和密碼進行Wi-Fi 設定 


const char ssid[] = "alex9ufo"; // Enter your Wi-Fi name  修改成自己的wifi ssid

const char pass[] = "alex9981";  // Enter Wi-Fi password  修改成自己的wifi pwd


//char ssid[] = "ASUS_D0";    // your network SSID (name)

//char pass[] = "night_9754";    // your network password (use for WPA, or use as key for WEP)


WiFiClient wifiClient;

MqttClient mqttClient(wifiClient);


const char broker[] = "test.mosquitto.org";

//const char broker[] = "broker.mqtt-dashboard.com";

int        port     = 1883;

String json = "";


const char *SubTopic1 = "alex9ufo/2024/RFID/LED_control";

const char *PubTopic2 = "alex9ufo/2024/RFID/LED_status";

const char *PubTopic3 = "alex9ufo/2024/RFID/RFID_UID";

//const char *PubTopic4 = "alex9ufo/2024/RFID/RFID_PICC";


const char willTopic[] = "alex9ufo/2024/RFID/Starting";

//======================================================

#define RST_PIN      27        // 讀卡機的重置腳位

#define SS_PIN       5        // 晶片選擇腳位

MFRC522 mfrc522(SS_PIN, RST_PIN);    // 建立MFRC522物件

MFRC522::MIFARE_Key key;  // 儲存金鑰

MFRC522::StatusCode status;

//===========================================================

//布林代數 LED狀態 是否連上網路ESP32 ready ?

bool ledState = false;

bool atwork = false;

bool Send = false;  //true

String LEDjson = "";

int Count= 0;

bool Flash = false;  //true

bool Timer = false;  //true


//===========================================================

void onMqttMessage(int messageSize) {

  // we received a message, print out the topic and contents

  Serial.print("Received a message with topic '");

  Serial.print(mqttClient.messageTopic());

  String Topic= mqttClient.messageTopic();

  Serial.print("', duplicate = ");

  Serial.print(mqttClient.messageDup() ? "true" : "false");

  Serial.print(", QoS = ");

  Serial.print(mqttClient.messageQoS());

  Serial.print(", retained = ");

  Serial.print(mqttClient.messageRetain() ? "true" : "false");

  Serial.print("', length ");

  Serial.print(messageSize);

  Serial.println(" bytes:");

  String message="";

  // use the Stream interface to print the contents

  while (mqttClient.available()) {

    //Serial.print((char)mqttClient.read());

    message += (char)mqttClient.read();

  }


  Serial.println(message);

  message.trim();

  Topic.trim();


  if (Topic=="alex9ufo/2024/RFID/LED_control") {

  if (message == "on") {

    digitalWrite(LED, LOW);  // Turn on the LED

    //ledState = true;  //ledState = ture HIGH

    //設定 各個 旗號

    LEDjson ="ON";

    Send = true ;

    Flash = false;

    Timer = false;

    Serial.print("LED =");

    Serial.println(LEDjson);

  }


  if (message == "off" ) {

    digitalWrite(LED, HIGH); // Turn off the LED

    //ledState = false; //ledState = false LOW

    LEDjson ="OFF";

    Send = true ;

    Flash = false;

    Timer = false;

    Serial.print("LED =");

    Serial.println(LEDjson);

  }

  

  if (message == "flash" ) {

    digitalWrite(LED, HIGH); // Turn off the LED

    Flash = true;

    Timer = false;

    Send = true ;  

    LEDjson ="FLASH";

    Serial.print("LED =");

    Serial.println(LEDjson);      

  }


  if (message == "timer" ) {

    digitalWrite(LED, LOW); // Turn off the LED

    Flash = false;

    Timer = true;

    Send = true ;

    LEDjson ="TIMER";

   Count= 11;

    Serial.print("LED =");

    Serial.println(LEDjson);   

  }

  

    Serial.println();

    Serial.println("-----------------------");

  }  


}


//===========================================================

String printHex(byte *buffer, byte bufferSize) {

      String id = "";

      for (byte i = 0; i < bufferSize; i++) {

        id += buffer[i] < 0x10 ? "0" : "";

        id += String(buffer[i], HEX);

        id +=" ";

      }

      return id;

}

//===========================================================

//副程式  setup wifi

void setup_wifi() {

  delay(10);

  // We start by connecting to a WiFi network

  Serial.println();

  Serial.print("Connecting to ");

  Serial.println(ssid);     //print ssid

  WiFi.begin(ssid, pass);  //初始化WiFi 函式庫並回傳目前的網路狀態

  while (WiFi.status() != WL_CONNECTED) {

    delay(500);

    Serial.print(".");

  }   //假設 wifi 未連接 show ………


  Serial.println("");

  Serial.println("WiFi connected");

  Serial.println("IP address: ");

  Serial.println(WiFi.localIP());

}  

//===========================================================

//判斷 旗號Flash , Timer 是否為真

void LED_Message() {

  //判斷 旗號 Flash / timer  是否為真 ? 閃爍 定時

  

  if (Flash){

    digitalWrite(LED, !digitalRead(LED));

    delay(500);

    if (digitalRead(LED))

      ledState = true;

    else

      ledState = false;


  } //(Flash)


  if (Timer) {

    digitalWrite(LED, LOW);

    delay(500);

    if (digitalRead(LED))

      ledState = true;

    else

      ledState = false;


  Count=Count-1;

  if (Count == 0 ){

    Timer=false;

    digitalWrite(LED, HIGH);

    ledState = false;

    }

  } //(Timer)

  

  

  ////判斷 旗號 Send 是否為真 回傳MQTT訊息到MQTT Broker 

  if (Send) {

    // Convert JSON string to character array

    Serial.print("Publish message: ");

    Serial.println(LEDjson);

    LEDjson.trim();


    bool retained = false;

    int qos = 1;

    bool dup = false;

    

    // Publish JSON character array to MQTT topic

    mqttClient.beginMessage(PubTopic2,  LEDjson.length(), retained, qos, dup);  //LED Status

    mqttClient.print(LEDjson);

    mqttClient.endMessage();

    Send = false;    //處理過後 旗號 Send為假

  }


//=========================================================== 

void setup() {

  pinMode(LED, OUTPUT);

  digitalWrite(LED, HIGH);  // Turn off the LED initially

  //Initialize serial and wait for port to open: 

  Serial.begin(115200);   // Initialize serial communications with the PC

  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)

  

  setup_wifi();

  Serial.println("You're connected to the network");

  Serial.println();

  

  String willPayload = "ESP32 Start working....!";

  bool willRetain = true;

  int willQos = 1;


  mqttClient.beginWill(willTopic, willPayload.length(), willRetain, willQos);

  mqttClient.print(willPayload);

  mqttClient.endWill();


  Serial.print("Attempting to connect to the MQTT broker: ");

  Serial.println(broker);


  if (!mqttClient.connect(broker, port)) {

    Serial.print("MQTT connection failed! Error code = ");

    Serial.println(mqttClient.connectError());


    while (1);

  }


  Serial.println("You're connected to the MQTT broker!");

  Serial.println();


  // set the message receive callback

  mqttClient.onMessage(onMqttMessage);

  Serial.print("Subscribing to topic: ");

  Serial.println(SubTopic1);

  // subscribe to a topic

  // the second parameter sets the QoS of the subscription,

  // the the library supports subscribing at QoS 0, 1, or 2

  int subscribeQos = 1;

  mqttClient.subscribe(SubTopic1, subscribeQos);



  Serial.println();

  SPI.begin();      // Init SPI bus

  mfrc522.PCD_Init();   // Init MFRC522

  delay(4);       // Optional delay. Some board do need more time after init to be ready, see Readme

  //mfrc522.PCD_DumpVersionToSerial();  // Show details of PCD - MFRC522 Card Reader details

  Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));

}

//===========================================================

void loop() {

  

  // call poll() regularly to allow the library to receive MQTT messages and

  // send MQTT keep alives which avoids being disconnected by the broker

  mqttClient.poll();

  

  LED_Message();

  // to avoid having delays in loop, we'll use the strategy from BlinkWithoutDelay

  // see: File -> Examples -> 02.Digital -> BlinkWithoutDelay for more info

  unsigned long currentMillis = millis();



 if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {

    

     Serial.println(F("Please scan MIFARE Classic card..."));

    // 確認是否有新卡片

    

    byte *id = mfrc522.uid.uidByte;   // 取得卡片的UID

    byte idSize = mfrc522.uid.size;   // 取得UID的長度

    String Type;

    Serial.print("PICC type: ");      // 顯示卡片類型

    // 根據卡片回應的SAK值(mfrc522.uid.sak)判斷卡片類型

    MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);

    Type= mfrc522.PICC_GetTypeName(piccType);

    Serial.println(mfrc522.PICC_GetTypeName(piccType));


    Serial.print("UID Size: ");       // 顯示卡片的UID長度值

    Serial.println(idSize);

 

    for (byte i = 0; i < idSize; i++) {  // 逐一顯示UID碼

      Serial.print("id[");

      Serial.print(i);

      Serial.print("]: ");

      Serial.println(id[i], HEX);       // 以16進位顯示UID值

    }

    Serial.println();




    json="";

    String json1=printHex(mfrc522.uid.uidByte, mfrc522.uid.size);

    json1.toUpperCase();

    json = json + json1;

    json.trim();


    bool retained = false;

    int qos = 1;

    bool dup = false;


    mqttClient.beginMessage(PubTopic3,  json.length(), retained, qos, dup);

    mqttClient.print(json);

    mqttClient.endMessage();

    

    /*

    json="";

    json = "PICC type: ";

    json =  json + Type;

    json.trim();

    

    retained = false;

    qos = 1;

    dup = false;


    mqttClient.beginMessage(PubTopic4,  json.length(), retained, qos, dup);

    mqttClient.print(json);

    mqttClient.endMessage();

    */



    Serial.println();

    // Dump debug info about the card; PICC_HaltA() is automatically called

    // 令卡片進入停止狀態

    // Dump debug info about the card; PICC_HaltA() is automatically called

    // mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

    

    mfrc522.PICC_HaltA();

    mfrc522.PCD_StopCrypto1(); // stop encryption on PCD

  }

}

////===========================================================

沒有留言:

張貼留言

113 學年度第 1 學期 RFID應用課程 Arduino程式

113 學年度第 1 學期 RFID應用課程 Arduino程式 https://www.mediafire.com/file/zr0h0p3iosq12jw/MFRC522+(2).7z/file 內含修改過後的 MFRC522 程式庫 (原程式有錯誤) //定義MFRC522...