Okay so ive got it half working now:
The tag is registered every second time - ie it takes the first scan to wake the arduino up and then the 2nd scan to scan the tag?
Here is my code:
#include <SoftwareSerial.h>
#include <avr/sleep.h>
// Create a software serial object for the connection to the RFID module
SoftwareSerial rfid = SoftwareSerial(2,4);
// Set up outputs for the strike plate and status LEDs.
// If you have built the circuit exactly as described in Practical
// Arduino, use pins D12 and D13:
#define strikePlate 12
#define redPin 9
#define greenPin 8
#define buttonPin 10
int wakePin = 3; // pin used for waking up
// If you are using the Freetronics RFID Lock Shield, use pins D6 / D7:
/* #define strikePlate 6 */
/* #define ledPin 7 */
// Specify how long the strike plate should be held open.
#define unlockSeconds 2
// The tag database consists of two parts. The first part is an array of
// tag values with each tag taking up 5 bytes. The second is a list of
// names with one name for each tag (ie: group of 5 bytes).
char* allowedTags[] = {
"01000554F0", // Tag 1
"0100443DE1", // Tag 2
"290093E62B", // Tag 3
"4F0023FF95",
};
// Check the number of tags defined
int numberOfTags = sizeof(allowedTags)/sizeof(allowedTags[0]);
int incomingByte = 0; // To store incoming serial data
int buttonState = 0;
/**
* Setup
*/
void setup() {
pinMode(buttonPin, INPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(strikePlate, OUTPUT);
digitalWrite(strikePlate, LOW);
Serial.begin(38400); // Serial port for connection to host
rfid.begin(9600); // Serial port for connection to RFID module
Serial.print("Keyless Locking System Starting... ");
Serial.println("Ready!");
Serial.println("");
pinMode(wakePin, INPUT);
attachInterrupt(1, wakeUpNow, LOW); // use interrupt 1 (pin 3) and run function
// wakeUpNow when pin 2 gets LOW
}
void wakeUpNow() // here the interrupt is handled after wakeup
{
}
void sleepNow() // here we put the arduino to sleep
{
/* Now is the time to set the sleep mode. In the Atmega8 datasheet
* http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf on page 35
* there is a list of sleep modes which explains which clocks and
* wake up sources are available in which sleep mode.
*
* In the avr/sleep.h file, the call names of these sleep modes are to be found:
*
* The 5 different modes are:
* SLEEP_MODE_IDLE -the least power savings
* SLEEP_MODE_ADC
* SLEEP_MODE_PWR_SAVE
* SLEEP_MODE_STANDBY
* SLEEP_MODE_PWR_DOWN -the most power savings
*
* For now, we want as much power savings as possible, so we
* choose the according
* sleep mode: SLEEP_MODE_PWR_DOWN
*
*/
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin
/* Now it is time to enable an interrupt. We do it here so an
* accidentally pushed interrupt button doesn't interrupt
* our running program. if you want to be able to run
* interrupt code besides the sleep function, place it in
* setup() for example.
*
* In the function call attachInterrupt(A, B, C)
* A can be either 0 or 1 for interrupts on pin 2 or 3.
*
* B Name of a function you want to execute at interrupt for A.
*
* C Trigger mode of the interrupt pin. can be:
* LOW a low level triggers
* CHANGE a change in level triggers
* RISING a rising edge of a level triggers
* FALLING a falling edge of a level triggers
*
* In all but the IDLE sleep modes only LOW can be used.
*/
attachInterrupt(1,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
// wakeUpNow when pin 2 gets LOW
Serial.println("Asleep");
sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
sleep_disable(); // first thing after waking from sleep:
// disable sleep...
Serial.println("Awake");
detachInterrupt(1); // disables interrupt 0 on pin 2 so the
// wakeUpNow code will not be executed
// during normal running time.
}
/**
* Loop
*/
void loop() {
sleepNow(); // sleep function called here
byte i = 0;
byte val = 0;
byte checksum = 0;
byte bytesRead = 0;
byte tempByte = 0;
byte tagBytes[6]; // "Unique" tags are only 5 bytes but we need an extra byte for the checksum
char tagValue[10];
if((val = rfid.read()) == 2) { // Check for header
bytesRead = 0;
while (bytesRead < 12) { // Read 10 digit code + 2 digit checksum
val = rfid.read();
// Append the first 10 bytes (0 to 9) to the raw tag value
if (bytesRead < 10)
{
tagValue[bytesRead] = val;
}
// Check if this is a header or stop byte before the 10 digit reading is complete
if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) {
break; // Stop reading
}
// Ascii/Hex conversion:
if ((val >= '0') && (val <= '9')) {
val = val - '0';
}
else if ((val >= 'A') && (val <= 'F')) {
val = 10 + val - 'A';
}
// Every two hex-digits, add a byte to the code:
if (bytesRead & 1 == 1) {
// Make space for this hex-digit by shifting the previous digit 4 bits to the left
tagBytes[bytesRead >> 1] = (val | (tempByte << 4));
if (bytesRead >> 1 != 5) { // If we're at the checksum byte,
checksum ^= tagBytes[bytesRead >> 1]; // Calculate the checksum... (XOR)
};
} else {
tempByte = val; // Store the first hex digit first
};
bytesRead++; // Ready to read next digit
}
// Send the result to the host connected via USB
if (bytesRead == 12) { // 12 digit read is complete
tagValue[10] = '\0'; // Null-terminate the string
// Search the tag database for this particular tag
int tagId = findTag( tagValue );
// Only fire the strike plate if this tag was found in the database
if( tagId > 0 )
{
Serial.println("Authorized");
Serial.print("TAG ID ");
Serial.println(tagId);
unlock(); // Fire the strike plate to open the lock
} else {
Serial.println("Unauthorized");
Serial.print(tagValue);
digitalWrite(redPin, HIGH);
delay(100);
digitalWrite(redPin, LOW);
delay(80);
digitalWrite(redPin, HIGH);
delay(100);
digitalWrite(redPin, LOW);
}
Serial.println(); // Blank separator line in output
}
bytesRead = 0;
}
// Read from the RFID module. Because this connection uses SoftwareSerial
// there is no equivalent to the Serial.available() function, so at this
// point the program blocks while waiting for a value from the module
}
/**
* Fire the relay to activate the strike plate for the configured
* number of seconds.
*/
void unlock() {
digitalWrite(greenPin, HIGH);
digitalWrite(strikePlate, HIGH);
delay(unlockSeconds * 1000);
digitalWrite(strikePlate, LOW);
digitalWrite(greenPin, LOW);
}
/**
* Search for a specific tag in the database
*/
int findTag( char tagValue[10] ) {
for (int thisCard = 0; thisCard < numberOfTags; thisCard++) {
// Check if the tag value matches this row in the tag database
if(strcmp(tagValue, allowedTags[thisCard]) == 0)
{
// The row in the database starts at 0, so add 1 to the result so
// that the card ID starts from 1 instead (0 represents "no match")
return(thisCard + 1);
}
}
// If we don't find the tag return a tag ID of 0 to show there was no match
return(0);
}
and my serial output is:
Keyless Locking System Starting... Ready!
AsleepC¡Ý…•5
AsleepýH(Ý…•5
AsleepC¡Ý…[•5
þ¡Ý…•5 Asleep
Unauthorized
4F00236BB7
AsleepCaPW•5
AsleepC¡Ý…•5
AsleepýH(Ý…•5
AsleepC¡Ý…•5
Authorized
TAG ID 2
Asleep
I dont know about those random characters??
John