Accueil > Activités > Arts et techniques > Automate de lecture et de transmission de données RFID

Automate de lecture et de transmission de données RFID

samedi 29 novembre 2008, par gepeto

Ce montage sert dans le cadre d’EcosXchange à la lecture et a comptabilisation des objets tels que le compost, les velos ...

La machine de base est une limace, le SLU2 déja étudié par la. Nous avons fait l’installation d’une Debian etch arm.

Nous avons ajouté le programme curl, pour transmettre de façon automatique tous les fichiers stockés dans le repertoire rfid_read . Voici le code :

#!/bin/bash
# rfid_upload.sh
# upload rfid trace to a server, beep , stop when transfert is ok
# cron

# server to upload (curl)
#SERVER=secure.parla.co.uk/am/test/data/
#USER=userlogin
#PASS=mot_de_pass
CURLPARAM=https://userlogin:mot_de_pass@secure.parla.co.uk/am/test/data/

#beep
DEVBEEP="/dev/input/by-path/platform-ixp4xx-beeper*"

beep -e $DEVBEEP -l400 -f 900
beep -e $DEVBEEP -l400 -f 700
beep -e $DEVBEEP -l400 -f 600

cd /home/toto
mkdir -p rfid_read rfid_transok

#date the last tag file and store it
[ -f rfid_tag.txt ] && mv rfid_tag.txt rfid_read/compostage-`date "+%y%m%d-%R"`.txt
cd rfid_read
for i in `ls -1` ; do
       curl -T $i $CURLPARAM
       RET=$?
       if [ "$RET" = 0 ] ;then
               beep -e $DEVBEEP -l500 -f 1000
               mv $i ../rfid_transok
       else
               beep -e $DEVBEEP -l300 -f 500
               beep -e $DEVBEEP -l300 -f 400
       fi

done
sleep 5

beep -e $DEVBEEP -l400 -f 600
beep -e $DEVBEEP -l400 -f 700
beep -e $DEVBEEP -l400 -f 900

Ce programme est lancé par le cron ( crontab -e : 0 * * * * /home/toto/rfid_upload.sh )
et fait des bips au lancement, histoire d’entendre si les fichiers sont bien transmis ou non.

La lecture des puces RFID se fait grace au module UM-005 cf l’article. Nous avons connecté le Tx du module sur le Rx d’une carte Arduino( en plus du 5V et de la masse). Le module Arduino est programmé avec le code suivant :

//RFID lextronic UM-005 reader
// Connect Rx(0),5V,GND

#define tagLengh 10
#define dataRate 9600

int i = 0;
int tagOK = false;

void setup() {
       Serial.begin(dataRate);
}
void loop() {
 if (Serial.available() > 0) {
   readByte();
 }
 if(tagOK == true) {
   Serial.println("");
   i = 0;
   tagOK=false;
   delay(3000);
 }
}
void readByte() {
 int thisChar = Serial.read();
 i++;
 if(i==tagLengh) {
  tagOK=true;
  Serial.flush();
 }
 if( i>3 && i<9) {
   Serial.print(thisChar,HEX);
   Serial.print(":");
 }
}

Et le code du lecteur coté SLU , ce programme est lancé par /etc/rc.local

#!/bin/bash
# rfid_read.sh
# read rfid tag , beep slug
# from arduino connect on a usb port USB0
# trace in a file
# format for data is zone,rfid-tag,date
# arduino is alone on USB
cd /home/toto
#beep
DEVBEEP="/dev/input/by-path/platform-ixp4xx-beeper*"

cd /home/toto
mkdir -p rfid_read
while true
do
if [ -c /dev/ttyUSB0 ] ;then

       [ -f rfid_tag.txt ] && mv rfid_tag.txt rfid_read/compostage-`date "+%y%m%d-%R"`.txt
        awk '{
       if(length($1) > 10) {
               printf ( "compostage %s ",$1 )
               system("date +%y%m%d-%R ");
               system("beep -e /dev/input/by-path/platform-ixp4xx-beeper* -l400 -f 1300");
       }

       }' /dev/ttyUSB0 >> rfid_tag.txt
fi
beep -e $DEVBEEP -l100 -f 500
beep -e $DEVBEEP -l100 -f 500
sleep 10
beep -e $DEVBEEP -l100 -f 400
beep -e $DEVBEEP -l100 -f 400
done

Voici ce qu’on récupère :

more rfid_transok/compostage-081107-18\:00.txt

compostage 1:4:45:C2:62: 081107-16:42
compostage 1:6:11:B8:41: 081107-16:42

Voici aussi une variante le fichier comporte aussi une donnée sur un poids, son format etant le suivant :

more compostage-081211-16\:18.txt
compostage 41:FF:17:88:1: 081211-16:16 weight=000.325

et le script d’envoie a été sécurisé :

#!/bin/bash
# rfid_upload_post.sh
# upload rfid trace to a server, beep , stop when transfert is ok
# cron

set -x

# upload site location
BASEURL="https://secure.parla.com"

# tempory file for storing cookies
COOKIEJAR="/tmp/rfid_upload_cookies.txt"

# credentials, replace with details for user with rfid upload permissions
USER=monsieurBidule
PASS=sesame


# beep
DEVBEEP="/dev/input/by-path/platform-ixp4xx-beeper*"

# location of files to upload
FILELOC="/home/toto"
beep -e $DEVBEEP -l400 -f 900
beep -e $DEVBEEP -l400 -f 700
beep -e $DEVBEEP -l400 -f 600

# login to server and save auth cookies, if login succeeds we'll receive a redirect header
curl -s -D - -d "name=$USER&pass=$PASS&form_id=user_login" -c "$COOKIEJAR" "$BASEURL/user/login"\
 | grep 'HTTP/1.1 302 Found' > /dev/null

if [ $? != 0 ] ;then
 echo "Login failed"
 beep -e $DEVBEEP -l300 -f 500
 beep -e $DEVBEEP -l300 -f 400
 exit 1
fi

# get the form's token
TOKEN=`curl -s -b "$COOKIEJAR" "$BASEURL/rfid-upload" | grep 'name="form_token"' | egrep -o '[[:alnum:]]{32}'`

cd "$FILELOC"
mkdir -p rfid_read rfid_transok

# date the last tag file and store it
[ -f rfid_tag.txt ] && mv rfid_tag.txt rfid_read/compostage-`date "+%y%m%d-%R"`.txt
cd rfid_read
for i in `ls -1` ; do
 # upload the file, if upload succeeds we'll receive a redirect header
 curl -s -D - -b "$COOKIEJAR" -F "form_id=amp_rfid_upload" -F "form_token=$TOKEN" -F "files[file]=@$i" "$BASEURL/rfid-upload"\
   | grep 'HTTP/1.1 302 Found'
 RET=$?
 if [ "$RET" = 0 ] ;then
   beep -e $DEVBEEP -l500 -f 1000
   mv $i ../rfid_transok
 else
   echo "Uploading file: $i failed, possible incorrect format, try uploading manually."
   beep -e $DEVBEEP -l300 -f 500
   beep -e $DEVBEEP -l300 -f 400
 fi
done
sleep 5

beep -e $DEVBEEP -l400 -f 600
beep -e $DEVBEEP -l400 -f 700
beep -e $DEVBEEP -l400 -f 900

# delete the auth cookies
rm "$COOKIEJAR"

Voici aussi une autre variante, la lecture de la puce rfid valide la reception de données venant d’une balance de pesé ( de marque EXA avec une connexion en RS232 ( maxim232 cf autre article pour la connexion serie).

// when read rfid tag with UM-005 and balance (exa with rs232)
// transmit rfid_tag with balance data
// wait 5s
// rfid on Arduino 0 (Rx)
// balance Rx on Arduino 2

#include "AFSoftSerial.h"
// balance rs232 data is a stream...
#define sensorUpdatesPerSec 10
#define sensorUpdateMillis (1000/sensorUpdatesPerSec)
#define sensorPacketSize 8   // "|xxyyzz" 8 bytes
#define sensorBuffSize ((sensorPacketSize*sensorUpdatesPerSec)+5)

#define RXPIN 2
#define TXPIN 3
AFSoftSerial mySerial = AFSoftSerial(RXPIN,TXPIN);
#define BUFFSIZ sensorBuffSize
char buffer[sensorBuffSize];
uint8_t buffidx;
#define tagLengh 10
int i = 0;
int tagOK = false;

void setup()
{
pinMode(RXPIN, INPUT);
Serial.begin(9600);
mySerial.begin(9600);
}
void readByte() {
int thisChar = Serial.read();
i++;
if(i==tagLengh) {
 tagOK=true;
 Serial.flush();
}
if( i>3 && i<9) {
  Serial.print(thisChar,HEX);
  Serial.print(":");
}
}
// read balance RS232 data
void readline(void) {
 char c;
 buffidx = 0; // start at begining
 while (1) {
     c = mySerial.read();
     if (c == -1)
       continue;
     if (c == '\n')
       continue;
     if ((buffidx == BUFFSIZ-1) || (c == '\r')) {
       buffer[buffidx] = 0;
       return;
     }
     buffer[buffidx++]= c;
 }
}




void loop() {
if (Serial.available() > 0) {
  readByte();
}
if(tagOK == true) {
  Serial.print(" = ");
  i = 0;
  tagOK=false;
  // read balance data
  readline();
  Serial.println(buffer);
  // delay 5" in case same code rfid
  delay(5000);
}
}