Interprétation de la lecture de données d'un tag RFID (élevage caprins / ovins)

Bonjour à tous !

Depuis quelques temps l’idée de lire les boucles électroniques maintenant obligatoires en élevage caprins et ovins me trotte dans la tête. Ces boucles représentent un gros potentiel d’automatisation en élevage mais quand on passe par les fabricants de matériel on s’en sort avec une énorme facture en général.

Bref, j’ai cherché sur le net, trouvé le lecteur adéquat, j’avais acheté un lecteur usb sur aliexpress qui simulait une entrée clavier pour afficher le numéro de la boucle. Cela m’a permis de confirmer mes recherches sur la compatibilité des boucles avec mon lecteur à moindre coût et sans avoir à faire un gros montage de test.
J’ai ensuite acheté un module avec une bien meilleure portée pour pouvoir l’utiliser dans un motage grandeur nature, mais bien sûr plus compliqué à utiliser. C’est là que commence mon problème.

Comme fichiers en pièces jointes vous avez les captures d’écran des lecteurs que j’ai achetés avec la description du vendeur sur Aliexpress, et un document fourni par le vendeur expliquant la manière d’utiliser les informations envoyées par le lecteur avec la grosse antenne carré.

Pour l’instant j’ai réussi à lire la valeur en hexadécimal de la carte, à l’afficher sur le moniteur série de l’IDE, mais je n’arrive absolument pas à comprendre ce qu’il faut faire pour convertir du format hexadécimal au format décimal en passant par la table ASCII (j’arrive à comprendre comment passer de l’hexadécimal à l’ASCII mais de l’ASCII au décimal je n’arrive pas à trouver la même conversion qu’eux).
D’ailleurs je n’arrive pas non plus à trouver la même valeur en convertissant directement l’hexadécimal en décimal…

N’ayant jamais appris ces histoires d’hexadécimal etc (mais ayant quelques notions à force de chercher) j’aimerais avoir votre avis, comment faire pour avoir une conversion qui colle avec le tuto pdf (en pj).
J’ai essayé de trouver des solutions sur des forums en anglais mais malgré mon niveau plus que suffisant j’en ai encore mal au crâne à force d’essayer de comprendre quelque chose, qui souvent n’est pas adapté à ce que je veux faire…

Pour le moment mon code est très simple :

char comSerie;

void setup()
{
  Serial.begin(9600, SERIAL_8N2);
}

void loop()
{
  if ( Serial.available())
  {
    comSerie = Serial.read();
    Serial.print(comSerie, HEX);
    Serial.println();
  }
}

Pin tx du module RFID connecté au pin 0 de l’arduino (rx), GND au ground, +9V soudé à la sauvage sur le connecteur batterie de l’arduino, avec une batterie branchée dedans (oui ça marche), le tout connecté au pc en usb pour la lecture des codes sur le moniteur série.

Ensuite, je n’ai pas besoin de lire l’entièreté des valeurs renvoyées, seulement à partir de la 2e jusqu’au 12e (voir dernière capture d’écran pour un exemple de lecture de boucle et ce que je veux garder).

IDE en version 1.8.5, arduino uno R3 version copie chinoise, Windows 10 pro x64

Voilà si je n’ai pas été assez clair n’hésitez pas à me demander plus de précisions, et merci d’avance de prendre du temps pour moi !

RFID reader module.pdf (295 KB)

Valeurs.png

Bonjour

Le format attendu est bien défini dans le pdf

Si vous lisez mon petit tuto sur le port serie c’est un peu la même approche : il faut en gros stocker dans un tableau de byte (au sein d’une union ce serait encore plus simple d’extraire certains champs) - vous cherchez un truc qui commence par 02 et fini par 03 et a le bon nombre d’octets et qui vérifie les checksum

Ensuite vous pouvez extraire ce que vous voulez de la trame

Merci de ta réponse, ce n’est pas exactement ce que je souhaitais, malgré tout ton code pour la réception de données sur le port série est beaucoup plus fiable que ce que j’avais fait et je t’en remercie grandement je ne connaissais pas trop ce domaine.

Mon problème principal est de pouvoir retrouver le numéro original de la boucle, or dans le tuto pdf je n’arrive pas à comprendre comment ils passent du numéro envoyé par le module (surligné en vert sur la photo) au numéro de la boucle (surligné en bleu) (le problème n’est pas dans le programme mais dans ma tête :slight_smile: ).

J’arrive bien à recevoir et à afficher en ASCII les nombres qui correspondent mais pas à comprendre comment obtenir les nombres codés dans les boucles :confused: .

voici comment j’ai tourné ton code pour en extraire les valeurs que je veux à convertir du coup en nombres qui correspondraient à ceux des boucles…

const byte tailleMessageMax = 11;
char messageBrut[tailleMessageMax + 1]; // +1 car on doit avoir un caractère de fin de chaîne en C, le '\0'
char message[tailleMessageMax];

const char marqueurDeFin = 3;

boolean ecouter()
{
  static byte indexMessage = 0; // static pour se souvenir de cette variable entre 2 appels consécutifs. initialisée qu'une seule fois.
  boolean messageEnCours = true;

  while (Serial.available() && messageEnCours)
  {
    int c = Serial.read();
    if (c != -1)
    {
      Serial.print(F("Octet lu: 0x")); Serial.print(c, HEX); // ici c est un entier, on affiche le code ASCII en Hexadécimal
      Serial.print(F("\t[")); Serial.print((char) c); Serial.println(F("]"));
      switch (c)
      {
        case marqueurDeFin:
          Serial.println(F("Fin de chaine"));
          messageBrut[indexMessage] = '\0'; // on termine la c-string
          indexMessage = 0; // on se remet au début pour la prochaine fois
          messageEnCours = false;
          break;
        default:
          if (indexMessage <= tailleMessageMax - 1) messageBrut[indexMessage++] = (char) c; // on stocke le caractère et on passe à la case suivante
          else //Serial.println(F("j'ignore!"));
            break;
      }
    }
  }
  return messageEnCours;
}

void setup()
{
  Serial.begin(9600, SERIAL_8N2);
}

void loop()
{
  if (! ecouter())
  {
    // on a reçu le marqueur de fin
    while (Serial.available())
    {
      Serial.read();
    }
    if (sizeof(messageBrut) > 9)
    {
      for (int i = 0; i <= tailleMessageMax + 1; i++)
      {
        message[i] = messageBrut[i + 1];

        Serial.print(atoi(message[i]));
      }
      Serial.print(F("Phrase retenue : [")); Serial.print(message); Serial.println(F("]"));
      Serial.println(sizeof(messageBrut));
    }
  }



  // ici on peut faire autre chose



}

Merci d’avance.

skichrome:
J'arrive bien à recevoir et à afficher en ASCII les nombres qui correspondent mais pas à comprendre comment obtenir les nombres codés dans les boucles :confused: .

il faut inverser le code en hexa avant de faire la conversion en décimal (LSB first)
171A9253A3-> 3A3529A171 -> 250000023921
idem pour le pays

Effectivement c'était ça mon problème ! Il ne me reste plus qu'à faire une fonction pour inverser le tableau et ensuite je ferais un système qui transettra le numéro par usb à un Raspberry qui fera un traitement un peu plus poussé (base de données entre autres).

J'ai aussi un problème de puissance d'antenne (il faut être à ras de l'antenne pour que la boucle soit lue) il va falloir que j'ajuste tout ça.

Un grand merci à vous deux !

Dans l’absolu Il suffit de lire le tableau à l’envers effectivement (si les octets sont entre les indices A et B du tableau, lire de B à A).

notez que vous n’avez pas besoin de fabriquer un « nombre » avec ces éléments, sur arduino ça sera compliqué car il est bcp plus long que les formats classiques (10 octets) et vous n’avez pas vraiment besoin de faire des maths avec ça, donc je garderai soit une représentation sous forme de chaîne de caractère, la représentation ASCII du codage HEXA, lu dans un sens ou dans l’autre restera un identifiant unique (faudra 21 octets) et c’est facilement imprimable ou simplement les 10 octets en question (mis dans l’ordre little endian ou big endian que vous souhaitez) pour économiser de la place mémoire.

Bien sûr si le stockage n’est pas un soucis vous pourriez conserver les 26 octets (en enlevant le 02, 03 et Check sums) vous serez prêt pour le futur si les octets réservés dans la spec venaient à être utilisés