本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

基于RFID的非接触式体温监测系统

发布时间:2022-08-14
分享到:

基于RFID的非接触式体温监测系统

发布时间:2022-08-14
分享到:

在该项目中员工通过 RFID 卡片访问企业,使用非接触式温度计将数据发送到云端。

当员工使用 RFID 卡片进入企业时,系统将额外使用非接触式红外温度计测量员工的体温。如果体温过高,访问将被阻止。此外,所有体温数据都将进入公司网站,用于监控员工到达公司时的体温(UID RFID 的员工识别)。

查看从云端发送的数据

使用带温度控制的 RFID 进入办公室

步骤 1. 软件安装
我们使用 Arduino MKR 1000 WiFi 板作为控制器。我们将在 Arduino IDE 中编程。默认情况下,Arduino IDE 仅配置用于 AVR 板。要使用 Arduino MK Wi-Fi 1000 平台,您需要在卡管理器中添加对 Arduino SAMD(32 位 ARM Cortex-M0+)的支持。在 Board Manager ( Tools > Board > Boards manager ) 中,找到 Arduino SAMD 并单击 Install 按钮。

在 Arduino IDE 中安装软件后,Tools  Board 菜单将支持 Arduino Zero 和 MKR 板,包括 MKR 1000 WiFi 板)。使用 USB 电缆将 MKR 1000 卡连接到您的计算机。驱动程序应该会自动安装。

步骤 2. 将 IR 温度传感器 MLX90614 连接到 Arduino MKR 1000 Wi Fi 板
MLX90614 是一款用于非接触式温度测量的红外传感器。它可以测量-70至380摄氏度范围内的温度,精度约为0.5°C。我有 MLX90614DAA 库存

传感器使用 I2C 协议。

与 Arduino MKR WiFi 板的连接图

对于编程,我们使用 Adafruit_MLX90614.h 库,该库必须通过 Manager Libraries ( Sketch > Include library > Manager Libraries ) 安装。将草图上传到 Arduino 板 (mlx90614_01.ino)

// Connecting libraries
#include <Wire.h>
#include <Adafruit_MLX90614.h>
// Creating an instance of an object
Adafruit_MLX90614 mlx = Adafruit_MLX90614();

void setup() {
   Serial.begin(9600);
   Serial.println("start");
   // starting the MLX90614 sensor
   mlx.begin();
}

void loop() {
   Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempC());
   Serial.print("*C");
   Serial.print("\tObject = "); Serial.print(mlx.readObjectTempC());
   Serial.print("*C");
   Serial.print("\tObject = "); Serial.print(mlx.readObjectTempF());
   Serial.println("*F");
   delay(3000);
}

并打开串口监视器。环境温度和物体温度每3秒输出到串口

步骤 3. 将 OLED 显示器连接到 Arduino MKR 1000 WiFi 板
该项目使用模块形式的 12x32 单色 OLED 显示屏,并在 SSD1306 芯片上进行必要的绑定。这些模块在 I2C 接口上运行。与 Arduino 板的连接图

编程时,我们使用 Adafruit SSD1306 库。将温度输出草图加载到显示器。我们每 3 秒测量一次温度 (mlx90614_02.ino)。

// Connecting libraries
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Creating an instance of an object
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
Adafruit_SSD1306 display(128, 32, &Wire, -1);

float temp;
unsigned long millis1=0;

void setup() {
   Serial.begin(9600);
   // starting display
   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
   display.setTextSize(1);
   display.setTextColor(WHITE);
   // options display
   display.clearDisplay();
   display.display();
   // starting the MLX90614 sensor
   mlx.begin();
   // start
   Serial.println("start");
}

void loop() {
   if(millis()-millis1 >= 3000) {
      display.clearDisplay();
      display.setCursor(10,10);
      display.println(F("Wait temp...."));
      temp=mlx.readObjectTempC();
      display.setCursor(10,20);
      display.print(temp);
      display.print(F(" *C"));
      display.display();
      //
      millis1=millis(); 
   }
}

步骤 4. 将 rc522 RFID 阅读器模块连接到 Arduino MKR 1000 WiFi 板
RFID标签种类繁多。标签是有源和无源的(没有内置电源,由来自阅读器的信号在天线中感应出的电流供电)。标签工作在不同的频率:LF (125 - 134 kHz)、HF (13.56 MHz)、UHF (860 - 960 MHz)。从标签读取信息并将数据写入标签的设备称为阅读器。在 Arduino 项目中,RFID-RC522 模块经常被用作阅读器。该模块是在 NSP 公司的 MFRC522 芯片上制作的,该芯片提供 RA 标签(频率为 13.56 MHz)。

通过 SPI 协议连接到 Arduino MCF 1000 WiFi 卡

RFID 卡的 UID 检测草图、温度测量以及关于打开或关闭输入并输出到串行端口 (mlx90614_03.ino) 的消息。

// Connecting libraries
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include <MFRC522.h>
// Creating an instance of an object
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
Adafruit_SSD1306 display(128, 32, &Wire, -1);
MFRC522 mfrc522(7, 6);

byte cardUID[4] = {0,0,0,0};
int res=1;
float temp;
unsigned long millis1=0;

void setup() {
   Serial.begin(9600);
   // starting display
   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
   display.setTextSize(1);
   display.setTextColor(WHITE);
   display.clearDisplay();
   display.display();
   // starting the MLX90614 sensor
   mlx.begin();
   // запуск SPI
   SPI.begin();
   // initializing MFRC522
   mfrc522.PCD_Init();
   Serial.println("start");
   Serial.println("Wait RFID ....");
}

void loop() {
   switch(res) {
      case 1: // waiting for RFID
         display.clearDisplay();
         display.setCursor(10,10);
         display.print(F("Wait RFID...."));
         // Checking whether the card is attached
         if ( mfrc522.PICC_IsNewCardPresent()) {
            // Reading the map info.
            if ( mfrc522.PICC_ReadCardSerial()) {
               // save UID
               Serial.print(F("Card UID:"));
               display.setCursor(10,20);
               for (byte i = 0; i < 4; i++) {
                  cardUID[i]=mfrc522.uid.uidByte[i];
                  Serial.print(cardUID[i],HEX);
                  display.print(cardUID[i],HEX);
               }
            Serial.println();
            Serial.println("Wait temp....");
            res=3;
            }
         mfrc522.PICC_HaltA();
         mfrc522.PCD_StopCrypto1();
         }
         display.display();
         break;
      case 2: // request to the UID server from the database
         break;
      case 3: // waiting for temperature measurement
         delay(2000);
         display.clearDisplay();
         display.setCursor(10,10);
         display.println(F("Wait temp...."));
         temp=mlx.readObjectTempC();
         display.setCursor(10,20);
         display.print(temp);
         display.print(F(" *C"));
         display.display();
         if(temp>34.0 && temp<42.0) {
            res=5;
         }
         break;
      case 4: // sending temperature data to the server
         break;
      case 5: // open or close
         display.clearDisplay();
         display.setCursor(10,10);
         display.print(F("Temp="));
         display.print(temp);
         display.print(F("*C"));
         display.setCursor(10,20);
         if(temp<37.5) {
            display.print(F("OPEN"));
            Serial.println("OPEN");
         }
         else {
            display.print(F("CLOSE"));
            display.setCursor(10,0);
            display.print(F("Temp high!!!"));
            Serial.println("CLOSE");
            Serial.println("Temp high!!!");
         }
         display.display();
         delay(3000);
         Serial.println("Wait RFID ....");
         res=1;
         break;
      default:
         break;
      }
}

步骤 5. 将 Arduino MKR 1000 WiFi 板连接到互联网
要将 Arduino MKR1000 连接到 Wi-Fi 网络,我们将使用 WiFi101 库,我们将使用库管理器安装该库。

下载将 Arduino MK R 1000 Wi-Fi 板连接到必要接入点的草图。通过在选项卡中输入您的 WiFi 热点数据,将connectWithWPA.ino库中的示例上传到开发板:

#define SECRET_SID "my_D Link"
#define SECRET_PASS "********"

打开串口监视器,您可以在其中观看将 Arduino MKR1000 Wi-Fi 板连接到接入点的过程。

如果连接成功,请继续。

步骤 6. 在公司网站上创建员工数据库和收集入口处每日温度读数的数据库
在主机(MySQL)上创建一个数据库并在其中创建两个表:

  • users- 员工数据及其 uid;
  • temp - 用于收集输入时测量的体温数据。

现在在主机上,我们创建了 2 个脚本来处理 Arduino MKR 1000 WiFi 发送的数据。脚本get_uid.php检查数据库中的 ID 并在响应中返回:

• #no – 如果 uid 不在数据库中

• #yes;<name> - 如果 uid 在数据库中

脚本get_uid.php的内容

<?php
//
$location="localhost";
$user="************";
$pass="************";
$db_name="************";
// connect db
if(! $db=mysqli_connect($location,$user,$pass,$db_name))
   {echo "connect error";}
else
   {;}
$query0=" SELECT * FROM users WHERE uid='".$_GET['uid']."' ";
$rez0=mysqli_query($db,$query0);
if(mysqli_num_rows($rez0)>0) {
   $row0=mysqli_fetch_assoc($rez0);
   echo "#yes".";".$row0[name];
}
else {
   echo "#no";
}
?>

可以通过从浏览器发送请求来测试脚本:

脚本get_temp.php将员工的体温发送到数据库

脚本get_temp.php的内容

<?php
//
$location="localhost";
$user="************";
$pass="************";
$db_name="************";
// connect db
if(! $db=mysqli_connect($location,$user,$pass,$db_name))
   {echo "connect error";}
else
   {;}
$query0=" SELECT * FROM users WHERE uid='".$_GET['uid']."' ";
$rez0=mysqli_query($db,$query0);
if(mysqli_num_rows($rez0)>0) {
   $row0=mysqli_fetch_assoc($rez0);
   $query1=" INSERT INTO temp SET
      id_user='".$row0['id']."',
      temp='".$_GET['temp']."',
      day='".date('Y-m-d H:i:s')."' ";
   mysqli_query($db,$query1);
   echo "#yes";
}
else {
   echo "#no";
}
?>

可以通过从浏览器发送请求来测试脚本:

步骤 7. 将数据从 Arduino MKR 1000 WiFi 发送到公司网站
两个函数:

  • send_uid_to_server() ——发送uid到服务器;
  • send_temp_to_server () - 将温度发送到服务器。

函数send_uid_to_server()

int send_uid_to_server() {
   int ret=3;
   unsigned long previos;
   int x=0;int f=0;
   char s;
   client.stop();
   if (client.connect(server, 80)) {
      //// sending data to the server
      // forming a string
      // uid per line
      String str="/firm/get_uid.php?uid=";
      for (byte i = 0; i < 4; i++) {
         str+=String(cardUID[i],HEX);
      }
      Serial.print("str=");Serial.println(str);
      client.println("GET "+str+" HTTP/1.1");
      client.println("Host: freeparkovka.ru");
      client.println("User-Agent: ArduinoWiFi/1.1");
      client.println("Connection: close");
      client.println();
      // получение ответа
      previos=millis();
      for(int i=0;i<40;i++)
         response[i]=0;
      do {
         if(client.available() > 0) {
            // get data from the server
            s = client.read();
            if(s=='#')
               f=1;
            if(f==1) {
               response[x]=s;
               x++;
            }
         Serial.write(s);
         }
      }
      while((millis() - previos) < 5000);
      if(response[0]='#') {
         ret=command(response);
      }
      Serial.println(response);
      //client.stop();
      return ret;
   }
   else {
      // no connection
      Serial.println("connection failed");
      //client.stop();
      return 3;
   }
}

函数send_temp_to_server()

void send_temp_to_server() {
   client.stop();
   if (client.connect(server, 80)) {
      //// sending data to the server
      // forming a string
      // uid per line
      String str="/firm/get_temp.php?uid=";
      for (byte i = 0; i < 4; i++) {
         str+=String(cardUID[i],HEX);
      }
      str+="&temp="+String(temp);
      Serial.print("str=");Serial.println(str);
      client.println("GET "+str+" HTTP/1.1");
      client.println("Host: freeparkovka.ru");
      client.println("User-Agent: ArduinoWiFi/1.1");
      client.println("Connection: close");
      client.println();
      Serial.println(response);
      delay(10); }
   else {
      // no connection
      Serial.println("connection failed");
   }
}
步骤 8. 添加继电器以启用/禁用输入
添加继电器以启用/禁用企业入口,具体取决于温度值。连接图:

并根据温度数据添加启用/禁用继电器以打开或关闭输入的代码。

if(temp<37.5) { // OPEN
   display.setCursor(10,0);
   display.print(F("OPEN"));
   Serial.println("OPEN");
   digitalWrite(pinRelay,HIGH);
}
else { // CLOSE
   display.print(F("CLOSE"));
   display.setCursor(10,0);
   display.print(F("Temp high!!!"));
   Serial.println("CLOSE");
   Serial.println("Temp high!!!");
   digitalWrite(pinRelay,LOW);
}

// Connecting libraries
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SPI.h>
#include <MFRC522.h>
#include <WiFi101.h>
// Creating object instances
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
Adafruit_SSD1306 display(128, 32, &Wire, -1);
MFRC522 mfrc522(7, 6);
WiFiClient client;
// your network SSID (name)
// and password (WPA)
char ssid[] = "my_DLink";
char pass[] = "********";
// name address
char server[] = "www.freeparkovka.ru";
int pinRelay=5;
int status = WL_IDLE_STATUS;
char response[40];
byte cardUID[4] = {0,0,0,0};
int res=0;
int rr;
float temp;
unsigned long millis1=0;
unsigned long millis2=0;
unsigned long millis3=0;

void setup() {
   Serial.begin(9600);
   // relay
   pinMode(pinRelay,OUTPUT);
   digitalWrite(pinRelay,LOW);
   // display
   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
   display.setTextSize(1);
   display.setTextColor(WHITE);
   display.clearDisplay();
   display.display();
   // starting the sensor MLX90614
   mlx.begin();
   // запуск SPI
   SPI.begin();
   // initializing MFRC522
   mfrc522.PCD_Init();
   Serial.println("connect WiFi ....");
   display.setCursor(10,10);
   display.print(F("Connect WiFi"));
   display.display();
   // check for the presence of the shield:
   if (WiFi.status() == WL_NO_SHIELD) {
      Serial.println("WiFi shield not present");
      // don't continue:
      while (true);
   }
   // attempt to connect to WiFi network:
   while ( status != WL_CONNECTED) {
      Serial.print("Attempting to connect to WPA SSID: ");
      Serial.println(ssid);
      // Connect to WPA/WPA2 network:
      status = WiFi.begin(ssid, pass);
      // wait 5 seconds for connection:
      delay(5000);
   }
   display.setCursor(30,20);
   display.print(F("ok"));
   display.display();
   printWiFiStatus();
   delay(2000);
   Serial.println("Wait RFID ....");
}

void loop() {
   switch(res) {
      case 0:  //
         send_display("Wait RFID....");
         res=1;
         break;
      case 1:  // waiting for RFID
         // Check whether the card is attachedа
         if ( mfrc522.PICC_IsNewCardPresent()) {
            // Reading the map info
            if ( mfrc522.PICC_ReadCardSerial()) {
               // save UID
               Serial.print(F("Card UID:"));
               display.setCursor(10,20);
               for (byte i = 0; i < 4; i++) {
                  cardUID[i]=mfrc522.uid.uidByte[i];
                  Serial.print(cardUID[i],HEX);
                  display.print(cardUID[i],HEX);
               }
               Serial.println();
               res=2;
               display.display();
               delay(2000);
               Serial.println("send uid to server....");
            }  
            mfrc522.PICC_HaltA();
            mfrc522.PCD_StopCrypto1();
         }
         display.display();
         break;
      case 2:  // request to the UID server from the database
         send_display("Send server...");
         rr=send_uid_to_server();
         if(rr==1) {
            res=3;
            display.setCursor(10,0);
            display.print(F("uid ok"));
            millis3=millis();
         }
         else if(rr==2) {
            res=0;
            display.setCursor(10,0);
            display.print(F("incorrect"));
         }
         else  {
            res=0;
            display.setCursor(10,0);
            display.print(F("error 404"));
         }
         display.display();
         delay(3000);
         break;
      case 3:  // waiting for temperature measurement
         if(millis()-millis3<10000) {
            send_display("Wait temp....");
            temp=mlx.readObjectTempC();
            display.setCursor(10,20);
            display.print(temp);
            display.print(F(" *C"));
            display.display();
            if(temp>34.0 && temp<42.0) {
               res=4;
               delay(2000);
            }
         }
         else {
            res=0;
         }
         break;
      case 4:  // sending temperature data to the server
         send_display("Wait temp....");
         send_temp_to_server();
         res=5;
         delay(2000);
         break;
      case 5:  // open or close 
         display.clearDisplay();
         display.setCursor(10,10);
         display.print(F("Temp="));
         display.print(temp);
         display.print(F("*C"));
         display.setCursor(10,20);
         if(temp<37.5) { // OPEN
            display.print(F("OPEN"));
            Serial.println("OPEN");
            digitalWrite(pinRelay,HIGH);
         }
         else {  // CLOSE
            display.print(F("CLOSE"));
            display.setCursor(10,0);
            display.print(F("Temp high!!!"));
            Serial.println("CLOSE");
            Serial.println("Temp high!!!");
            digitalWrite(pinRelay,LOW);
         }
         display.display();
         delay(3000);
         Serial.println("Wait RFID ....");
         res=0;
         break;
      default:
         break;
   }
}

//
void printWiFiStatus() {
   // print the SSID of the network you're attached to:
   Serial.print("SSID: ");
   Serial.println(WiFi.SSID());
   // print your WiFi shield's IP address:
   IPAddress ip = WiFi.localIP();
   Serial.print("IP Address: ");
   Serial.println(ip);
   // print the received signal strength:
   long rssi = WiFi.RSSI();
   Serial.print("signal strength (RSSI):");
   Serial.print(rssi);
   Serial.println(" dBm");
}
//
int send_uid_to_server() {
   int ret=3;
   unsigned long previos;
   int x=0;int f=0;
   char s;
   client.stop();
   if (client.connect(server, 80)) {
      //// sending data to the server
      // forming a string
      // uid per line
      String str="/firm/get_uid.php?uid=";
      for (byte i = 0; i < 4; i++) {
         str+=String(cardUID[i],HEX);
      }
      Serial.print("str=");Serial.println(str);
      client.println("GET "+str+" HTTP/1.1");
      client.println("Host: freeparkovka.ru");
      client.println("User-Agent: ArduinoWiFi/1.1");
      client.println("Connection: close");
      client.println();
      // получение ответа
      previos=millis();
      for(int i=0;i<40;i++)
         response[i]=0;
      do {
         if(client.available() > 0) {
            // get data from the server
            s = client.read();
            if(s=='#')
               f=1;
            if(f==1) {
               response[x]=s;
               x++;
            }
         Serial.write(s);
         }
      }
      while((millis() - previos) < 5000);
      if(response[0]='#') {
         ret=command(response);
      }
      Serial.println(response);
      //client.stop();
      return ret;
   }
   else {
      // no connection
      Serial.println("connection failed");
      //client.stop();
      return 3;
   }
}
//
void send_temp_to_server() {
   client.stop();
   if (client.connect(server, 80)) {
      //// sending data to the server
      // forming a string
      // uid per line
      String str="/firm/get_temp.php?uid=";
      for (byte i = 0; i < 4; i++) {
         str+=String(cardUID[i],HEX);
      }
      str+="&temp="+String(temp);
      Serial.print("str=");Serial.println(str);
      client.println("GET "+str+" HTTP/1.1");
      client.println("Host: freeparkovka.ru");
      client.println("User-Agent: ArduinoWiFi/1.1");
      client.println("Connection: close");
      client.println();
      Serial.println(response);
      delay(10); }
   else {
      // no connection
      Serial.println("connection failed");
   }
}
// checking commands that came from the server
int command(char* arr) {
   String str(arr);
   //
   if(str.indexOf("yes")!=-1) {
      return 1;
   }
   else if(str.indexOf("no")!=-1) {
      return 2;
   }
   return 3;
}
// display output
void send_display(String str) {
   display.clearDisplay();
   display.setCursor(10,10);
   display.print(str);
   display.display();
}
步骤 9. 远程查看员工体温数据的页面
要查看发送到服务器的数据,请打开站点页面。脚本内容输出页面文件view_temp.php

<?php
//
$location="localhost";
$user="********";
$pass="********";
$db_name="********";
// connect db
if(! $db=mysqli_connect($location,$user,$pass,$db_name))
{echo "connect error";}
else
{;}
$query0=" SELECT * FROM temp WHERE uid='".$_GET['uid']."' ";
$rez0=mysqli_query($db,$query0);
$content1.=date('Y-m-d')."<br><br>";
$content1.="

<table>";
$query1="SELECT * FROM temp WHERE day >= CURDATE() ";
$rez1=mysqli_query($db,$query1); $i=1;
while($row1=mysqli_fetch_assoc($rez1)) {
   $content1.="<tr>";
   $content1.="<td>".$i."</td>";
   $rez2=mysqli_query($db,"SELECT name FROM users WHERE id =".$row1['id_user']." ");
   $row2=mysqli_fetch_assoc($rez2);
   $content1.="<td>".$row2['name']."</td>";
   $content1.="<td>".mb_substr($row1['day'],10,9)."</td>";
   if($row1['temp']>37.5)
      $content1.="<td style='background-color:red'>".$row1['temp']."</td>";
   else
      $content1.="<td>".$row1['temp']."</td>";
   $content1.="</tr>";
   $i++;
}
$content1.="</table>
";
echo $content1;
?>

如果您对此项目有任何想法、意见或问题,请在下方留言。

以上内容翻译自网络,原作者:VPA,如涉及侵权,可联系删除。

加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论