[Arduino] 雲端打卡

NodeMCU + RFID(MFRC522) + Google Apps Script + Google 試算表 + pushingbox = 雲端打卡

在任何地點,連上網路,使用 RFID 卡(高雄的一卡通或是台北的悠遊卡,都可以)刷卡後,卡號直接傳到 Google 試算表。

  • 接線圖
NodeMCU RFID(MFRC522)
D1 RST
D2 SDA
D5 SCK
D6 MISO
D7 MOSI
3V 3.3V
G GND
  • Arduino程式
/*
RFID讀卡機連接NodeMCU的接腳方式
RST = GPIO5(D1)
SDA(SS) = GPIO4(D2)
MOSI = GPIO13(D7)
MISO = GPIO12(D6)
SCK = GPIO14(D5)
GND = GND
3.3V = 3.3V
*/
#include <ESP8266WiFi.h> // <>此為全形,請記得改為半形,後續的部分皆相同
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 5 // 讀卡機的重置腳位
#define SS_PIN 4 // 晶片選擇腳位
const char *ssid = "SSID"; // WIFI名稱
const char *pass = "Password"; // WIFI密碼
MFRC522 mfrc522(SS_PIN, RST_PIN); // 建立MFRC522物件

const char* host = "api.pushingbox.com";
String data;

void setup()
{
   Serial.begin(115200);
   delay(1000);
   Serial.println("RFID reader initial...");
   SPI.begin(); // 初始化SPI BUS
   mfrc522.PCD_Init(); // 初始化MFRC522讀卡機模組
   WiFi.begin(ssid, pass); // 初始化WiFi

   int retries = 0;
   while ((WiFi.status() != WL_CONNECTED) && (retries < 10))
   {
      retries++;
      delay(500);
      Serial.print(".");
   }
   if (WiFi.status() == WL_CONNECTED)
   {
      Serial.println(F("WiFi connected"));
   }
   Serial.println(F("WiFi Ready!"));
   Serial.println(F("============================"));
   Serial.println(F("Scan for Card and print UID:"));
}
void loop()
{
   // 確認是否有新卡片
   if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) // 如果出現新卡片就讀取卡片資料
   {
      delay(100);
      byte *id = mfrc522.uid.uidByte; // 取得卡片的UID
      byte idSize = mfrc522.uid.size; // 取得UID的長度
      Serial.print(F("Card UID:")); // 顯示卡片的UID
      dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
      Serial.println();
      mfrc522.PICC_HaltA(); // 讓卡片進入停止模式
      delay(5000);
      WiFiClient client; const int httpPort = 80;
      if (!client.connect(host, httpPort))
      {
         Serial.println("connection failed");
         return;
      }
      String url = "/pushingbox?";
      url += "devid=";
      url += "v53538826848EAEC";
      url += "&CardNo="+String(data); Serial.print("Requesting URL: ");
      Serial.println(url);
      client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
      unsigned long timeout = millis();
      while (client.available() == 0)
      {
         if (millis() - timeout > 5000)
         {
            Serial.println(">>> Client Timeout !");
            client.stop();
            return;
         }
      }

      while(client.available())
      {
         String readStr = client.readStringUntil('\r');
         Serial.print(readStr);
         Serial.print("Data Sent!");
      }

      Serial.println();
      Serial.println("closing connection");
      data = "";
   }
}

void dump_byte_array(byte *buffer, byte bufferSize)
{
   Serial.println("dump_byte_array ... ");
   for (byte i = 0; i < bufferSize; i++)
   {
      Serial.print(buffer[i] < 0x10 ? " 0" : " ");
      Serial.print(buffer[i], HEX); //10進位DEC;或者使用16進位HEX
      data += String(buffer[i], HEX);
   }
}
  • 結果