Skip to content

Instantly share code, notes, and snippets.

@DanielCollins
Created September 16, 2012 07:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanielCollins/3731477 to your computer and use it in GitHub Desktop.
Save DanielCollins/3731477 to your computer and use it in GitHub Desktop.
#include <string.h>
#include <SoftwareSerial.h>
SoftwareSerial rfid(3, 2);
void check_for_notag(void);
void rfid_halt(void);
void parse(void);
void print_serial(void);
void read_serial(void);
void rfid_seek(void);
void set_flag(void);
uint8_t tag[] = { 0x87, 0x9D, 0x64, 0x02 };
enum RfidCmd
{
RESET = 0x80,
FIRMWARE = 0x81,
SEEK = 0x82,
POWER = 0x90,
HALT = 0x93
};
void setup()
{
Serial.begin(9600);
Serial.println("Start I");
}
void loop()
{
if (rfid_do_id(millis() + 5000))
Serial.println("identified");
else
Serial.println("timed out");
}
void rfid_send_frame(uint8_t cmd, uint8_t *data, uint8_t length)
{
uint8_t payload_length = length + 1;
uint8_t checksum = 0x00 + payload_length + cmd;
rfid.write((uint8_t)0xFF); // header
rfid.write((uint8_t)0x00); // reserved, unimplimented
rfid.write((uint8_t)payload_length); // payload byte count including cmd
rfid.write((uint8_t)cmd); // command
for (uint8_t i = 0; i < length; ++i) // data
{
rfid.write(data[i]);
checksum += data[i];
}
rfid.write((uint8_t)checksum); // checksum ends packet
}
void rfid_halt(void)
{
rfid_send_frame(HALT, 0, 0);
}
void rfid_seek()
{
rfid_send_frame(SEEK, 0, 0);
delay(10);
}
bool rfid_timeout_read(unsigned long expire_time, uint8_t *out)
{
while (millis() < expire_time)
{
if (rfid.available() > 0)
{
*out = rfid.read();
return true;
}
delay(20);
}
return false;
}
bool rfid_read_seek_response(unsigned long expire_time)
{
uint8_t b;
// ignore everything up to packet frame header
while (1)
{
if (!rfid_timeout_read(expire_time, &b))
return false;
if (b == 0xFF)
break;
}
// require rest of packet header
if (!rfid_timeout_read(expire_time, &b) || b != 0x00)
return false;
if (!rfid_timeout_read(expire_time, &b) || b != 0x02)
return false;
// require seek command reply
if (!rfid_timeout_read(expire_time, &b) || b != SEEK)
return false;
// require success
if (!rfid_timeout_read(expire_time, &b) || b != 0x4C)
return false;
// require checksum
if (!rfid_timeout_read(expire_time, &b) || b != 0xD0)
return false;
return true;
}
bool rfid_cmp_tag_packet(unsigned long expire_time)
{
uint8_t l, b;
// ignore everything up to packet frame header
while (1)
{
if (!rfid_timeout_read(expire_time, &b))
return false;
if (b == 0xFF)
break;
}
// require reserved byte
if (!rfid_timeout_read(expire_time, &b) || b != 0x00)
return false; // bad packet frame
// read payload length. needs to be a sensible tag length
if (!rfid_timeout_read(expire_time, &b) || (b != 6 && b != 9))
return false;
// ought to be a reply to a seek command
if (!rfid_timeout_read(expire_time, &b) || b != SEEK)
return false;
// ignore "tag type" byte
if (!rfid_timeout_read(expire_time, &b))
return false;
for (int i = l - 3; i >= 0; --i)
{
if (!rfid_timeout_read(expire_time, &b))
return false;
if (tag[i] != b)
{
Serial.print(tag[i], HEX);
Serial.print(" != ");
Serial.println(b, HEX);
return false;
}
}
return true;
}
bool rfid_do_id(unsigned long expire_time)
{
rfid.begin(19200);
delay(10);
while (millis() < expire_time)
{
rfid_seek();
delay(10);
if (!rfid_read_seek_response(expire_time))
{
rfid.end();
return false;
}
if (rfid_cmp_tag_packet(expire_time))
{
rfid.end();
return true;
}
}
rfid.end();
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment