0% found this document useful (0 votes)
28 views19 pages

Project Assignment-CPS-Review - Arindam

The document describes the components and process for a smart school attendance system using RFID tags. The system uses an Arduino, RFID sensor and NodeMCU to read student RFID tags, send the IDs to a cloud database (ThingSpeak), and send SMS and email notifications if attendance is recorded successfully.

Uploaded by

mohitxp
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views19 pages

Project Assignment-CPS-Review - Arindam

The document describes the components and process for a smart school attendance system using RFID tags. The system uses an Arduino, RFID sensor and NodeMCU to read student RFID tags, send the IDs to a cloud database (ThingSpeak), and send SMS and email notifications if attendance is recorded successfully.

Uploaded by

mohitxp
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 19

Project Assignment: Smart School System

2 b: Record attendance using RFID tags and store


it on the cloud; send SMS & email notifications

Student: Arindam Chowdhury (2021ht66027)


Group 8 - Student 2

Date: 26th October, 2022


Contents
Components Required.......................................................................................................................3
Diagram:............................................................................................................................................3
Logical Connections:..........................................................................................................................3
Physical Connections:........................................................................................................................4
Flow Summary:..................................................................................................................................4
Code - Arduino:..................................................................................................................................5
Code - NodeMCU...............................................................................................................................7
Serial Output :..................................................................................................................................16
ThingSpeak Access Details:..............................................................................................................17
Email Notification:...........................................................................................................................18
SMS Notification:.............................................................................................................................18
VIDEO Recording :............................................................................................................................18
Components Required

Hardware:
1. Arduino
2. NodeMCU
3. RFID Sensor & Tag
4. Jump wires

Software:
1. Library MFRC522 - https://github.com/miguelbalboa/rfid
2. Library “DSC Keybus Interface” - https://github.com/miguelbalboa/rfid
3. Arduino IDE

Diagram:
Logical Connections:

Arduino UNO RFID Sensor Node MCU


GND GND
3.3V 3.3V
9 RST
10 SDA
11 MOSI
12 MISO
13 SDA
GND G
6 (Tx) D5 (Rx)
7 (Rx) D6 (Tx)
Physical Connections:

Flow Summary:

1. Read card ID by RFID sensor.

2. Receive the ID on Arduino sent by RFID sensor.

3. Send the ID to NodeMCU.

4. NodeMCU establishes connection to thinkspeak portal; and sends the ID using http POST
method.

5. NodeMCU reads the code returned by POST method to identify whether data is successfully
saved on thinkspeak or not.

6. If it was successful, NodeMCU performs following tasks:

a) Establishes connection to Twilio portal, and sends SMS to student’s mobile phone
number confirming attendance record.

b) Establishes connection to google SMTP server, and sends email to principal confirming
attendance record.

Code - Arduino:

// Arduino UNO code

#include <SPI.h>
#include <MFRC522.h>
#include <SoftwareSerial.h>

#define RST_PIN 9 // Configurable


#define SS_PIN 10 // Configurable

MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance


byte card_ID[4]; //card UID size 4byte

SoftwareSerial ard (7, 6); //GPIO Pin 7 RX and Pin 6 TX

//
**************************************************************
***************************//
void setup() {
Serial.begin(9600);
// Initialize serial communications with the PC
SPI.begin();
// Init SPI bus
mfrc522.PCD_Init();
// Init MFRC522 card
Serial.println(F("Read personal data on a MIFARE PICC:"));
//shows in serial that it is ready to read

ard.begin (9600);
}

//
**************************************************************
***************************//
void loop()
{
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip
delivery from the factory.
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++)
{
key.keyByte[i] = 0xFF;
}

//some variables we need


byte block;
byte len;
MFRC522::StatusCode status;
//-------------------------------------------

// Reset the loop if no new card present on the


sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent())
{
return;
}

// Select one of the cards


if ( ! mfrc522.PICC_ReadCardSerial())
{
return;
}

//Serial.println(F("**Card Detected:**"));

for (byte i = 0; i < mfrc522.uid.size; i++) {


card_ID[i]=mfrc522.uid.uidByte[i];}

delay(1000); //change value if you want to read cards faster

mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();

if (ard.available() > 0)
{
for (byte i = 0; i < mfrc522.uid.size; i++) {
ard.write(card_ID[i]);}
}
}

Code - NodeMCU

#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>

#include <ESP8266HTTPClient.h>
#include "base64.h"

HTTPClient http;
int httpCode = 0;

SoftwareSerial esp (D5,D6); // Pin D5 RX and Pin D6 TX


unsigned long data = 0;
String strdata;
String apiKey = "xxxxx"; // Enter your Write API key from
ThingSpeak

const char *ssid = "xxxxx"; //Add SSID of your WIFI


Connection
const char *pass = "xxxxx"; // ADD password
const char* server = "http://api.thingspeak.com/update";

const char* AccountSID = "xxxxx"; // Set the account SID


from the Twilio Account Dashboard
const char* AuthToken = "xxxxx"; // Set the auth token
from the Twilio Account Dashboard
const char* From = "xxxxx"; // From phone number,
starting with the country code without the + sign: 18005551234
const char* To = "xxxxx"; // To phone number,
starting with the country code without the + sign: 18005551234
const char* messagePrefix = "[Attendance system] "; // Set a
prefix for all messages

WiFiClient client;

// HTTPS root certificate for api.twilio.com: DigiCert Global


Root CA, expires 2031.11.10
const char twilioCertificateRoot[] = R"=EOF=(
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFAD
Bh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLEx
B3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdC
BD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAl
VT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC
5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhk
iG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOll
sB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/
fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/
Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//
AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/
y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/
tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/
zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90V
Uw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/
Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/
2PV5Adg
06O/
nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0
ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tb
Qk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
)=EOF=";

// Initialize components
X509List twilioCert(twilioCertificateRoot);
WiFiClientSecure ipSMSClient, ipMailClient;
char twilioAuth[128];
size_t twilioAuthLength = 128;
char encodedTwilioAuth[128], encodedMessagePrefix[128],
encodedMessageContent[480];

void setup()
{
esp.begin (9600);
//Serial.begin (9600);
Serial.begin(115200);

delay(10);
Serial.println("Connecting to ");
Serial.println(ssid);

WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
ipSMSClient.setTrustAnchors(&twilioCert);

while (WiFi.status() != WL_CONNECTED)


{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
randomSeed(analogRead(0));
ipMailClient.setInsecure();

Serial.print(F("NTP time...."));
configTime(0, 0, "pool.ntp.org");
time_t now = time(nullptr);
while (now < 24 * 3600)
{
Serial.print(".");
delay(2000);
now = time(nullptr);
}
Serial.println(F("synchronized."));

// Encodes authentication in base64 and message prefix in


URL encoding
strcat(twilioAuth, AccountSID);
strcat(twilioAuth, ":");
strcat(twilioAuth, AuthToken);

base64::encode(String(twilioAuth)).toCharArray(encodedTwilioAu
th, 128);
encodeURL(messagePrefix, encodedMessagePrefix);
}

void loop(){
if (esp.available() > 0){
data = esp.read();
//Serial.println ("Receiving data...");
//Serial.println (data, HEX);
if (strdata.length() != 0)
{
strdata += " ";
}
char tempstr[2];
sprintf(tempstr, "%02X", data);
strdata += tempstr;
}

if (strdata.length() == 11)
{
String postStr = "api_key=";
postStr += apiKey;
postStr +="&field1=";
postStr += strdata;

// configure traged server and url


http.begin(client, server); //HTTP
http.addHeader("Content-Type", "application/x-www-form-
urlencoded");

// start connection and send HTTP header and body


httpCode = http.POST(postStr);

// httpCode will be negative on error


if (httpCode > 0) {
// HTTP header has been send and Server response header
has been handled
Serial.printf("[HTTP] POST... code: %d\n", httpCode);

// Data saved on server


if (httpCode == HTTP_CODE_OK) {
const String& payload = http.getString();
Serial.println("received payload:\n<<");
Serial.println(payload);
Serial.println(">>");

String newstr = "Attendance recorded for ID: ";


newstr += strdata;

int n = newstr.length();
char msgContent[n+1];
strcpy(msgContent, newstr.c_str());
Serial.printf("messageContent: %s\n", msgContent);
//Send SMS
sendMessage(msgContent);

//Send Mail
Serial.print(F("Email...."));
if (sendMailMessage(msgContent))
Serial.println(F("connected and sent."));
else
Serial.println(F("connection error."));
}
}
else {
Serial.printf("[HTTP] POST... failed, error: %s\n",
http.errorToString(httpCode).c_str());
}

Serial.print("Card ID: ");


Serial.print(strdata);
Serial.println(" Sent to Thingspeak.");
Serial.println("POST string: "+postStr);
Serial.printf("Returned http code: %d\n"+httpCode);
Serial.println("Waiting...");

// thingspeak needs minimum 15 sec delay between updates


delay (15000);

// reset the message before next card swipe


strdata = "";
}
}

// sendMessage() takes the SPI content as parameter, prepares


and sends the message.
bool sendMessage(const char* messageContent) {
encodeURL(messageContent, encodedMessageContent); //
Encodes message content in URL encoding

if (!ipSMSClient.connect("api.twilio.com", 443)) return


false;
ipSMSClient.print(F("POST https://api.twilio.com/2010-04-
01/Accounts/"));
ipSMSClient.print(AccountSID);
ipSMSClient.println(F("/Messages.json HTTP/1.1"));
ipSMSClient.print(F("Authorization: Basic "));
ipSMSClient.println(encodedTwilioAuth);
ipSMSClient.println(F("Host: api.twilio.com"));
ipSMSClient.println(F("User-Agent: ESP8266"));
ipSMSClient.println(F("Accept: */*"));
ipSMSClient.println(F("Content-Type: application/x-www-form-
urlencoded"));
ipSMSClient.print(F("Content-Length: "));
ipSMSClient.println(strlen(To) + strlen(From) +
strlen(encodedMessagePrefix) + strlen(encodedMessageContent) +
21);
ipSMSClient.println("Connection: Close");
ipSMSClient.println();
ipSMSClient.print(F("To=%2B"));
ipSMSClient.print(To);
ipSMSClient.print(F("&From=%2B"));
ipSMSClient.print(From);
ipSMSClient.print(F("&Body="));
ipSMSClient.print(encodedMessagePrefix);
ipSMSClient.print(encodedMessageContent);

// Waits for a response


unsigned long previousMillis = millis();
while (!ipSMSClient.available()) {
//dsc.loop();
if (millis() - previousMillis > 3000) {
Serial.println(F("Connection timed out waiting for a
response."));
ipSMSClient.stop();
return false;
}
}

// Reads the response until the first space - the next


characters will be the HTTP status code
while (ipSMSClient.available()) {
if (ipSMSClient.read() == ' ') break;
}

// Checks the first character of the HTTP status code - the


message was sent successfully if the status code
// begins with "2"
char statusCode = ipSMSClient.read();
// Successful, reads the remaining response to clear the
client buffer
if (statusCode == '2') {
while (ipSMSClient.available()) ipSMSClient.read();
ipSMSClient.stop();
return true;
}

// Unsuccessful, prints the response to serial to help debug


else {
Serial.println();
Serial.println(F("SMS messaging error, response:"));
Serial.print(statusCode);
while (ipSMSClient.available())
Serial.print((char)ipSMSClient.read());
Serial.println();
ipSMSClient.stop();
return false;
}
}

// Helper for encodeURL()


static char encodeHex(char c) {
return "0123456789ABCDEF"[c & 0x0F];
}

// Encodes a char array to URL encoded using '+' for spaces as


required for application/x-www-form-urlencoded
char *encodeURL(const char *src, char *dst) {
char c, *d = dst;
while (c = *src++) {
if (c == ' ') {
*d++ = '+';
continue;
}
else if (!('a' <= c && c <= 'z')
&& !('A' <= c && c <= 'Z')
&& !('0' <= c && c <= '9')) {
*d++ = '%';
*d++ = encodeHex(c >> 4);
c = encodeHex(c);
}
*d++ = c;
}
*d = '\0';
return dst;
}

// sendMailMessage() takes the email subject and body as


separate parameters. Configure the settings for your SMTP
// server - the login and password must be base64 encoded. For
example, on the macOS/Linux terminal:
// $ echo -n '[email protected]' | base64 -w 0
bool sendMailMessage(const char* messageContent) {
if (!ipMailClient.connect("smtp.gmail.com", 465)) return
false; // Set the SMTP server address - for example:
smtp.gmail.com
if(!smtpValidResponse()) return false;
ipMailClient.println(F("HELO ESP8266"));
if(!smtpValidResponse()) return false;
ipMailClient.println(F("AUTH LOGIN"));
if(!smtpValidResponse()) return false;
ipMailClient.println(F("xxxxx")); //
Set the SMTP server login in base64
if(!smtpValidResponse()) return false;
ipMailClient.println(F("xxxxx")); // Set
the SMTP server password in base64; google app-password may be
applicable
if(!smtpValidResponse()) return false;
ipMailClient.println(F("MAIL FROM:<[email protected]>"));
// Set the sender address
if(!smtpValidResponse()) return false;
ipMailClient.println(F("RCPT TO:<[email protected]>"));
// Set the recipient address - repeat to add multiple
recipients
if(!smtpValidResponse()) return false;
//ipMailClient.println(F("RCPT
TO:<[email protected]>")); // An optional
additional recipient
//if(!smtpValidResponse()) return false;
ipMailClient.println(F("DATA"));
if(!smtpValidResponse()) return false;
ipMailClient.println(F("From: Security System
[email protected]")); // Set the sender displayed in the email
header
ipMailClient.println(F("To: Recipient [email protected]"));
// Set the recipient displayed in the email header
ipMailClient.print(F("Subject: "));
ipMailClient.print(messagePrefix);
ipMailClient.println(messageContent);
ipMailClient.println();
// Required blank line between the header and body
ipMailClient.print(messagePrefix);
ipMailClient.println(messageContent);
ipMailClient.println(F("."));
if(!smtpValidResponse()) return false;
ipMailClient.println(F("QUIT"));
if(!smtpValidResponse()) return false;
ipMailClient.stop();
return true;
}

bool smtpValidResponse() {

// Waits for a response


unsigned long previousMillis = millis();
while (!ipMailClient.available()) {
if (millis() - previousMillis > 3000) {
Serial.println(F("Connection timed out waiting for a
response."));
ipMailClient.stop();
return false;
}
}

// Checks the first character of the SMTP reply code - the


command was successful if the reply code begins
// with "2" or "3"
char replyCode = ipMailClient.read();

// Successful, reads the remainder of the response to clear


the client buffer
if (replyCode == '2' || replyCode == '3') {
while (ipMailClient.available()) ipMailClient.read();
return true;
}

// Unsuccessful, prints the response to serial to help debug


else {
Serial.println(F("Email send error, response:"));
Serial.print(replyCode);
while (ipMailClient.available())
Serial.print((char)ipMailClient.read());
Serial.println();
ipMailClient.println(F("QUIT"));
smtpValidResponse();
ipMailClient.stop();
return false;
}
}

Serial Output :

Displays – Card ID, HTTP POST return code & email status.

ThingSpeak Access Details:

Access has been given to Public

URL for the same is Student Attendance


This portal primarily stores records of attendance entries, which can be downloaded using
“Export recent data” option.

Email Notification:

Gmail SMTP server has been used here to send email to admin mail id. Following screenshot was
captured as part of this project execution:

SMS Notification:
Twilio online messaging service has been used here to send text message to student’s
mobile phone number. Following screenshot was captured as part of this project execution:

VIDEO Recording :

Google drive link:

https://drive.google.com/file/d/1Nf3xU2S3dvbLxpMHRtq_rc6rdxAsEBh7/view?usp=sharing

You might also like