[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);
   }
}
  • 結果

[Arduino] 改變ESP8266的鮑率(傳輸速率)

ESP8266預設的傳輸速率是115200,需要先改成9600才有辦法跟Arduino互相溝通。

  • 接線
aduino ESP8266
D4 TX
D5 RX
3.3V EN
3.3V 3.3V
GND GND
  • 程式
    #include <SoftwareSerial.h> // <>改為半形,用全形網頁才能顯示,但是 arduino ide 編譯不過
    SoftwareSerial mySerial(4, 5); // Arduino RX:4, TX:5
    void setup()
    {
      // Open serial communications and wait for port to open:
      Serial.begin(9600);
      Serial.println("Arduino...OK");
      mySerial.begin(115200);
      mySerial.write("AT+UART_DEF=9600,8,1,0,0\r\n");
      delay(1500);
      mySerial.begin(9600);
      Serial.println("ESP8266...OK");
    }
    void loop() // run over and over
    {
      if (mySerial.available())
        Serial.write(mySerial.read());
      if (Serial.available())
        mySerial.write(Serial.read());
    }
    
  • 程式編譯後,上傳到Arduino開發板,上傳完畢後就可以直接在序列埠視窗測試AT指令了。

[Arduino] Arduino與Python通訊(三)Arduino傳送資料給Python

  • 使用 python 程式透過通訊埠(COM PORT)接收 arduino 的資料 ,並顯示在電腦中。
  • arduino 接線
aduino 可變電阻
A0 中間腳位
VCC VCC
GND GND
  • arduino 程式
void setup() 
{
  Serial.begin(9600);
}

void loop() 
{
  int vr = analogRead(A0);
  Serial.println(vr);
}
  • python 程式:python沒有陣列(array)的型態,所以只能用list。
import serial

COM_PORT = 'COM4'  # 根據連結的Arduino的通訊埠修改設定
BAUD_RATES = 9600
arduinoSerial = serial.Serial(COM_PORT, BAUD_RATES)

try:
    buffer = list()
    
    while True:
        while arduinoSerial.in_waiting:
            data_raw = arduinoSerial.read()
            buffer.append(data_raw)

            if data_raw == b'\n':
                print('收到的資料:', buffer)
                buffer.clear()

except KeyboardInterrupt:
    arduinoSerial.close()    # 清除序列通訊物件
    print('關閉程式')

 

[Arduino] Arduino與Python通訊(二)使用Python點亮Arduino上的LED

  • 使用 python 程式透過通訊埠(COM PORT)傳輸指令給 arduino  ,來控制 LED 燈的開關(亮暗)。
  • python程式
import serial

COM_PORT = 'COM4'  # 根據連結的Arduino的通訊埠修改設定
BAUD_RATES = 9600
arduinoSerial = serial.Serial(COM_PORT, BAUD_RATES)

try:
    while True:
        choice = input('1:開燈 0:關燈 9:關閉程式  ')
        if choice == '1':
            print('開燈')
            arduinoSerial.write(b'1')
        elif choice == '0':
            print('關燈')
            arduinoSerial.write(b'0')
        elif choice == '9':
            print('關閉程式')
            arduinoSerial.close()
            exit()
        else:
            print('指令錯誤')

except KeyboardInterrupt:
    arduinoSerial.close()    # 清除序列通訊物件
    print('關閉程式')
  • arduino 接線
arduino LED
D10 正(長腳)
GND 負(短腳)
  • arduino程式
char serialData;
int LedPin = 10;

void setup() 
{
  pinMode(LedPin, OUTPUT);  
  Serial.begin(9600);
}

void loop() 
{
  if(Serial.available() > 0)
  {
    serialData = Serial.read();
    Serial.print(serialData);

    if(serialData == '1')
      digitalWrite(LedPin, HIGH);
    else if(serialData == '0')
      digitalWrite(LedPin, LOW);
  }
}

 

[Arduino] Arduino與Python通訊(一)安裝prserial

透過通訊埠(COM PORT)串聯 arduino 與 python。

點選下載

  • 選擇壓縮檔(.tar.gz)下載。

選擇壓縮檔下載

  • 下載到電腦後,解壓縮,進入解壓縮後的目錄,並執行安裝「python setup.py install」,開啟命令提示時,請使用「管理員權限」,不然可能會導致安裝失敗。

安裝pyserial

  • 安裝完成後,會顯示「Finished processing dependencies for pyserial==3.4」

pyserial安裝完成

[Arduino] 自動給皂機

因為武漢肺炎要多洗手(應該平時就要養成這個習慣),所以來做個自動給皂機,減少接觸物品。

  • 零件:

sg90伺服馬達*2,紅外線感測器*1,(Arduino Nano + 擴充板)*1

  • 接線:
左邊馬達 右邊馬達 紅外線感測器 Arduino
5S
5V
棕(或黑) 5G
3S
3V
棕(或黑) 3G
OUT 7S
VCC 7V
GND 7G
  • 程式碼:
#include <Servo.h> // <>改為半形,用全形網頁才能顯示,但是 arduino ide 編譯不過

Servo myservoR, myservoL; // 建立Servo物件,控制伺服馬達

int servoRPin = 3;
int servoLPin = 5;
int irPin = 7;
void setup()
{
  Serial.begin(9600);
  myservoR.attach(servoRPin); // 連接數位腳位servoRPin,伺服馬達的訊號線
  myservoL.attach(servoLPin); // 連接數位腳位servoLPin,伺服馬達的訊號線
  myservoR.write(170); // 一開始先170度
  myservoL.write(10); // 一開始先10度
  pinMode(irPin, INPUT);
}

void loop()
{
  int moist;
  moist = digitalRead(irPin);
  Serial.println(moist);

  // 靠近時,轉動馬達
  if (moist == 0)
  {
    myservoR.write(10);
    myservoL.write(170);
    delay(20);
  }
  else // 遠離時,恢復馬達
  {
    myservoR.write(170);
    myservoL.write(10);
    delay(20);
  }
}
  • 注意事項:
  1. 馬達的角度需要視馬達的情況而調整,sg90的馬達扭力不足,改為其他扭力更強的馬達,效果會更好。
  2. 馬達間的線,需要固定,在停止狀態時,最好是緊繃的。現用縫衣服的線,若改用釣魚用水線,效果可能會更好。
  • 結果影片:

[Arduino] 手機教調酒

透過手機學習如何調酒!

這是二年前做的一個小專案,可以透過手機教導如何調酒。

調酒的過程(菜單)放在 FireBase 中,然後透過手機 APP 連線到 FireBase 取得資料,跟著步驟一步一步做,就可以完成調酒。

這個 APP 是用 App Inventor2 來製作的,硬體是用 Arduino ,再加上 HX711、LCD1602 以及藍芽模組 HC-05,APP 與硬體的溝通是透過藍芽。

學校如果有餐飲科系及資訊科系,正好可以做誇科系的教學。由餐飲科系提供調酒菜單及過程,再由資訊科系編輯修改 FireBase 的資料,或是修改 APP 的介面。

[Arduino] ESP32(三) 使用 ESP32 CAM 拍照並傳LINE通知

  • 參考這個 YouTube 的影片來實作,影片中是使用紅外線人體感測器,我把它改為按下按鈕後,拍照傳到 LINE。

  • 首先要取得 LINE Notify 的權杖,可以設定要通知自己,或是某一個群組。
  • 連線到「https://notify-bot.line.me/zh_TW/」,並使用自己的 LINE 帳號登入。LINE_Notify
  • 登入後,進入「個人頁面」。LINE個人頁面
  • 如果之前有申請過權杖,則會顯示出來,不再使用的話,可以刪除。這裡要申請一個新的權杖給 ESP32-CAM 使用。LINE發行權杖
  • 輸入權杖名稱,並選擇要傳送通知的聊天室,第一個是傳給LINE的擁有者,後面是其他聊天室,被選擇的聊天室會顯示綠色。LINE發行權杖02
  • 注意:要先把權杖複製起來,一旦關閉頁面,就只能重新申請權杖囉!

LINE發行權杖03

  • 實作後的影片

[Arduino] ESP32(二) ESP32 CAM

  • ESP32 與 ESP32-CAM的差異,ESP32 可以直接使用 Micro USB 的線來上傳程式,但是 ESP32-CAM 並不能直接上傳程式,所以必須透過 FTDI ( USB 轉 TTL ),而 FTDI 使用的是 Mini USB 的線;ESP32-CAM 還比 ESP32 多了照相機功能
USB 線的規格 FTDI
USB線規格 FTDI
ESP32 ESP32-CAM
ESP32 ESP32CAM
  •  在 Arduino IDE 安裝好 ESP32 的環境之後,有一個範例程式(WebServer)可以直接拿來使用,就可以建立一個串流的系統,還可以有人臉追蹤的功能。點擊「檔案」-> 「範例」-> 「ESP32」->「Camera」->「CameraWebServer」。CameraWebServer範例程式
  • 在這個範例程式,只需要修改幾個地方,就可以直接使用了。修改CameraWebServer範例程式
  • FTDI 與 ESP32-CAM 的接線方式。
FTDI ESP32-CAM
RXD UOT
TCD UOR
VCC 5V
GND GND
  • 接著就可以將修改後的程式上傳到 ESP32-CAM ,上傳時需要注意的地方:
  1. 需要將 ESP32-CAM 的 IO0 與 GND 連接,可以使用一條母對母的杜邦線直接接到這兩個腳位。
  2. 上傳時當 Arduino IDE 的下方訊息框出現下圖藍色框的訊息時,需要按下 ESP32-CAM 上的 RST 按鈕,再鬆開後,程式就會繼續上傳。ESP32-CAM上傳訊息
  3. 上完完畢後,將第1點提到的杜邦線移除,也就是不需要將 ESP32-CAM 的 IO0 與 GND 連接,並再次按下「RST」按鈕。
  • 程式上傳完畢後,透過 Arduino IDE 的監控視窗,可以取得 ESP32-CAM 的 IP 。Arduino監控視窗
  • 接著開啟瀏覽器,在網址列輸入上圖中紅色框的 IP ,「192.168.1.115」,即可連線到 ESP32-CAM 了。將畫面移到最下面,按下「Start Stream」,就可以在瀏覽器上看到 ESP32-CAM 攝影到的畫面了。畫面上的參數都可以變更,如果要使用人臉追蹤的話,要開啟「Face Detection」這個選項。ESP32-CAM畫面擷取

 

 

[Arduino] ESP32(一) 環境設定–在Arduino IDE上安裝ESP32

  • 在 Arduino IDE 中加入 ESP32,原始的 Arduino IDE 中並沒有 ESP32 ,需要額外加入。
  • 打開 Arduino IDE 並點擊左上角的「檔案」-> 「偏好設定」,在「額外的開發板管理員網址」 輸入「https://dl.espressif.com/dl/package_esp32_index.json」並按下確定。Arduino偏好設定
  • 接著點擊「工具」-> 「開發板」-> 「開發板管理員」 , 等待畫面下方下載進度條完成。Arduino開發版管理員
  • 在上方搜尋框輸入「ESP32」,並點選 「ESP32」,再選擇版本(也可以直接安裝最新版),然後點擊「安裝」。Arduino開發版管理員2
  • 安裝完成後,如下圖,點擊「關閉」,回到 Arduino IDE。開發版管理員安裝完成
  • 選擇 Arduino 開發板,「工具」-> 「開發板」-> 選擇 「ESP32 Wrover Module 」 (Arduino IDE 會紀錄上次選擇或使用的開發板資料,所以如果上次的開發板跟下圖不同也沒有關係,只要選對目前要使用的開發板就可以)選擇ESP32開發板
  • 設定 ESP32 參數,下圖紅色框部分要一樣,而序列埠則視每台電腦的抓取而定。ESP32參數設定