คัดลอกโค้ดเรียบร้อยแล้ว!

โรงเรียนบ้านเขาหินซ้อน (พัฒนาการภาคตะวันออก)

Coding Room Smart Access System

IoT & Robotics Lab

ระบบเปิด-ปิดประตูอัตโนมัติด้วย RFID

สรุปสถาปัตยกรรมและการทำงาน โค้ดควบคุมประตูห้องเรียน Coding ด้วย NodeMCU ESP8266, เครื่องอ่านบัตร MFRC522, เซอร์โวมอเตอร์ และการเชื่อมโยงระบบบันทึกข้อมูลผ่าน HTTP Server

Smart Door Control System

ภาพตัวอย่าง: ชุดอุปกรณ์ควบคุมประตูสมาร์ทรูม ห้องเรียน Coding

สรุปหลักการทำงานของระบบ

ขั้นตอนกระบวนการประมวลผลตั้งแต่การสแกนบัตรจนถึงการเปิดประตู

1. เชื่อมต่อ Wi-Fi & NTP Server

ระบบทำการเชื่อมต่อกับ Wi-Fi HS_TP_WiFi และดึงเวลาปัจจุบันจาก NTP Server (pool.ntp.org)

2. ตรวจสอบบัตร RFID

เมื่อนำบัตร RFID มาทาบที่เครื่องอ่าน MFRC522 ระบบจะอ่านค่า UID ของบัตรแปลงเป็นข้อความ Hexadecimal

3. ส่งข้อมูลยืนยันตัวตน

ส่งคำขอ HTTP GET ไปยังมินิเซิร์ฟเวอร์ (arduionsave.php) เพื่อบันทึกเวลา

4. สั่งการ Servo Motor

หากสิทธิ์ถูกต้อง Servo Motor จะหมุนไปที่ตำแหน่งเปิด 90° เป็นเวลา 2.5 วินาที ก่อนหมุนกลับมาปิด

5. แสดงสถานะด้วย NeoPixel & Buzzer

- ผ่าน: ไฟเขียว + เสียงปี๊บสำเร็จ
- ไม่ผ่าน: ไฟแดง + เสียงเตือนผิดพลาด

6. Self-Test System

เมื่อเปิดเครื่อง ระบบจะทดสอบกลไกประตูโดยการเปิดและปิดสั้นๆ 1 ครั้ง เพื่อตรวจสอบว่ากลไกไม่ติดขัด

รายการอุปกรณ์ที่ใช้ (Hardware Components)

ESP8266

NodeMCU Wi-Fi

MFRC522

RFID Reader

Servo Motor

SG90 / MG996R

NeoPixel Ring

8 LEDs

Buzzer

Active Buzzer

Power & Wires

5V Power Supply

ตารางการต่อสายวงจร (Pin Mapping)

อุปกรณ์ (Component) ขาอุปกรณ์ (Pin Name) ตำแหน่งขา NodeMCU ESP8266 หมายเหตุ (Notes)
RFID MFRC522 SDA (SS) GPIO4 (D2) #define SS_PIN 4
RFID MFRC522 RST GPIO5 (D1) #define RST_PIN 5
Buzzer I/O Signal D0 (GPIO16) #define BEEP_PIN D0
NeoPixel LED Ring DIN D3 (GPIO0) #define NEO_PIN D3
Servo Motor PWM Signal D8 (GPIO15) #define SERVO_PIN D8

ซอร์สโค้ดโปรแกรม (Source Code)

DoorControlSystem.ino
Arduino / ESP8266 C++
#include <Adafruit_NeoPixel.h>
#include <NTPClient.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiUdp.h>
#include <Servo.h> 

#define SS_PIN     4  
#define RST_PIN     5  
#define BEEP_PIN    D0
#define NEO_PIN     D3 
#define NUMPIXELS   8
#define SERVO_PIN   D8   

const char* ssid = "HS_TP_WiFi";
const char* password = "";
const long offsetTime = 25200; 

Adafruit_NeoPixel pixels(NUMPIXELS, NEO_PIN, NEO_GRB + NEO_KHZ800);
MFRC522 rfid(SS_PIN, RST_PIN);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", offsetTime);
Servo myServo; 

int closeAngle = 10;    
int openAngle  = 90;  

void setup() {
    Serial.begin(9600); 
    SPI.begin();
    rfid.PCD_Init();
    
    pinMode(BEEP_PIN, OUTPUT);
    digitalWrite(BEEP_PIN, HIGH);
    
    pixels.begin();
    pixels.setBrightness(25);
    setNeoColor(255, 100, 0); 
    
    myServo.attach(SERVO_PIN, 500, 2500); 
    myServo.write(closeAngle); 
    delay(200);
    myServo.write(openAngle); 
    delay(300);
    myServo.write(closeAngle); 
    delay(200);
    myServo.detach();    
    beepPowerOff();      

    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
    
    timeClient.begin();
    beepStart();
}

void loop() {
    timeClient.update();
    updateTimeColor(); 

    if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;

    String strID = "";
    for (byte i = 0; i < 4; i++) {
        strID += (rfid.uid.uidByte[i] < 0x10 ? "0" : "") + String(rfid.uid.uidByte[i], HEX) + (i != 3 ? ":" : "");
    }
    strID.toUpperCase();

    WiFiClient client;
    HTTPClient http;
    int hourNow = timeClient.getHours();
    String url = "http://192.168.100.5/hscouncil/arduionsave.php?checkc=Rcoding&RFid_arduino=" + strID + "&MM_insert=form1";

    http.begin(client, url);
    int httpCode = http.GET();

    if (httpCode > 0 && httpCode != 200) { 
        setNeoColor(0, 255, 0); 
        beepSuccess();
        
        myServo.attach(SERVO_PIN, 500, 2500); 
        delay(10);
        myServo.write(openAngle); 
        delay(2500); 
        
        beepWarning(); 
        myServo.write(closeAngle); 
        delay(350); 
        myServo.detach(); 
        beepPowerOff(); 
    } else {
        setNeoColor(255, 0, 0); 
        beepError();
    }
    
    http.end();
    rfid.PICC_HaltA();
    rfid.PCD_StopCrypto1();
}

void beepPowerOff() { digitalWrite(BEEP_PIN, LOW); delay(50); digitalWrite(BEEP_PIN, HIGH); }
void setNeoColor(int r, int g, int b) { for(int i = 0; i < NUMPIXELS; i++) pixels.setPixelColor(i, pixels.Color(r,g,b)); pixels.show(); }
void updateTimeColor() { int h = timeClient.getHours(); if (h < 12) setNeoColor(255, 255, 0); else setNeoColor(0, 0, 255); }
void beepSuccess() { digitalWrite(BEEP_PIN, LOW); delay(150); digitalWrite(BEEP_PIN, HIGH); }
void beepError() { for(int i=0; i<3; i++){digitalWrite(BEEP_PIN, LOW); delay(400); digitalWrite(BEEP_PIN, HIGH); delay(100);} }
void beepWarning() { for(int i=0; i<3; i++){digitalWrite(BEEP_PIN, LOW); delay(80); digitalWrite(BEEP_PIN, HIGH); delay(80);} }
void beepStart() { digitalWrite(BEEP_PIN, LOW); delay(50); digitalWrite(BEEP_PIN, HIGH); delay(50); digitalWrite(BEEP_PIN, LOW); delay(50); digitalWrite(BEEP_PIN, HIGH); }

คลิปวิดีโอตัวอย่างการทำงาน

System Logs & Activity

บันทึกข้อมูลการใช้งานห้องเรียน Coding

ตรวจสอบประวัติการสแกนบัตร RFID และสถานะการเข้า-ออกห้องเรียนย้อนหลัง

ดูข้อมูลการใช้งาน