Accueil > Activités > Arts et techniques > Automate de lecture et de transmission de données RFID
samedi 29 novembre 2008, par
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);
}
}