0% found this document useful (0 votes)
6 views9 pages

Controle de Acesso RFID com ESP32

Uploaded by

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

Controle de Acesso RFID com ESP32

Uploaded by

Marcos Eduardo
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Projeto completo: Controle de Acesso RFID

(ESP32 + WebSocket + React)


Este repositório contém três partes:

• server/ — WebSocket server em [Link] (Express + ws) e REST simples para gerenciar UIDs
autorizados.
• frontend/ — App React (Vite) que mostra notificações de leitura e permite liberar a porta.
• esp32/ — Código Arduino (ESP32) para leitor RC522 que se conecta ao servidor via WebSocket.

Árvore de arquivos

acesso-rfid-project/
├─ server/
│ ├─ [Link]
│ ├─ [Link]
│ ├─ .[Link]
│ └─ [Link]
├─ frontend/
│ ├─ [Link]
│ ├─ [Link]
│ └─ src/
│ ├─ [Link]
│ ├─ [Link]
│ └─ [Link]
└─ esp32/
└─ esp32_rfid_ws.ino

server/[Link]

{
"name": "acesso-rfid-server",
"version": "1.0.0",
"main": "[Link]",
"scripts": {
"start": "node [Link]"
},
"dependencies": {
"express": "^4.18.2",
"ws": "^8.13.0",
"body-parser": "^1.20.2",
"dotenv": "^16.0.3"

1
}
}

server/.[Link]

PORT=3000
AUTHORIZED_UIDS=A1:B2:C3:D4

server/[Link]

require('dotenv').config();
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const bodyParser = require('body-parser');

const app = express();


[Link]([Link]());

// Config
const PORT = [Link] || 3000;
const initial = ([Link].AUTHORIZED_UIDS || '').split(',').map(s =>
[Link]()).filter(Boolean);

// Memory stores (replace with DB in produção)


const authorized = new Set(initial);
const connectedESP = new Map(); // deviceId -> ws
const webClients = new Set();

const server = [Link](app);


const wss = new [Link]({ server });

[Link]('connection', function connection(ws, req) {


[Link]('[WS] connected');

[Link]('message', function incoming(message) {


try {
const msg = [Link]([Link]());
handleMessage(ws, msg);
} catch (e) {
[Link]('[WS] invalid message', e);
}
});

2
[Link]('close', () => {
for (const [id, socket] of [Link]()) {
if (socket === ws) [Link](id);
}
[Link](ws);
});
});

function handleMessage(ws, msg) {


if (!msg || ![Link]) return;

if ([Link] === 'hello' && [Link]) {


[Link]([Link], ws);
[Link] = [Link];
[Link]('[WS] ESP connected:', [Link]);
return;
}

if ([Link] === 'scan' && [Link] && [Link]) {


const payload = {
type: 'card_scanned',
uid: [Link],
deviceId: [Link],
time: new Date().toISOString(),
authorized: [Link]([Link])
};
for (const client of webClients) {
if ([Link] === [Link])
[Link]([Link](payload));
}
[Link]('[WS] scan', [Link], 'authorized?',
[Link]([Link]));
return;
}

if ([Link] === 'register_web') {


[Link](ws);
[Link] = true;
[Link]('[WS] web client registered');
return;
}

if ([Link] === 'grant_request' && [Link] && [Link]) {


const deviceWs = [Link]([Link]);
if (!deviceWs) {
if (ws && [Link] && [Link] === [Link])
[Link]([Link]({ type: 'error', message: 'device offline' }));
return;
}
const grant = { type: 'grant', uid: [Link], duration: [Link] ||
3000 };

3
[Link]([Link](grant));
for (const client of webClients) {
if ([Link] === [Link]) [Link]([Link]({
type: 'grant_event', uid: [Link], deviceId: [Link], by: 'web' }));
}
[Link]('[WS] grant sent for', [Link], 'to', [Link]);
return;
}
}

// Simple REST API to view and manage authorized UIDs


[Link]('/api/authorized', (req, res) => {
[Link]([Link](authorized));
});
[Link]('/api/authorized', (req, res) => {
const { uid } = [Link];
if (!uid) return [Link](400).json({ error: 'uid required' });
[Link](uid);
[Link]({ ok: true });
});
[Link]('/api/authorized', (req, res) => {
const { uid } = [Link];
[Link](uid);
[Link]({ ok: true });
});

[Link](PORT, () => [Link]('Server listening on', PORT));

server/[Link]

# Server WebSocket - Acesso RFID

Instalação:

```bash
cd server
npm install
cp .[Link] .env
# ajustar .env
npm start

O servidor escuta na porta configurada ( PORT ).

Endpoints REST: /api/authorized (GET, POST, DELETE) para gerenciar UIDs.

WebSocket: [Link] — o servidor aceita mensagens JSON conforme protocolo.

4
---

# frontend/[Link]

```json
{
"name": "acesso-rfid-frontend",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"vite": "5.0.0"
}
}

frontend/[Link]

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Acesso RFID</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/[Link]"></script>
</body>
</html>

frontend/src/[Link]

import React from 'react'


import { createRoot } from 'react-dom/client'
import App from './App'

5
import './[Link]'

createRoot([Link]('root')).render(<App />)

frontend/src/[Link]

import React, { useEffect, useState } from 'react'

const WS_URL = [Link].VITE_WS_URL || '[Link]

export default function App(){


const [ws, setWs] = useState(null);
const [events, setEvents] = useState([]);

useEffect(() => {
const socket = new WebSocket(WS_URL);
[Link]('open', () => {
[Link]([Link]({ type: 'register_web' }));
});
[Link]('message', e => {
try{
const msg = [Link]([Link]);
if ([Link] === 'card_scanned') setEvents(ev => [msg, ...ev]);
else [Link]('ws msg', msg);
}catch(err){ [Link](err) }
});
setWs(socket);
return () => [Link]();
}, []);

function handleLiberar(ev){
if (!ws || [Link] !== [Link]) return alert('Conexão WS
fechada');
[Link]([Link]({ type: 'grant_request', uid: [Link], deviceId:
[Link], duration: 3000 }));
}

return (
<div style={{ padding: 20, fontFamily: 'Arial, sans-serif' }}>
<h1>Controle de Acesso (WS)</h1>
<div>
{[Link] === 0 && <div>Nenhuma leitura ainda</div>}
{[Link]((ev, i) => (
<div key={i} style={{ border: '1px solid #ddd', padding: 10,
marginBottom: 8 }}>
<div><b>UID:</b> {[Link]}</div>
<div><b>Device:</b> {[Link]}</div>
<div><b>Hora:</b> {new Date([Link]).toLocaleString()}</div>

6
<div><b>Autorizado:</b> {[Link] ? 'SIM' : 'NÃO'}</div>
<button onClick={() => handleLiberar(ev)} style={{ marginTop:
6 }}>Liberar</button>
</div>
))}
</div>
</div>
)
}

frontend/src/[Link]

body { margin: 0; padding: 0; }

esp32/esp32_rfid_ws.ino

#include <SPI.h>
#include <MFRC522.h>
#include <WiFi.h>
#include <WebSocketsClient.h>

#define RST_PIN 22
#define SS_PIN 21
MFRC522 rfid(SS_PIN, RST_PIN);

const char* ssid = "SEU_SSID";


const char* pass = "SUA_SENHA";
const char* wsHost = "SEU_SERVIDOR_IP"; // ex: [Link]
uint16_t wsPort = 3000;

WebSocketsClient webSocket;

void webEvent(WStype_t type, uint8_t * payload, size_t length) {


switch(type) {
case WStype_CONNECTED:
[Link]("[WS] connected");
[Link]("{\"type\":\"hello\",\"deviceId\":\"esp01\"}");
break;
case WStype_TEXT:
{
String msg = String((char*)payload);
[Link]("[WS] msg: " + msg);
if ([Link]("\"type\":\"grant\"") >= 0) {
int dpos = [Link]("\"duration\":");

7
int duration = 3000;
if (dpos > 0) {
int start = dpos + 11;
int end = [Link]('}', start);
if (end > start) duration = [Link](start, end).toInt();
}
openDoor(duration);
}
}
break;
default:
break;
}
}

void openDoor(int ms) {


[Link]("Abrindo porta por ms: " + String(ms));
digitalWrite(2, HIGH);
delay(ms);
digitalWrite(2, LOW);
}

void setup() {
[Link](115200);
[Link]();
rfid.PCD_Init();
pinMode(2, OUTPUT);
digitalWrite(2, LOW);

[Link](ssid, pass);
[Link]("Conectando WiFi");
while ([Link]() != WL_CONNECTED) {
delay(500);
[Link](".");
}
[Link]("\nWiFi ok");

[Link](wsHost, wsPort, "/");


[Link](webEvent);
[Link](5000);
}

void loop() {
[Link]();
if ( ! rfid.PICC_IsNewCardPresent()) return;
if ( ! rfid.PICC_ReadCardSerial()) return;

String uid = "";


for (byte i = 0; i < [Link]; i++) {
if (i > 0) uid += ":";
if ([Link][i] < 0x10) uid += "0";

8
uid += String([Link][i], HEX);
}
[Link]();
[Link]("Leu UID: " + uid);

String payload = "{\"type\":\"scan\",\"uid\":\"" + uid + "\",\"deviceId\":


\"esp01\"}";
[Link](payload);
delay(1000);
}

Como usar (resumo rápido)


1. Server:
2. cd server
3. npm install
4. copiar .[Link] para .env e ajustar PORT e AUTHORIZED_UIDS (ex:
A1:B2:C3:D4 )

5. npm start

6. Frontend:

7. cd frontend
8. npm install
9. ajustar VITE_WS_URL se necessário (ou editar src/[Link] para apontar para o servidor)

10. npm run dev

11. ESP32:

12. abrir esp32/esp32_rfid_ws.ino


13. ajustar ssid , pass e wsHost para o IP do servidor
14. compilar e enviar para a placa

Observações e próximos passos recomendados


• Em produção, substitua o armazenamento em memória por um banco (SQLite/Postgres).
• Adicione autenticação no painel (login + JWT) e valide grant_request no servidor.
• Use wss:// (TLS) via proxy reverso (Nginx) em produção.
• Proteja endpoints REST com autenticação.

Se quiser, eu adapto o projeto para adicionar autenticação JWT no servidor e no frontend, ou para usar
[Link] em vez de ws . Diga qual opção prefere.

You might also like