Bonjour,
Je vais essayer de faire synthétique,
Je reçois sur l'arduino via UART une chaine de 16 valeurs (base 16, compris entre 0 et F), exemple : BBFC0000013A81E5
Comment est il possible SVP d'isoler que les 5 dernières valeurs?
pour ensuite (ça ce complique encore..) convertir les lettres en chiffre quand il y en a ?
(avec A = 1, B=2,...., jusqu'a F=6 avec une petite subtilitée, si il y'a un 0=7 )
la finalité étant ensuite d'envoyer les 5 chiffres sur le LCD (ici dans l'exemple) : 18155
merci à tous ceux qui ont des idées ! car je début et j'en ai aucune idée...
mais je suis près à apprendre si j'y arrive
merci
pourquoi 5 lettres ? est-ce de l'hexa ? càd que vous avez en fait 8 x 2 caractères pour 8 octets ?
Pourquoi voulez vous faire A = 1 ? A devrait être 10 en hexadécimal (sinon comment le différencier de 1)
êtes vous 100% sûr de toujours recevoir 16 caractères et vous savez exactement où ça commence ?
clarifiez cela avant de poser la moindre ligne de code...
sinon un petit bout de code qui lit 16 caractères hexadécimaux indépendant et stocke leur valeur dans un tableau, c'est assez simple à écrire en non bloquant
const uint8_t tailleBuffer = 16;
uint8_t valeurs[tailleBuffer];
bool recevoir16CaracteresHexa(bool raz = false)
{
static uint8_t index = 0;
if (raz) {
index = 0;
return false;
}
int b = Serial.read();
if (b == -1) return false; // -1 veut dire rien à lire
bool hexDigit = true;
if ((b >= '0') && (b <= '9')) valeurs[index] = b - '0';
else if ((b >= 'a') && (b <= 'f')) valeurs[index] = b - 'a' + 10;
else if ((b >= 'A') && (b <= 'F')) valeurs[index] = b - 'A' + 10;
else hexDigit = false;
if (! hexDigit) return false; // ce n'était pas un caractère acceptable en HEXA on l'ignore
if (++index >= tailleBuffer) {
index = 0;
return true; // on a rempli le tableau
}
return false;
}
void setup() {
Serial.begin(115200);
}
void loop()
{
if (recevoir16CaracteresHexa()) {
Serial.println(F("J'ai bien reçu tous les éléments"));
for (uint8_t i = 0; i < tailleBuffer; i++) {
Serial.print(i+1);
Serial.print(F("\t -> "));
Serial.println(valeurs[i]);
}
}
}
tant que la fonction recevoir16CaracteresHexa()
ne répond pas 'true' (vrai) alors on n'a pas reçu le message. Dès qu'on a eu 'true' alors les 16 valeurs converties ('0' -> 0, '1' -> 1, ... '9' -> 9, 'A' -> 10, 'B' -> 11, ... 'F' -> 15) sont dans le tableau valeurs[]
il vous suffit de lancer le code ci dessus avec la console à 115200 bauds et taper dans la console série vos données par exemple BBFC0000013A81E5 et vous verrez dans le moniteur série (à 115200 bauds)
[color=purple]
J'ai bien reçu tous les éléments
1 -> 11
2 -> 11
3 -> 15
4 -> 12
5 -> 0
6 -> 0
7 -> 0
8 -> 0
9 -> 0
10 -> 1
11 -> 3
12 -> 10
13 -> 8
14 -> 1
15 -> 14
16 -> 5
[/color]
si vous ne voulez que les 5 dernières valeurs, elles sont donc lisible avec
for (uint8_t i = tailleBuffer-5; i < tailleBuffer; i++) {
Serial.print(i+1);
Serial.print(F("\t -> "));
Serial.println(valeurs[i]);
}
Tout d'abord merci pour votre réponse !
Oui à la base c'est de l'hexadecimale (dans l'exemple BB ; FC ; 00 ; ...) mais avant d'être envoyé vers l'Arduino, c'est modifié pour envoyer tout attaché BBFC00....
(ceci dit si ça complique l'exercice, je dois pouvoir faire en sorte de recevoir directement les valeures hexadécimales sans cette "remise en forme")
Pour la conversion de A=1 etc, oui je sais, ça peut paraître étonnant, mais c'est bien cette conversion qu'il me faut.
Je peux recevoir différentes chaines de caratère, mais avec le même résultat !
Si je reprend un exemple, le message pour être :
BBFC0000013A81E5, avec récupération de A81E5, qui devient le résultat à afficher : 18155
mais aussi :
BBFC0000013181E5, avec récupération de 181E5, qui devient le résultat à afficher : 18155
ou encore:
BBFC0000013A8155, avec récupération de A8155, qui devient le résultat à afficher :18155
et aussi comme j'indiquai la subtilité du 0 = 7, exemple:
BBFC0000013A8150, avec récupération de A8150, qui devient le résultat à afficher :18157
Pour répondre à la question, oui je reçois bien toujours par 16 caractères uniquement.
(comme dit au début de ce post, à la base c'est 8 valeurs hexadécimales "BB FC 00 00 01 3A 81 E5" pour l'exemple)
Super merci pour les infos des codes, là j'écris ce message, mais je ne pourrais tester cela que ce soir malheureusement.
merci
il ne sera pas difficile de modifier le code pour retourner 1 pour A au lieu de 10 - en modifiant le +10 en +1 dans
else if ((b >= 'a') && (b <= 'f')) valeurs[index] = b - 'a' + 10;
else if ((b >= 'A') && (b <= 'F')) valeurs[index] = b - 'A' + 10;
pour faire le calcul que vous souhaitez et traiter le 0 à part
if (b == '0') valeurs[index] = 7;
else if ((b > '0') && (b <= '9')) valeurs[index] = b - '0';
ça me parait quand même très louche... Quel est l'usage exact ?
ok merci ! ce soir j'essai de m'ateller à tous cela et vous tiens au courant (je débute alors je suis pas rapide..)
oui je sais c'est pas courant, c'est une lecture d'un transpondeur qui est fournit avec un code court 5 chiffres, et ceci me permettrait de retrouver le code qui va avec le transpondeur dont on a perdu le code (du moins le code je sais le récupérer, là c'est pour que ce soit facile en affichant le code sur ecran LCD sans avoir à faire le travail de conversion dans la tête )
bonjour,
alors super merci le code avec la console série ça fonctionne impeccable !
(j'aurai jamais réussi tous seul)
j'ai même réussi à intégrer le fonctionnement de mon LCD, hormis que pour le moment les chiffres s'écrivent les un sur les autres (en s'effacent entre eux), et non pas tous à la suite sur le LCD, j'ai pas encore trouvé comment faire.
Ensuite forcement, j'ai voulu ensuite intégrer le code que j'avais trouvé pour la réception du tag RFID sur la connectique UART, et ça déconne.
Avec le code (plus bas) :
1/quand je passe le transpondeur j'arrive à recevoir sur la console serie du PC:
-->le code s'écrit en entier "brut" (16 caractères) sans être traité (ça n'utilise pas ton code à priori)
-->mais rien ne s'affiche sur le LCD (j’imagine qu'il n'est pas capable d'écrire ces 16 caractères)
2/ quand j'envoi manuellement ma suite de 16 caractères par la console série du PC,
--> j'ai bien les 5 chiffres traités sur le LCD qui s'écrivent (mais qui s'écrivent les uns sur les autres)
--> par contre j'ai plus rien qui s'affiche sur la console série sur le PC (avant j'avais bien les 5 chiffres les uns après les autres)
Alors déjà au delà d'un problème de code, je me demande si y'a pas un bug (ou conflit) du fait d'être connecté au PC d'un côté, et avec aussi un autre matériel connecté sur l'UART (vcc/gnd/rx/tx), car quand je veux téléverser, faut que je déconnecte la liaison UART de mon autre matériel (lecture RFID) sinon ça plante...(rien ne se téléverse)
voici mon code J-M-L si tu arrives à détecter le problème ! ???
merci!
#include <SoftwareSerial.h>
#include <Wire.h>
#include "rgb_lcd.h"
#define rxPin 0
#define txPin 1
rgb_lcd lcd;
const int colorR = 255;
const int colorG = 0;
const int colorB = 0;
const uint8_t tailleBuffer = 16;
uint8_t valeurs[tailleBuffer];
//------------------------------------
//create a Serial object RFID
SoftwareSerial RFID= SoftwareSerial(rxPin, txPin);
bool recevoir16CaracteresHexa(bool raz = false)
{
static uint8_t index = 0;
if (raz) {
index = 0;
return false;
}
int b = Serial.read();
if (b == -1) return false; // -1 veut dire rien à lire
bool hexDigit = true;
if ((b >= '0') && (b <= '9')) valeurs[index] = b - '0';
if (b == '0') valeurs[index] = 7;
else if ((b >= 'a') && (b <= 'f')) valeurs[index] = b - 'a' + 1;
else if ((b >= 'A') && (b <= 'F')) valeurs[index] = b - 'A' + 1;
else if ((b > '0') && (b <= '9')) valeurs[index] = b - '0';
else hexDigit = false;
if (! hexDigit) return false; // ce n'était pas un caractère acceptable en HEXA on l'ignore
if (++index >= tailleBuffer) {
index = 0;
return true; // on a rempli le tableau
}
return false;
}
void setup() {
Serial.begin(19200);
lcd.begin(16, 2);
lcd.setRGB(colorR, colorG, colorB);
// Print a message to the LCD.
lcd.print("code:");
}
void loop()
{
if (recevoir16CaracteresHexa()) {
Serial.println(F("J'ai bien reçu tous les éléments"));
for (uint8_t i = tailleBuffer-5; i < tailleBuffer; i++) {
Serial.println(valeurs[i]);
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
lcd.print(valeurs[i]);
delay(1000);
}
}
}
#define rxPin 0
#define txPin 1
//create a Serial object RFID
SoftwareSerial RFID = SoftwareSerial(rxPin, txPin);
ces pins sont réservées sur un UNO ou similaire à la connexion USB. Vous ne pouvez pas les utiliser en même temps pour un autre accessoire série.
prenez d'autres pins par exemple 2 et 3, et c'est à ça que sert SoftwareSerial --> simuler un port série en logiciel
il manque un RFID.begin(xxx); pour dire cependant au port série de démarrer. (mais est-ce que votre lecteur RFID en vraiment Série ? lequel avez vous ?)
Vos caractères s'écrivent les uns sur les autres parce que vous faites ça
for (uint8_t i = tailleBuffer - 5; i < tailleBuffer; i++) {
Serial.println(valeurs[i]);
lcd.setCursor(0, 1); // <===== TOUJOURS AU DEBUT
lcd.print(valeurs[i]);
delay(1000);
}
si vous disiez au programme que vous voulez le ième caractère en position i sur le LCD ils ne se superposeraient pas, donc mettre lcd.setCursor(i-(tailleBuffer - 5), 1);
devrait fonctionner car i varie entre (tailleBuffer - 5) et (tailleBuffer-1) donc i-(tailleBuffer - 5) va varier entre 0 et 4 ==> les 5 premiers caractères de votre LCD
ha ok, je met pin 2 et 3 alors !
effectivement il me manquait le RFID.begin(19200); alors que je l'avais mis à un moment
ce que je comprend pas, j'ai du faire une mauvaise manipulation forcement, car avec le code que j'ai indiqué je n'arrive plus à récupérer le tag RFID sur me moniteur série...même en remettant "RFID.begin" c'est bizarre...
en matériel j'ai ça :
et au cas où je précise si jamais ça a son importance (mais je crois pas ?), j'ai ce matériel avec le câblage qui arrive sur "UART" (en bas à gauche de l'image)
en tous cas encore une fois merci pour les infos et explication, je comprend mieux pour le LCD et ça fonctionne bien maintenant pour cette partie là du moins !
merci
EDIT : connectique 4 d'où provient l'info
vous avez bien croisé les Rx et Tx ? les GNDs sont bien connectés entre les cartes ? vous êtes sûr que le débit est 19200 bauds ?
oui j'ai bien croisé RX/TX j'avais vu que c'était inversé entre les 2 cartes, et oui les GND sont bien connectés entre les cartes car j'alimente le lecteur RFID via la carte seeeduino (câblage avec GND/VCC/RX/TX entre les 2 cartes) et oui je suis sûr pour le débit car c'est celui de mon lecteur RFID et je m'aligne sur ce réglages avec le seeeduino.
J'arrive pas à savoir pourquoi, mais avec le même code, dès fois je peux réussir à lire le tag RFID complet sur le moniteur série, et dès fois rien du tout, idem pour le test manuellement en envoyant les 16 caractères dans le moniteur série pour que le code 5 chiffres s'affiche (moniteur + LCD).
J'ai l'impression que c'est soit l'un, soit l'autre, (de façon aléatoire) comme si les 2 se disputaient la voies série de communication, malgré le changement de RX et TX avec d'autres adressages de PIN (2;3 ou même 6;7)
Ensuite en ce qui concerne le code,
je me demande si il faudrait pas que à la place de :
int b = Serial.read();
il faudrait pas quelque chose comme :
unsigned chart b = RFID.read();
pour prendre la chaine depuis le lecteur RFID et non pas depuis le moniteur série ?
mais quand j'essaie ça ne fonctionne pas.
j'ai même essayé d'alimenter le seeeduino (et par découlement le lecteur RFID via le câblage) via une alim externe pour ne plus avoir l'USB vers le PC et éviter potentiellement des conflits avec le port COM, mais rien ne s'affiche sur l'écran LCD.. mais aucune idée du coup si c'est mon code qui fait que rien ne peux être affiché sur le LCD, ou si c'est un problème de lecture aléatoire du tag RFID..
désolé du pavé avec mes problèmes..
Non non il ne faut pas un unsigned char cat après on fait
if (b == -1)
Donc faut un int qui est ce que read() va retourner
Difficile de vous dire pourquoi ça ne fonctionne pas
Vérifiez la consommation électrique de votre capteur et s’il faut pas l’alimenter séparément
ok merci je vais voir ce que je peux faire !
bon pour le moment rien de bien nouveau, mais j'ai vérifié la sortie du lecteur RFID c'est :
"UART OUTPUT TYPE: Ascii"
pour être sûr, c'est compatible avec le code "int b = Serial.read();"
merci !
dct748:
bon pour le moment rien de bien nouveau, mais j'ai vérifié la sortie du lecteur RFID c'est :
"UART OUTPUT TYPE: Ascii"
pour être sûr, c'est compatible avec le code "int b = Serial.read();"
merci !
oui pas de souci avec cela. vérifiez bien vos pins 2 et 3 et l'ordre Tx et Rx.
êtes vous sûr que votre module RFID est en 5V ?
ça fonctionne !!!
j'ai essayé différentes configurations, d'alimenter en 9V le lecteur rfid, qui lui même alimentait le seeeduino, changé les câblages, changé avec une ancienne carte Selectronic, bien refaire les connectiques, bref...j'ai vu votre message et je me suis dit aller même si j'ai vérifié 20 fois et que c'est ok, j'essais d'inverser Tx/Rx sais t-on jamais, et ça fonctionne :o :-X
en fait, il y a une erreur d'indication écrite sur la carte !!!! c'est indiqué RX à la place de TX et inversement... comme sur l'image du post un peu avant !!
et en vérifiant sur une autre photo constructeur, j'ai vu que entre la photo et les indications lisibles sur la carte c'est différent...
le pire c'est que j'avais remarqué que c'était inversé par rapport à l'habitude (GND/VCC/TX/RX), et je m'en étais étonné, mais j'ai pas percuté que ça pouvait être simplement une erreur d'indication sur la carte... passer des heures juste pour ça c'est rude.
en tous cas merci J-M-L sans toi j'aurai jamais réussi !! grand merci !!
bon si je peux abuser une dernière petite fois
j'ai voulu ajouter un "lcd.clear();" mais si j'ai bien compris le fonctionnement, la boucle s’exécute 5 fois de suite pour arriver aux 5 chiffres, du coup si j'ajoute l'effacement à la fin de la boucle, ça s'efface entre chaque chiffres.. (normale).. il existe une astuce pour lui dire d'effacer par exemple après 10 secondes, mais que une fois que les 5 chiffres ont été affichés ?
merci encore !
j'ai voulu ajouter un "lcd.clear();" mais si j'ai bien compris le fonctionnement, la boucle s'exécute 5 fois de suite pour arriver aux 5 chiffres, du coup si j'ajoute l'effacement à la fin de la boucle, ça s'efface entre chaque chiffres.. (normale).. il existe une astuce pour lui dire d'effacer par exemple après 10 secondes, mais que une fois que les 5 chiffres ont été affichés ?
oui vous avez bien compris.
pour l'effacement au bout de 5 secondes il faut noter le moment où vous avez effectué un affichage. Vous déclarez deux variables globales
bool affichageUID = false;
uint32_t chrono;
quand vous faites l'affichage, au cas où vous faites un lcd.clear(); // ou des espaces sur la zone cible
juste avant, puis vous faites la boucle qui fait l'affichage de l'UID. une fois l'affichage effectué, vous notez que vous venez de le faire en faisant
affichageUID = true;
chrono = millis();
Ensuite en début de loop() vous faites
if (affichageUID && (millis() - chrono >= 5000)) { // efface au bout de 5 secondes
lcd.clear(); // ou juste mettre des espaces dans la zone d'affichage si vous ne voulez pas tout effacer
affichageUID = false;
}
mettre des espaces c'est sans doute mieux car ça évite le clignotement de l'écran et si vous avez d'autres choses affichées, ça ne les enlève pas.
ça fonctionne impeccablement !! trop fort J-M-L !
merci pour tout !
8)
avec plaisir - bons bricolages !