The Meeting Attendance Swipe is a project I've built and iterated through over the last few months. It's an ESP8266 powered project that has an RFID reader in it for recording members' attendance at HSBNE.

Hardware

  • A Lolin esp8266 development board and base board.
  • A 3xAA battery pack.
  • A single WS2812b addressable RGB LED
  • A Seeedstudio Grove - 125KHz RFID Reader
  • A funky case based on Parametric Flexbox by bdahlem

Here's all the laser cut parts and the development board I originally was using but had issues using any particular pin for software serial.
Laser Cut Parts

And here it is while gluing together the case. I found out that the living hinges on the flexbox weren't great on 3mm acrylic and would break so I snapped them off cleanly.

Software

The software side of things is a very simple C program written in the Arduino IDE using ESP8266 custom board support.

On boot it connects to a wireless network and then waits for a serial message on a digital pin of the RFID tag swiped on the reader. It then massages this tag ID to remove the manufacturer code and CRC and then turn it into the decimal representation of the tag ID.

Once it has the tag ID in decimal format it sends it off to our access system and waits for a response, turning the WS2812b yellow. Based on that response it will then either turn the WS2812b green or red depending on whether or not the user is in the system and is paid up.

I've posted some example code below sans passwords to demonstrate how I implemented it in C.

/*
 *  Simple HTTP get webclient test
 */
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
const char* ssid     = "wifissid";  
const char* password = "wifipassword";  
const char* host = "accessystemurl";  
SoftwareSerial swSer(4, 5, 128);  
String rawtag; // buffer string for data receive over serial port

void setup() {  
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(14, OUTPUT);
  Serial.begin(112500);
  delay(10);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

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

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  swSer.begin(9600);
  Serial.println("Serial Started");
}


void loop() {

  while (swSer.available()) {
       delay(10);  
         if (swSer.available() >0) {
       char c = swSer.read();
       rawtag += c;}
       }

     if (rawtag.length() >0) {
     Serial.println(rawtag);
     String tagID = rawtag.substring(5,11);
     Serial.println(tagID);
     long tagIDDEC = hexToDec(tagID);
     Serial.println(tagIDDEC);
     checkcard(tagIDDEC);
     delay(3000);
     rawtag="";
     } 
}


void checkcard(long tagid) {

  // ++value;
  digitalWrite(13, HIGH);
  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URI for the request
  String url = "/logger.php?q=" + String(tagid) + "";
  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  delay(10);

  // Read all the lines of the reply from server and print them to Serial
  digitalWrite(13, LOW);
  digitalWrite(12, HIGH);
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }

  Serial.println();
  Serial.println("closing connection");
  digitalWrite(12, LOW);
}


unsigned long hexToDec(String hexString) {

  unsigned long decValue = 0;
  int nextInt;

  for (int i = 0; i < hexString.length(); i++) {

    nextInt = int(hexString.charAt(i));
    if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
    if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
    if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
    nextInt = constrain(nextInt, 0, 15);

    decValue = (decValue * 16) + nextInt;
  }

  return decValue;
}

As you can see in this version I'm missing the ws2812b controlling part, it should also be noted that I'm using a different softwareserial library than the default one on the Arduino IDE. You can find it at https://github.com/plerup/espsoftwareserial .

If you have any queries, please feel free to ask in the comments or poke me on social media.