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-<span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+ZGF0ZSAmcXVvdDsrJXklbSVkLSVSJnF1b3Q7PC9jb2RlPg=="></span>.txt
cd rfid_read
for i in <span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+bHMgLTE8L2NvZGU+"></span> ; 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-<span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+ZGF0ZSAmcXVvdDsrJXklbSVkLSVSJnF1b3Q7PC9jb2RlPg=="></span>.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=<span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+Y3VybCAtcyAtYiAmcXVvdDskQ09PS0lFSkFSJnF1b3Q7ICZxdW90OyRCQVNFVVJML3JmaWQtdXBsb2FkJnF1b3Q7IHwgZ3JlcCAnbmFtZT0mcXVvdDtmb3JtX3Rva2VuJnF1b3Q7JyB8IGVncmVwIC1vICdbWzphbG51bTpdXXszMn0nPC9jb2RlPg=="></span>

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-<span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+ZGF0ZSAmcXVvdDsrJXklbSVkLSVSJnF1b3Q7PC9jb2RlPg=="></span>.txt
cd rfid_read
for i in <span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+bHMgLTE8L2NvZGU+"></span> ; 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);
 }
}