💡 划重点

  • 用一张几毛钱的 NFC 卡片,在 ESP32 终端上“滴”一下,即刻完成自习馆签到,签到记录自动推送至飞书群,管理者不用再人工点名、核对时间。整套方案硬件成本控制在 80 元以内,学生团队、创业自习室都能轻松复刻。核心亮点:双设备复用 I2C 总线节约引脚,本地 OLED 实时反馈,飞书 Webhook 实现零服务器运维的日志归档,外加一颗物理按键用于手动补

需求洞察

目标用户:自习馆主理人、合作社运营者以及日常签到打卡的会员。他们往往没有专职前台,依赖微信群接龙或纸质登记,一到旺季就出现漏签、蹭卡、数据对不上的麻烦。

真实痛点:人工签到效率低、容易遗漏,事后追溯靠聊天记录极不可靠;传统的指纹机或刷卡器价格偏高、部署复杂,且数据无法即时同步给合作方;小型场馆需要一种便宜、直观、能证明“某人在某时刻来过”的轻量方案。

为什么值得做:一套 80 元的终端就能把签到行为数字化,减少人肉管理的同时,还能通过飞书机器人自动通知“张三 已签到 14:02”,让管理员和合伙人第一时间看到实况。签到数据可扩展为出勤统计、扣费依据、座位释放信号,商业价值远高于硬件投入。而且技术门槛低,适合 Maker 和教育场景,很容易在社区复制推广。

方案设计

整体按四层结构展开,各层职责清晰,便于调试和维护。

感知层:由 PN532 NFC 模块和物理按键组成。PN532 负责读取 M1 卡、NTAG 等符合 ISO14443 协议的卡片 UID,按键用于触发补签模式、清屏或长按重启。所有输入信号统一交给 ESP32 处理。

控制层:ESP32 作为主控,运行 Arduino 框架。轮询 PN532 的读卡事件,解析卡号后与本地白名单匹配,同时驱动 OLED 显示签到结果,并通过板载 Wi‑Fi 调用飞书 Webhook 完成数据上报。控制层还负责按键消抖、LED 状态指示和通信异常重试。

执行层:一块 0.96 寸 I2C OLED 屏显示“请刷卡”、姓名、签到时间灯信息;一颗高亮 LED(接 GPIO2)在刷卡成功时闪烁,失败时常亮两秒。这些输出直接给用户清晰的行为反馈,减少误刷卡带来的困惑。

日志 / 联网层:不依赖自建服务器,直接使用飞书机器人的 Webhook 接口。ESP32 通过 HTTPS POST 发送 JSON 格式消息,内容包括卡片 UID、签到时间戳、设备 ID 等字段。飞书群即时弹窗通知,同时群消息可沉淀为永久签到日志。后续如需数据分析,可以在飞书侧设置机器人回调,或定期导出消息记录。

物料清单

物料名称 数量 用途 估算单价(元)
ESP32 DevKit 1 主控与 Wi‑Fi 通信 18
PN532 NFC 模块 (I2C) 1 读取卡片 UID 25
0.96 寸 OLED (SSD1306) 1 显示签到信息 12
轻触按键 1 补签/复位功能 0.5
LED (5mm 红) 1 状态指示 0.2
220Ω 电阻 1 LED 限流 0.1
面包板 + 跳线 1 套 原型搭建 8
Micro‑USB 电源线 1 供电 2
合计 65.8

剩余预算可用来补充外壳或焊接 PCB,总体控制在 80 元以内完全可行。

接线与结构

本方案严格遵循题目建议,同时微调按键引脚以避免与 I2C 冲突,具体接线如下:

结构上,建议将 ESP32、PN532 和 OLED 固定在一块亚克力面板上,NFC 感应区朝外,面板开孔露出屏幕和按键,内部用热熔胶或螺丝固定。这样既美观又能快速拆装调试。

核心代码

以下是基于 Arduino 框架在 PlatformIO 下可编译的骨架代码,展示了 NFC 读卡、OLED 显示与飞书 Webhook 的核心逻辑。


#include <Wire.h>
#include <Adafruit_PN532.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <HTTPClient.h>

#define PN532_IRQ  -1
#define OLED_ADDR  0x3C
#define LED_PIN    2
#define BTN_PIN    4

#define WIFI_SSID   "your_ssid"
#define WIFI_PASS   "your_pw"
#define WEBHOOK_URL "https://open.feishu.cn/open-apis/bot/v2/hook/xxxx"

Adafruit_PN532 nfc(21, 22);
Adafruit_SSD1306 display(128, 64, &Wire, -1);

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  Wire.begin(21, 22);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(10, 20);
  display.println("Scan Card");
  display.display();

  nfc.begin();
  uint32_t versiondata = nfc.getFirmwareVersion();
  if (!versiondata) {
    display.clearDisplay();
    display.setCursor(0, 20);
    display.println("PN532 fail");
    display.display();
    while (1);
  }
  nfc.SAMConfig();

  while (WiFi.status() != WL_CONNECTED) { delay(500); }
}

void loop() {
  uint8_t uid[] = {0,0,0,0,0,0,0};
  uint8_t uidLength;
  if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 100)) {
    String cardID = "";
    for (uint8_t i = 0; i < uidLength; i++) {
      cardID += String(uid[i], HEX);
    }
    display.clearDisplay();
    display.setCursor(10, 20);
    display.println("OK");
    display.setCursor(10, 40);
    display.println(cardID);
    display.display();
    digitalWrite(LED_PIN, HIGH);
    delay(200);
    digitalWrite(LED_PIN, LOW);

    HTTPClient http;
    http.begin(WEBHOOK_URL);
    http.addHeader("Content-Type", "application/json");
    String payload = "{\"msg_type\":\"text\",\"content\":{\"text\":\"签到: " + cardID + " 时间: " + String(millis()) + "\"}}";
    http.POST(payload);
    http.end();
  }
  if (digitalRead(BTN_PIN) == LOW) {
    display.clearDisplay();
    display.setCursor(10, 20);
    display.println("Manual");
    display.display();
    delay(1000);
    display.clearDisplay();
    display.setCursor(10, 20);
    display.println("Scan Card");
    display.display();
  }
}

上面的代码可在 Arduino IDE 或 PlatformIO 中直接编译,需要提前安装 Adafruit_PN532Adafruit_GFXAdafruit_SSD1306 三个库。生产使用时请替换真实的 Wi‑Fi 信息和飞书 Webhook 地址,并可增加白名单匹配、RTC 时间同步等逻辑。

调试步骤

  1. I2C 地址确认:先用 I2C Scanner 例程检查 PN532(0x24)和 OLED(0x3C)是否同时在线,确保总线无冲突。
  2. NFC 读卡测试:单独运行 PN532 示例代码,刷卡后观察串口输出 UID,验证识别距离和卡片类型。
  3. 飞书 Webhook 联通:编写一个最小化的 POST 测试程序,向飞书机器人发送固定消息,确认网络和 JSON 格式无误。
  4. 整机联调:下载完整骨架,刷卡一次,查看 OLED 是否更新、LED 是否闪烁、飞书群是否弹出通知。若有延迟,检查 HTTPS 证书或更换 DNS。
  5. 按键功能测试:按下按键,屏幕显示“Manual”后切换回欢迎界面,可进一步扩展为补签逻辑。
  6. 稳定性观察:连续刷卡几十次,观察有无死机、掉网或 I2C 挂死现象,必要时在循环中加入看门狗复位。

设计图

NFC 打卡自习馆签到结构flow
1
感知输入
2
控制处理
3
执行反馈
4
数据上报

在图示流程中,NFC 卡片靠近天线后被 PN532 捕获 UID(感知输入),ESP32 负责解析并与本地白名单比对,同时驱动屏幕和 LED(控制处理),随后用户看到签到成功提示(执行反馈),最后通过 Wi‑Fi 将结构化记录推送至飞书 Webhook(数据上报)。整个链路闭环在 700 毫秒内完成,做到了“即刷即走、即时通知”。