Show Posts
Pages: [1] 2
1  Topics / Science and Measurement / Re: Timing an RFID tag between two points on: April 16, 2012, 12:50:28 pm
I have had a go at putting my program logic into flow charts, one for the start and on for the finish.  Feedback and criticism appreciated!



2  Topics / Science and Measurement / Re: Timing an RFID tag between two points on: April 13, 2012, 08:12:01 am
This is where I am up to so far.

I have copy and pasted bits of what I already had into the template you provided me.

Now i can scan a tag on the start RFID and then push the start button to get the tag ID shown on the serial monitor.  There is some behaviour I need to change, it will queue tag reads and then display them all when the start button is pushed, it needs to work with only one tag at a time so it disregards every other read after the first one until the start button has been activated.

With regards to the overdue tags, would I need to specify a time period in milis of more than 600,000 to have them removed from the array after 10 minutes?

The current code is below, I hope I am on the right track!

Code:
#define STARTPIN 8
#define ENDPIN 9
#include <UTFT.h>


extern uint8_t SmallFont[];   // Declare which fonts we will be using

UTFT myGLCD(ITDB32S,38,39,40,41);   // Remember to change the model parameter to suit your display module!

struct
{
  char rfid[16];
  uint32_t start;  // start time for determining duration.
}
progress[25];

int idx = 0;

void setup()
{
 // initialize the pushbutton pin as an input:
  pinMode(STARTPIN, INPUT); 
  pinMode(ENDPIN, INPUT);
 
// Setup the LCD
  myGLCD.InitLCD();
  myGLCD.setFont(SmallFont);

 
  Serial.begin(9600);    // connect to the serial port for output to serial monitor
  Serial2.begin(9600);   // serial port of RFID reader at start
  Serial3.begin(9600);   // serial port of RFID reader at finish
}

void loop()
{
  if (RFIDavailable(STARTPIN))
  {
    doStart();
  }

  if (RFIDavailable(ENDPIN))
  {
    doEnd();
  }

  if (RFIDoverdue())
  {
    doOverdue();
  }   
}

bool RFIDavailable(int pin)


  int finishState = digitalRead(ENDPIN);
  if (pin == STARTPIN) {
     int startState = digitalRead(STARTPIN);
     if (startState == HIGH) return Serial2.available() > 0; // assuming 12 chars in RFID
  }
 
  if (pin == ENDPIN) return Serial3.available() > 0;
  return false;
}

bool RFIDoverdue()
{
  return false; // dummy
}

void doStart()
{
  // read RFID and add to array
  //for (int i=0; i< 12; i++) progress[idx].rfid[i] = Serial2.read();
  //progress[idx].rfid[13] = 0; // null terminated string
  //progress[idx].start = millis();
  //idx++;
  byte i = 0;
  byte val = 0;
  byte code[6];
  byte checksum = 0;
  byte bytesread = 0;
  byte tempbyte = 0;
 
    if((val = Serial2.read()) == 2) {                  // check for header
      bytesread = 0;
      while (bytesread < 12) {                        // read 10 digit code + 2 digit checksum
        if( Serial2.available() > 0) {
          val = Serial2.read();
          if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) { // if header or stop bytes before the 10 digit reading
            break;                                    // stop reading
          }

          // Do 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 byte to code:
          if (bytesread & 1 == 1) {
            // make some space for this hex-digit by
            // shifting the previous hex-digit with 4 bits to the left:
            code[bytesread >> 1] = (val | (tempbyte << 4));

            if (bytesread >> 1 != 5) {                // If we're at the checksum byte,
              checksum ^= code[bytesread >> 1];       // Calculate the checksum... (XOR)
            };
          } else {
            tempbyte = val;                           // Store the first hex digit first...
          };

          bytesread++;                                // ready to read next digit
        }
      }

      // Output to Serial:
      if (bytesread == 12) {                          // if 12 digit read is complete
       // Serial.print("5-byte code: ");
        String thisString;
        if (code[0] < 16){
          thisString = String(0);
          thisString += String(code[0], HEX);
        }
        else {
        thisString = String(code[0], HEX);
        }
        for (i=1; i<5; i++) {
        if (code[i] < 16) thisString += 0;
       thisString += String(code[i], HEX);

        }
        Serial.print(thisString);
        Serial.println();
      }

      bytesread = 0;
    }
 
}

void doEnd()
{
  // read RFID,
  // they might be removed due to overdue
  char rfid[16];
  for (int i=0; i< 12; i++) rfid[i] = Serial3.read();
  rfid[13] = 0;
  // search in array
  // if not found ==> error
  // calculate duration   
  // display rfid tag + duration
  // remove rfid from array
  // idx--;
}

void doOverdue()
{
  // handle overdue items in array + remove them
}
3  Topics / Science and Measurement / Re: Timing an RFID tag between two points on: April 12, 2012, 02:03:08 pm
Thanks again for your help and advice.  I will have a play and post back my results or more likely when im stuck again!

Quote
No, they can end in a different order that they start, some may not ever reach the end.

That means that your array will need to be infinite or you should check that a specific is overdue and remove it from the array.
Do you mean like a timeout if the tag has been in progress too long?  10 minutes would be long enough for my application.
4  Topics / Science and Measurement / Re: Timing an RFID tag between two points on: April 12, 2012, 01:29:44 pm
Thank you for your help  smiley

Quote
Q: How many RFID's can be in progress simultaneously?
Several, a maximum of 10 in progress at any one time.

Quote
Q: do they come in the same order? always? sure?
No, they can end in a different order that they start, some may not ever reach the end.

I realised that I would need to use an array (or several, indexed?) but unsure about how to go about that as I am completely new to this.
What kind of array would I need to be able to cope with the unique HEX code of each tag?

Thanks again!
5  Topics / Science and Measurement / Timing an RFID tag between two points on: April 12, 2012, 12:48:05 pm
Hi All,
  I am using the following hardware,

Arduino Mega 2560
ITBD02 moudule
3.2" TFT touchscreen module
ID-12 RFID reader x 2  (The ID-12's are connected to serial 2 & 3)
Momentary switch x 2 (The switches are connected to pins 8 & 9)

Lets say I have an RFID reader and switch at the 'start' and the the same at the 'end'. 

What I would like to be able to do is scan an RFID tag at the start and then activate a switch which logs the time interval the switch was activated against that specific tag. 
At the end the reverse would happen, a switch would be activated and time logged then the system would wait for an RFID tag to be scanned which will then be associated with the time just logged. 
Once an RFID tag has gone through both start and end procedure I would like the time taken to be displayed on the TFT screen in minute/second/milisecond format.

This is the code I have so far, all it does is prove my hardware works, I get time intervals displayed on the screen and RFIDs spat out over serial but im not sure what I need to do next to accomplish my objective.

Any and all feedback and advice much appreciated!  Regards Jason.

Code:
const int startPin = 8;
const int finishPin = 9;

// variables will change:
int buttonState;             // variable for reading the pushbutton status
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

#include <UTFT.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];

UTFT myGLCD(ITDB32S,38,39,40,41);   // Remember to change the model parameter to suit your display module!

unsigned long time;
unsigned short minutes;
unsigned short seconds;

unsigned long startTime;
unsigned long stopTime;
unsigned long result;

boolean newresult = false;

void setup() {
 
  // initialize the pushbutton pin as an input:
  pinMode(startPin, INPUT); 
  pinMode(finishPin, INPUT);
 
// Setup the LCD
  myGLCD.InitLCD();
  myGLCD.setFont(SmallFont);

 
  Serial.begin(9600);    // connect to the serial port for output to serial monitor
  Serial2.begin(9600);   // serial port of RFID reader at start
  Serial3.begin(9600);   // serial port of RFID reader at finish
}

void loop () {
 
  // Clear the screen and draw the frame
 
  time = millis();
  seconds = time / 1000;
  minutes = seconds / 60;
  //result = start - millis();
 
 /* myGLCD.setColor(255, 0, 0);
  myGLCD.fillRect(0, 0, 319, 13);
  myGLCD.setColor(64, 64, 64);
  myGLCD.fillRect(0, 226, 319, 239);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  */
 
 
   // read the state of the switch into a local variable:
  int startState = digitalRead(startPin);
  int finishState = digitalRead(finishPin);
  int reading = 0;

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
  lastDebounceTime = millis();
  }
 
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:
    buttonState = reading;
  }
  if (startState == HIGH){
    startTime = time;
  }
 
  if (finishState == HIGH){
    result = time - startTime;
    newresult=true;
  }
 
 if (newresult==true){
  myGLCD.setColor(255, 0, 0);
  myGLCD.fillRect(0, 0, 319, 13);
  myGLCD.setColor(64, 64, 64);
  myGLCD.fillRect(0, 226, 319, 239);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
 
   // set the LED using the state of the button:
   myGLCD.printNumI(result, CENTER, 1); 
 }
  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;
 
  byte i = 0;
  byte val = 0;
  byte code[6];
  byte checksum = 0;
  byte bytesread = 0;
  byte tempbyte = 0;

  if(Serial2.available() > 0) {
    if((val = Serial2.read()) == 2) {                  // check for header
      bytesread = 0;
      while (bytesread < 12) {                        // read 10 digit code + 2 digit checksum
        if( Serial2.available() > 0) {
          val = Serial2.read();
          if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) { // if header or stop bytes before the 10 digit reading
            break;                                    // stop reading
          }

          // Do 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 byte to code:
          if (bytesread & 1 == 1) {
            // make some space for this hex-digit by
            // shifting the previous hex-digit with 4 bits to the left:
            code[bytesread >> 1] = (val | (tempbyte << 4));

            if (bytesread >> 1 != 5) {                // If we're at the checksum byte,
              checksum ^= code[bytesread >> 1];       // Calculate the checksum... (XOR)
            };
          } else {
            tempbyte = val;                           // Store the first hex digit first...
          };

          bytesread++;                                // ready to read next digit
        }
      }

      // Output to Serial:

      if (bytesread == 12) {                          // if 12 digit read is complete
       // Serial.print("5-byte code: ");
        String thisString;
        if (code[0] < 16){
          thisString = String(0);
          thisString += String(code[0], HEX);
        }
        else {
        thisString = String(code[0], HEX);
        }
        for (i=1; i<5; i++) {
        if (code[i] < 16) thisString += 0;
       thisString += String(code[i], HEX);
       //   Serial.print(code[i]);
         // Serial.print(" ");
        }
        Serial.print(thisString);
        Serial.println();

      //  Serial.print("Checksum: ");
       // Serial.print(code[5], HEX);
       // Serial.println(code[5] == checksum ? " -- passed." : " -- error.");
       // Serial.println();
      }

      bytesread = 0;
    }
  }

if(Serial3.available() > 0) {
    if((val = Serial3.read()) == 2) {                  // check for header
      bytesread = 0;
      while (bytesread < 12) {                        // read 10 digit code + 2 digit checksum
        if( Serial3.available() > 0) {
          val = Serial3.read();
          if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) { // if header or stop bytes before the 10 digit reading
            break;                                    // stop reading
          }

          // Do 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 byte to code:
          if (bytesread & 1 == 1) {
            // make some space for this hex-digit by
            // shifting the previous hex-digit with 4 bits to the left:
            code[bytesread >> 1] = (val | (tempbyte << 4));

            if (bytesread >> 1 != 5) {                // If we're at the checksum byte,
              checksum ^= code[bytesread >> 1];       // Calculate the checksum... (XOR)
            };
          } else {
            tempbyte = val;                           // Store the first hex digit first...
          };

          bytesread++;                                // ready to read next digit
        }
      }

      // Output to Serial:

      if (bytesread == 12) {                          // if 12 digit read is complete
       
        String thisString;
        if (code[0] < 16){
          thisString = String(0);
          thisString += String(code[0], HEX);
        }
        else {
        thisString = String(code[0], HEX);
        }
        for (i=1; i<5; i++) {
        if (code[i] < 16) thisString += 0;
       thisString += String(code[i], HEX);
     
        }
        Serial.print(thisString);
        Serial.println();

     
      }

      bytesread = 0;
    }
  }
newresult=false;
}


6  Using Arduino / Project Guidance / Re: wireless xbee Ardunio network timing of mountain bike race is this possible? on: November 07, 2011, 07:34:02 am
Quote
Depends on how you actually write the code. The delay can be anywhere from a few hundred nanoseconds to days.

The delay can be small enough to be considered insignificant. If the delay is on the order of microseconds or less, I doubt that the delay will be observable in the measured time with respect to the actual time. Certainly the displayed value of the measured time could have more variation (between the measured time and the displayed time) than the actual delay values.

Thank you for confirming that for me, will hopefully make the project a little simpler to program and also cheaper.

Knowing what you do about the project, do you think at an Arduino FIO would be suitable to use for the start transmitter?  Am I correct in assuming that I can connect the ID-12 and a photoswitch without issue or would it be more straightforward just to use an Uno board instead?

Thanks,

-Jason
7  Using Arduino / Project Guidance / Re: wireless xbee Ardunio network timing of mountain bike race is this possible? on: November 07, 2011, 07:23:41 am
Quote
What constraints are you trying to meet?
I would like to be able to identify when a rider enters and leaves the course so that I know how long they are on course for.  Each rider needs their own unique identity.  Start and finish are significantly far apart to need some form of wireless communication.  Will need to handle multiple riders on course at one time.

Quote
What sort of distance will there be between the start/end points?
I was considering an Xbee pro for the transmitter that has a theoretical outdoor line-of-sight range of a mile.  These races take place on hillsides and often in quite dense woodland but the start is always at a much higher vertical elevation than the finish.

Quote
How tolerant will you be of false/missing results?
This is not for any regulatory body but I would rather avoid any if possible.

Quote
Does it need to be tamper-proof?
Not really, this is just for use between friends and clubs so I wouldn't expect any attempts to cheat or manipulate the system

Quote
Can you get away with simply banning overtaking?
No, but we could theoretically only allow one rider on course at any time.  However this is not desirable as on a longer course (3 min for a fast rider or 5+ min for a slow rider) with many people each requiring 2 runs, you can quickly run out of time.

Quote
Is there anything stopping you having a human element involved in the normal operation of this?
It needs to be as automated as possible, I don't want someone writing down riders numbers as they finish for example.

Thanks,

-Jason
8  Using Arduino / Project Guidance / Re: wireless xbee Ardunio network timing of mountain bike race is this possible? on: November 07, 2011, 06:29:15 am
Quote
No. On the other hand, you don't need to. Scan a tag. Send the data. The receiver time stamps the receipt of the tag, defining the start time. Scan a tag on the other end to record the end time for that tag.
This is how I had originally planned for the system to work but was concerned with latency issues from sending and receiving the data hence the idea to add a real time clock to the transmitter unit.  For simplicity's sake would it be ok to assume that there is negligible delay from when the start gate is triggered and when the receiving Arduino is actually aware that it was triggered?  At the very least would this delay be consistent for every rider throughout the day?

Thanks,

-Jason
9  Using Arduino / Project Guidance / Re: wireless xbee Ardunio network timing of mountain bike race is this possible? on: November 06, 2011, 05:42:35 pm
Quote
Sure it is, and no they don't. I'm not aware of any RTC with a serial interface.
Ah excellent, I must have crossed my wires somewhere while I have been trying to work all this out.

Aside from the points raised do you see anything else I have overlooked regarding this proposal?  Can you think of a better way to accomplish what I am trying to do?  I know I could use a UHF RFID reader and do away with the photo-switches completely but the cost is prohibitive.

If I have a real time clock module in the start Arduino and a real time clock module in the finish Arduino can I get them to automatically sync time with each other?

Also, am I correct in assuming that the Xbee is transparent to the Arduino so that I can prototype this all on a bench by connecting the boards via a serial cable and not have to cover the additional expense of the Xbee's until the software part is actually finished?

Thanks,

-Jason
10  Using Arduino / Project Guidance / Re: wireless xbee Ardunio network timing of mountain bike race is this possible? on: November 06, 2011, 03:49:10 pm
Quote
Are the racers racing each other, or the clock?
The clock.

Quote
more than one rider at a time may reach the finish line. Lining to to scan RFID tags to stop the clock hardly seems like a viable solution.
That is a possibility but not that regular an occurrence for it to be a hindrance

Quote
How is sending the switch state going to prove useful? What you need to send is the RFID tag and the time that the switch was triggered
By switch state I just meant that it had been triggered.

Quote
The end time will be defined when the rider scans his/her tag again
That is correct

Quote
Getting them to not pass each other on the course, and to line up neatly at the finish line will be the biggest challenge.
If the system logs the time a tag scans onto the course and then the time it scans off the course then it would not matter if the riders were to pass each other of if a rider failed to ever finish, would it?  Fundamentally it comes down to associating a time stamp with an tag.

Can you tell me if it is possible to connect a real time clock and an Xbee to an Arduino uno at the same time as they would both require the serial connection?

Thanks,

-Jason
11  Using Arduino / Project Guidance / Re: wireless xbee Ardunio network timing of mountain bike race is this possible? on: November 06, 2011, 02:58:34 pm
Original post modified to reflect new direction of project.

Thanks for any input!

-Jason
12  Using Arduino / Project Guidance / Re: RFID conundrum for start / finish line timing of mountain bike race on: November 02, 2011, 04:55:22 pm
Quote
short range transmitter

Please elaborate as your suggestion sounds entirely feasible.

It works like this, Riders start at the top of the hill and race down the course one at a time to the finish at the bottom.  A really short course would take a fast rider approx 30 seconds to get down but a slow rider on the same course may take 90+ seconds.  Rider starts are staggered by 30 second intervals so although it would be bad practice to send a slow rider down before a fast rider it is still feasible that there would be 2 or more riders on the course at any one time and they could finish in a different order than they initially set off.  Riders would typically cross the line separately.

That's it in a nutshell.

Initially I had planned to wire a infra-red photoelectric switch into a motorola walkie talkie as the push to talk button to trigger the vibrate function in a receiving walkie talkie wired into an arduino and start a timer.  At the finish would be another photoelectric switch connected directly to the arduino that would record the time.  While this would work it seemed somewhat crude and a waste of the hardware, also it would only allow one rider on course.  RFID seemed ideal for the project until I found out the cost was significantly more than I first expected!

Any suggestions?  Im all ears!

Thanks

-Jason
13  Using Arduino / Project Guidance / Re: RFID conundrum for start / finish line timing of mountain bike race on: November 02, 2011, 01:10:48 pm
Well there are championchip, ipico etc but obviously they are shall we say, not affordable.

I would like an automated system and thought using RFID would be pretty simple and not that expensive.  Machine vision was considered a possibility but deemed unsuitable as on a wet muddy course it would end up unreadable by the time the rider finished.

What about something like this? http://www.ebay.co.uk/itm/RF8315RT-u-Active-RFID-8-Meters-Transmitter-n-Receiver-/290365177740?pt=LH_DefaultDomain_0&hash=item439b1cff8c#ht_2066wt_1064
14  Using Arduino / Project Guidance / Re: RFID conundrum for start / finish line timing of mountain bike race on: November 02, 2011, 12:36:19 pm
Back to the drawing board then!

Can you suggest any other technology that will let me uniquely track individual riders as they cross the start and finish lines?

-Jason
15  Using Arduino / Project Guidance / Re: RFID conundrum for start / finish line timing of mountain bike race on: November 02, 2011, 12:02:14 pm
Quote
I used to design RFID readers for a living

Then you are certainly a good person to talk to and I think you for taking the time to respond.

As I know next to nothing about this, is it possible to use a battery activated passive tag with any low cost passive RFID reader or do they require specific hardware?  Assume that a read rage of 12" (30 cm) is workable would it also be possible to read a chip that passes over the antenna at 10 m/s ?

-Jason
Pages: [1] 2