bonjour à tous,
je cherche à récupérer une adresse ip qui est envoyée sur le port série ex: VarIp=192.168.1.45
Le problème que je rencontre c'est que je suis limité en effet si j’envoie VarIp=192.168.1.45 cela ne fonctionne pas, si j’envoie la même chose sans le 5 (le dernier chiffre) c'est ok.
Merci d'avance pour votre aide
voici mon code :
String inputString = "";
String ipAddress = ""; // Variable qui contiendra la saisie après "VarIp="
// Fonction pour vérifier si le texte commence par "VarIp"
bool startsWithVarIp(const String& text) {
return text.startsWith("VarIp=");
}
void setup() {
// Initialize serial communication
{
Serial.begin(115200);
Serial.println("ComVarIp");
delay(200);
}
while (true) {
// Vérifier si des données sont disponibles dans le port série
if (Serial.available() > 0) {
// Lire les données disponibles
char incomingChar = Serial.read();
// Ajouter le caractère à la chaîne d'entrée
ipAddress += incomingChar;
// Si le caractère reçu est un saut de ligne ou un retour chariot, on le considère comme une ligne complète
if (incomingChar == '\n' || incomingChar == '\r') {
// Enlever les espaces inutiles et trim la chaîne
ipAddress.trim();
// Si la chaîne commence par "VarIp=", on extrait ce qui suit "="
if (startsWithVarIp(ipAddress)) {
// Extraire la partie après "VarIp="
String extractedData = ipAddress.substring(6); // "VarIp=" fait 6 caractères
Serial.println(F("Commande 'VarIp' détectée. Donnée extraite :"));
Serial.println(extractedData);
Serial.println(F("le script continue !!!!"));
break; // Sortir de la boucle d'attente
} else {
// Si la saisie n'est pas "VarIp=", afficher un message et recommencer
Serial.println(F("Ce n'est pas une commande valide. Essayez encore..."));
ipAddress = ""; // Réinitialiser la chaîne pour recommencer
}
}
}
}
}
void loop() {
}
Bonjour et merci pour votre réponse rapide cela fait plaisir de se sentir soutenu
en fait je crois savoir pourquoi :
void setup() {
// Initialize serial communication
{
Serial.begin(115200);
Serial.println("ComVarIp");
//delay(200);
//Serial.println("ComVarListsalons");
}
si je n'envoies qu'une commande Serial.println c'est ok si j'envoie les deux à la suite cela coince
De plus, oui en effet, je pense aussi car je suis tendu au niveau mémoire mais je n'ai pas le niveau de dev pour remplacer les String par char ...
Merci encore.
pas dans le petit exemple que vous donnez et il n'y a aucune raison que ce soit le problème en soi.
C'est peut être un souci mémoire. Si vous faites le test dans votre "gros" code, il se peut en effet qu'il y ait un souci mémoire. Activez tous les warning dans les préférences et regardez aussi combien de RAM il vous reste une fois que vous avez compilé ➜ ça dit quoi ?
un truc simple pour regagner de la RAM, c'est d'utiliser la macro F() dans vos affichages de texte. Au lieu de
Serial.println("ComVarIp");
faites
Serial.println(F("ComVarIp"));
➜ remplacer tous les print de texte par cette forme, ça met le texte en mémoire flash au lieu de dupliquer et de l'avoir en flash + RAM.
en effet la cela passe nickel
Une petite aide pour transformer le string en char dans mon code ne serait pas de refus mais je ne veux pas abuser de votre gentillesse ...
J
Pour saisir des paramètres depuis la ligne de commande, c'est plus simple en utilisant la fonction:
ipAddress = Serial.readStringUntil('\n');
Le programme:
String ipAddress = ""; // Variable qui contiendra la saisie après "VarIp="
const int ipAddressLenght = 15;
char ipAddressChar[ipAddressLenght+1]; // IP adresse en char
void setup() {
// Initialize serial communication
{
Serial.begin(115200);
delay(200);
Serial.println("ComVarIp");
}
}
void loop()
{
if (Serial.available())
{
ipAddress = Serial.readStringUntil('\n');
ipAddress.trim();
if (ipAddress.startsWith("VarIp="))
{
ipAddress.replace("VarIp=", ""); // Supprimer "VarIp="
ipAddress.toCharArray(ipAddressChar, ipAddress.length() +1);
Serial.println(F("Commande 'VarIp' détectée. Donnée extraite :")); // IP en char
Serial.println(ipAddress);
Serial.println(F("le script continue !!!!"));
}
else
{
// Si la saisie n'est pas "VarIp=", afficher un message et recommencer
Serial.println(F("Ce n'est pas une commande valide. Essayez encore..."));
ipAddress = ""; // Réinitialiser la chaîne pour recommencer
}
}
}
byte adresseIP[4];
void lireIP() {
constexpr byte bufferSize = 32;
char buffer[bufferSize];
byte index = 0;
char currentChar;
while (true) {
// Lire une ligne terminée par '\n'
index = 0; // Réinitialiser l'index pour chaque nouvelle lecture
while (index < bufferSize - 1) {
if (Serial.available()) {
currentChar = Serial.read();
if (currentChar == '\n') break; // Arrêter la lecture si on atteint un retour à la ligne
if (!isspace(currentChar)) buffer[index++] = currentChar; // Ignorer les espaces
}
}
buffer[index] = '\0'; // Terminer la chaîne
Serial.print("J'ai reçu : "); Serial.println(buffer);
// Vérifier le format et extraire les octets IP
int octet1, octet2, octet3, octet4;
if (sscanf(buffer, "VarIp=%d.%d.%d.%d", &octet1, &octet2, &octet3, &octet4) == 4) {
// Vérifier que les octets sont dans la plage valide
if ((octet1 >= 0 && octet1 <= 255) &&
(octet2 >= 0 && octet2 <= 255) &&
(octet3 >= 0 && octet3 <= 255) &&
(octet4 >= 0 && octet4 <= 255)) {
adresseIP[0] = octet1;
adresseIP[1] = octet2;
adresseIP[2] = octet3;
adresseIP[3] = octet4;
break; // Quitter la boucle après avoir reçu une adresse IP valide
}
} else {
Serial.println("Format invalide. Réessayez.");
}
}
}
void setup() {
Serial.begin(115200);
Serial.println("Entrez l'adressse IP.");
lireIP(); // fonction bloquante
Serial.print("Adresse IP extraite : ");
Serial.print(adresseIP[0]);
Serial.print(".");
Serial.print(adresseIP[1]);
Serial.print(".");
Serial.print(adresseIP[2]);
Serial.print(".");
Serial.println(adresseIP[3]);
}
void loop() {}
ça devrait aller extraire l'adresse IP et mettre les valeurs dans le tableau d'octets.
l'appel à la fonction lireIP () est bloquant tant qu'on n'a pas reçu quelque chose de cohérent.
Il y a un petit contrôle de cohérence mais si vous tapez "VarIp=192.168.1.45.coucou" par exemple, ça va fonctionner quand même.
On pourrait faire moins gourmand encore en n'utilisant pas sscanf() et utilisant strncmp() et strtol() mais ça complexifie un peu le code
Bonjour JP,
Merci pour ton aide cela fonctionne bien dans ce cas de figure si je rentre 192.168.1.45
dans le même ordre d'idée je souhaiterai pouvoir intercepter une chaine de caractères qui possède des espaces ex : (67) BOUTIQUE A, (88) BOUTIQUE B et la cela coince, je pense que c'est la fonction .trim tu aurais une idée merci encore Cordialement.
Si vous voulez étudier comment écouter le port série (ou gérer un flux asynchrone genre keypad) vous pouvez jeter un oeil à mon petit tuto sur le sujet
Il y a une fonction qui écoute le port série jusqu’à la fin de ligne et de façon non bloquante
La fonction trim() n'enlève les espaces qu'au 2 bouts de la chaîne-
Je n'ai pas compris quel est le problème, tu n'arrive pas à saisir une chaîne avec des espaces?
Si l'on utilise un terminal comme le moniteur de l'IDE Arduino ou tout autre émulateur asynchrone, la chaîne introduite n'est pas envoyée caractère aprés caractère (à la volée), mais d'un bloque, en cliquant sur le bouton d'envoi ou usage de la touche Enter, donc pas de problème de vitesse de frappe.
Le seul cas où il peut y avoir un timout sur Serial.readStringUntil, est l'oubli de la terminaison attendue, dans les paramètres du terminal.
Bon je n'y arrive pas avec le VarStock, en fait si j'entre VarStock=TOTO pas de problème, si j'entre VarStock=(54) BOUTIQUE A, cela coince ... https://wokwi.com/projects/412612328842067969
Merci encore à la communauté pour votre aide
Oui pour le moniteur série de l’arduino (ce n’est pas envoyé d’un bloc mais à la vitesse en bauds définie avec potentiellement des ralentissements dûs à l’émetteur si par hasard votre PC fait aussi autre chose mais ce n’est généralement pas suffisamment bloquant pour atteindre le timeout par défaut qui est d’une seconde).
Par contre d’autres terminaux peuvent envoyer les touches à la volée et la ce pourrait être un souci.
non les espaces ne sont pas supprimés et c'est le but mais essayes mon script sur wokwi tu verras que la trame VarStock=(XX) BOUTIQUE A ne passe pas ?
Commande 'VarStock' détectée. Donnée extraite :
(55) BOUTIQUE A
VarStock est :
le script continue !!!!
Pour passer de la page 0 à 1 il faut juste entre VarIp=192.111111 etc et le script se poursuit
si l'on entre VarStock=TOTO pas de pb si espace cela coince et je ne l'explique pas ?
Si tu utilise uniquement le woki, ton problème est celui décrit pas @J-M-L.
Le timeout ce déclenche avant l'arrivé du \n,
A mon avis le mieux serait d'utiliser la façon commune de lire un port série
while (Serial.available() > 0) {
incomingChar = Serial.read();
VarDatas += incomingChar;
if (incomingChar == '\n') {
break;
}
}
tu peux aussi garder le readStringUntil mais vérifier que tu as bien tout lu, puisque comme l'indique @J-M-L tu n'a pas de garantit de toujours recevoir la chaine en une seul fois.