Evan Rust
Published © GPL3+

Raspberry Pi NFC Clothes Tracker

Use DFRobot's PN532 NFC module to track if your favorite clothes are clean or dirty.

BeginnerFull instructions provided1 hour6,547
Raspberry Pi NFC Clothes Tracker

Things used in this project

Hardware components

DFRobot Raspberry Pi 3
×1
DFRobot PN532 NFC Module
×1
DFRobot NFC RFID Card 13.56 MHz
×5
Arduino Mega 2560
Arduino Mega 2560
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Schematic

Code

Python Code

Python
import serial

ser = serial.Serial("/dev/ttyACM0",baudrate=9600)


#example information
card_stats = {"Card 0":{"name":"Blank T-shirt","color":"Blue","status":"clean"},
              "Card 1":{"name":"T-shirt","color":"Red","status":"dirty"},
               "Card 2":{"name":"gym shorts","color":"black","status":"clean"},
                "Card 3":{"name":"test1","color":"yellow","status":"clean"},
                 "Card 4":{"name":"test2","color":"green","status":"dirty"}}
                  

while 1:
    if ser.inWaiting():
        data = ser.readline()
        print(data)
        if "Card" in data:
            data = data[0:6]
            print(card_stats[data]["color"]+" "+card_stats[data]["name"])
            print("Status: "+card_stats[data]["status"])
            choice=raw_input("Would you like to change the status? (Y or N) ")
            if choice=="Y":
                new_status = raw_input("Type 'C or 'D to change the status: ")
                if new_status=="C":
                    card_stats[data]["status"] = "clean"
                    print(card_stats[data]["status"])
                elif new_status=="D":
                    card_stats[data]["status"] = "dirty"
                    print(card_stats[data]["status"])
            print("Thank you")
            

Arduino Mega Code

C/C++
const unsigned char wake[24]={
  0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xfd, 0xd4, 0x14, 0x01, 0x17, 0x00};//wake up NFC module
const unsigned char firmware[9]={
  0x00, 0x00, 0xFF, 0x02, 0xFE, 0xD4, 0x02, 0x2A, 0x00};//
const unsigned char tag[11]={
  0x00, 0x00, 0xFF, 0x04, 0xFC, 0xD4, 0x4A, 0x01, 0x00, 0xE1, 0x00};//detecting tag command
const unsigned char std_ACK[25] = {
  0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x0C, \
0xF4, 0xD5, 0x4B, 0x01, 0x01, 0x00, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x00};
unsigned char old_id[5];

unsigned char receive_ACK[25];//Command receiving buffer
//int inByte = 0;               //incoming serial byte buffer

int known_ids[] = {833,538,881,961,574};

#if defined(ARDUINO) && ARDUINO >= 100
#include <stdlib.h>
long strtol (const char *__nptr, char **__endptr, int __base);
#include "Arduino.h"
#define print1Byte(args) Serial1.write(args)
#define print1lnByte(args)  Serial1.write(args),Serial1.println()
#else
#include "WProgram.h"
#define print1Byte(args) Serial1.print(args,BYTE)
#define print1lnByte(args)  Serial1.println(args,BYTE)
#endif

void setup(){
  Serial.begin(9600);  // open serial with PC
  Serial1.begin(115200);  //open serial1 with device
  //Serial2.begin(115200);
  wake_card();
  delay(100);
  read_ACK(15);
  delay(100);
  display(15);
}

void loop(){
  send_tag(); 
  read_ACK(25);
  delay(100);
  if (!cmp_id ()) {
    if (test_ACK ()) {
      send_id();
      //display (25);
      delay (100);
    }
  }
  copy_id ();
}

void copy_id (void) {//save old id
  int ai, oi;
  for (oi=0, ai=19; oi<5; oi++,ai++) {
    old_id[oi] = receive_ACK[ai];
  }
}
 
char cmp_id (void){//return true if find id is old
  int ai, oi;
  for (oi=0,ai=19; oi<5; oi++,ai++) {
    if (old_id[oi] != receive_ACK[ai])
      return 0;
  }
  return 1;
}

int test_ACK (void) {// return true if receive_ACK accord with std_ACK
  int i;
  for (i=0; i<19; i++) {
    if (receive_ACK[i] != std_ACK[i])
      return 0;
  }
  return 1;
}

void send_id (void) {//send id to PC
  int i;
  Serial.print ("ID: ");
  int checksum=0;
  for (i=0; i<= 4; i++) {
    Serial.print (receive_ACK[i+19]);
    checksum += receive_ACK[i+19];
    Serial.print (",");
  }
  checksum += receive_ACK[4+19];
  Serial.println (checksum);
  for(i=0;i<5;i++){
    if(checksum==known_ids[i]){
      Serial.println(known_ids[i]);
      Serial.println("Card "+String(i));
      break;
    }
  }
}

void UART1_Send_Byte(unsigned char command_data){//send byte to device
  print1Byte(command_data);
#if defined(ARDUINO) && ARDUINO >= 100
  Serial1.flush();// complete the transmission of outgoing serial data 
#endif
} 

void UART_Send_Byte(unsigned char command_data){//send byte to PC
  Serial.print(command_data,HEX);
  Serial.print(" ");
} 

void read_ACK(unsigned char temp){//read ACK into reveive_ACK[]
  unsigned char i;
  for(i=0;i<temp;i++) {
    receive_ACK[i]= Serial1.read();
  }
}

void wake_card(void){//send wake[] to device
  unsigned char i;
  for(i=0;i<24;i++) //send command
    UART1_Send_Byte(wake[i]);
}

void firmware_version(void){//send fireware[] to device
  unsigned char i;
  for(i=0;i<9;i++) //send command
    UART1_Send_Byte(firmware[i]);
}

void send_tag(void){//send tag[] to device
  unsigned char i;
  for(i=0;i<11;i++) //send command
    UART1_Send_Byte(tag[i]);
}

void display(unsigned char tem){//send receive_ACK[] to PC
  unsigned char i;
  for(i=0;i<tem;i++) //send command
    UART_Send_Byte(receive_ACK[i]);
  Serial.println();
}

Credits

Evan Rust

Evan Rust

120 projects • 1054 followers
IoT, web, and embedded systems enthusiast. Contact me for product reviews or custom project requests.

Comments