2023年11月13日 星期一

作業 2 的 Arduino 程式 (含作業2-1 , 2-2 , 2-3 )

 作業 2 的 Arduino 程式 (含作業2-1 , 2-2 , 2-3 )

1) Arduino 2.2.1 版本

2) ESP32 ,  ESP32 Dev Module 

3)  MQTT 相關資料

// MQTT Broker
const char *mqtt_broker = "broker.mqtt-dashboard.com";
const char *topic1 = "alex9ufo/esp32/led";
const char *topic2 = "alex9ufo/esp32/RFID";
const char *topic = "alex9ufo/esp32/Starting";
const char *topic3 = "alex9ufo/esp32/led_status";

const char *mqtt_username = "alex9ufo";
const char *mqtt_password = "public";
const int mqtt_port = 1883;

4) 系統圖

5) MFRC522 編譯錯誤需修改

C:\Users\User\OneDrive\文件\Arduino\libraries\MFRC522\src\MFRC522Extended.cpp

將824 與 847 的 修改成

if (backData && (backLen > (byte *) 0))

     


 

6) Arduino 程式


//wifi &  MQTT
#include <WiFi.h>
#include <PubSubClient.h>

//RC522 SPI Mode
#include <SPI.h>
#include <MFRC522.h>

//GPIO 2 D1 Build in LED
#define LED 2

/* Wiring RFID RC522 module
=============================================================================
GND     = GND   3.3V    = 3.3V
The following table shows the typical pin layout used:
 *             MFRC522      ESP32     Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD             Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin       Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          GPIO27    9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      GPIO5     10            53        D10        10               10
 * SPI MOSI    MOSI         GPIO23    11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         GPIO19    12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          GPIO18    13 / ICSP-3   52        D13        ICSP-3           15
 *
[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
=============================================================================
*/

#define SS_PIN  5  // ESP32 pin GIOP5
#define RST_PIN 27 // ESP32 pin GIOP27


// WiFi
const char *ssid = "alex9ufo"; // Enter your Wi-Fi name
const char *password = "alex9981";  // Enter Wi-Fi password

// MQTT Broker
const char *mqtt_broker = "broker.mqtt-dashboard.com";
const char *topic1 = "alex9ufo/esp32/led";
const char *topic2 = "alex9ufo/esp32/RFID";
const char *topic = "alex9ufo/esp32/Starting";
const char *topic3 = "alex9ufo/esp32/led_status";

const char *mqtt_username = "alex9ufo";
const char *mqtt_password = "public";
const int mqtt_port = 1883;

bool ledState = false;
bool atwork = false;


WiFiClient espClient;
PubSubClient client(espClient);
MFRC522 rfid(SS_PIN, RST_PIN); // Create MFRC522 instance

long lastMsg = 0;
long lastMsg1= 0;

char msg[50];
String json = "";
bool Flash = false;  //true
bool Timer = false;  //true
bool Send = false;  //true
int Count= 0;

char jsonChar1[50];  //client.publish("alex9ufo/Esp32/RFID"
//宣告任務Task1
TaskHandle_t Task1;

// Wifi reconnect
unsigned long previousMillis = 0;
unsigned long interval = 30000;
//===========================================================
//任務1副程式Task1_senddata
void Task1_senddata(void * pvParameters ) {
  //無窮迴圈
  for (;;) {
    //偵測上傳旗標是否為true
    Serial.println("Reading RFID tag");
    if (rfid.PICC_IsNewCardPresent()) { // new tag is available
      if (rfid.PICC_ReadCardSerial()) { // NUID has been readed
        MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
        Serial.print("RFID/NFC Tag Type: ");
        Serial.println(rfid.PICC_GetTypeName(piccType));
        String rfidno="";
        // print UID in Serial Monitor in the hex format
        Serial.print("UID:");
        for (int i = 0; i < rfid.uid.size; i++) {
          Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
          Serial.print(rfid.uid.uidByte[i], HEX);
        }
        Serial.println();

        String json = printHex(rfid.uid.uidByte, rfid.uid.size);
        json.trim();
        json.toUpperCase();
        // Convert JSON string to character array
        json.toCharArray(jsonChar1, json.length()+1);
   
        if  (client.connected()) {
            Serial.print("Publish message: ");
            Serial.println(json);
            // Publish JSON character array to MQTT topic
            client.publish(topic2,jsonChar1);
             
          rfid.PICC_HaltA(); // halt PICC
          rfid.PCD_StopCrypto1(); // stop encryption on PCD
        }  
        else
        {
          Serial.print("MQTT not connected ");
        }
     
      }
    }


    else  
    {
      // PN532 probably timed out waiting for a card
      Serial.println("Timed out waiting for a card");
    }      
    //Task1休息,delay(X)不可省略
    delay(1000);
  }
}
//===========================================================

//===========================================================
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;
    }
//===========================================================
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}    
//===========================================================

//===========================================================
void callback(char *topic, byte *payload, unsigned int length) {
    Serial.print("Message arrived in topic: ");
    Serial.println(topic);
    Serial.print("Message: ");
    String message;
    for (int i = 0; i < length; i++) {
        message += (char) payload[i];  // Convert *byte to string
    }
    Serial.print(message);
    if (message == "on" && !ledState) {
        digitalWrite(LED, HIGH);  // Turn on the LED
        ledState = true;  //ledState = ture HIGH
        Flash = false;
        Timer = false;
        json ="ON";
        Send = true ;
    }
    if (message == "off" && ledState) {
        digitalWrite(LED, LOW); // Turn off the LED
        ledState = false; //ledState = false LOW
        Flash = false;
        Timer = false;
        json ="OFF";
        Send = true ;

    }
    if (message == "flash" ) {
        digitalWrite(LED, LOW); // Turn off the LED
        Flash = true;
        Timer = false;
        json ="FLASH";
        Send = true ;        

    }
    if (message == "timer" ) {
        digitalWrite(LED, LOW); // Turn off the LED
        Flash = false;
        Timer = true;
        json ="TIMER";
        Send = true ;
        Count= 11;
    }

    if (message == "toggle" ) {
        digitalWrite(LED, !digitalRead(LED));   // Turn the LED toggle
        if (digitalRead(LED))
            ledState = true;
        else
            ledState = false;
       
        Flash = false;
        Timer = false;
        json ="TOGGLE";
        Send = true ;        
    }

    Serial.println();
    Serial.println("-----------------------");
}
//===========================================================
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect

    if (client.connect("esp32-client-")) {
      Serial.println("connected");
      // Subscribe
      client.subscribe("alex9ufo/esp32/led");
      client.subscribe("alex9ufo/esp32/RFID");      
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
      if (WiFi.status() != WL_CONNECTED)  {
        Serial.println("Reconnecting to WiFi...");
        WiFi.disconnect();
        WiFi.reconnect();
      }
    }
  }
}
//===========================================================

void LED_Message() {
    if (Flash){
        digitalWrite(LED, !digitalRead(LED));
        delay(500);
        if (digitalRead(LED))
            ledState = true;
        else
            ledState = false;
    } //(Flash)
       
    if (Timer) {
        digitalWrite(LED, HIGH);
        delay(500);
        if (digitalRead(LED))
            ledState = true;
        else
            ledState = false;

        Count=Count-1;
        if (Count == 0 ){
            Timer=false;
            digitalWrite(LED, LOW);
            ledState = false;
        }
    } //(Timer)
   
    if (client.connected()) {        
        if (Send) {
          // Convert JSON string to character array
          json.toCharArray(jsonChar1, json.length()+1);
          Serial.print("Publish message: ");
          Serial.println(json);
          // Publish JSON character array to MQTT topic
          client.publish(topic3,jsonChar1);
        }
        Send = false;    
    }
    else
    {
      if (WiFi.status() != WL_CONNECTED)  {
        Serial.println("Reconnecting to WiFi...");
        WiFi.disconnect();
        WiFi.reconnect();
      }
    }

}

//===========================================================
void setup() {
    // Set software serial baud to 115200;
    Serial.begin(115200);
    delay(1000); // Delay for stability
    //======================================================
    // Connecting to a WiFi network
    setup_wifi();
    // Setting LED pin as output
    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);  // Turn off the LED initially
    //======================================================
    SPI.begin();           // Init SPI bus
    rfid.PCD_Init();    // Init MFRC522

    Serial.println(F("Ready!"));
    Serial.println(F("======================================================"));
    Serial.println("Tap an RFID/NFC tag on the RFID-RC522 reader");


    // Connecting to an MQTT broker
    client.setServer(mqtt_broker, mqtt_port);
    client.setCallback(callback);
    while (!client.connected()) {
        String client_id = "esp32-client-";
        client_id += String(WiFi.macAddress());
        Serial.printf("The client %s connects to the public MQTT broker\n", client_id.c_str());
        if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
            Serial.println("Public HiveMQ MQTT broker (broker.mqtt-dashboard.com) connected");
        } else {
            Serial.print("Failed with state ");
            Serial.print(client.state());
            delay(2000);
        }
    }

    // Publish and subscribe
    client.subscribe(topic1);
    client.publish(topic,"ESP32 at work");

    //在核心0啟動任務1
    xTaskCreatePinnedToCore(
    Task1_senddata, /*任務實際對應的Function*/
      "Task1",        /*任務名稱*/
      10000,          /*堆疊空間*/
      NULL,           /*無輸入值*/
      0,              /*優先序0*/
      &Task1,         /*對應的任務變數位址*/
      0);             /*指定在核心0執行 */
}
//===========================================================
void loop()
{
 if (!client.connected()) {
      reconnect();
      Serial.print(" client not connected  reconnect ");
      delay(200);
    }
  client.loop();
  // Process LED message
  LED_Message();

  unsigned long currentMillis = millis();
  // if WiFi is down, try reconnecting
  if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >=interval)) {
    Serial.print(millis());
    Serial.println("Reconnecting to WiFi...");
    WiFi.disconnect();
    WiFi.reconnect();
    previousMillis = currentMillis;

    client.setCallback(callback);
  }

}
//===========================================================

沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...