Concatenation d'un mySerial.read() impossible

Bonjour,

Je tourne en rond depuis maintenant 5-6 heures sur un problème que j'ai pourtant réussi à isoler. Dans le code ci-dessous, je détecte une lecture d'un QRCode à partir d'un scanner TTL. Lorsque le passage du QRCode devant le scanner a lieu, j'entends un "bip" sonore puis, dans le "Serial Monitor" d'Arduino, le contenu du QRCode s'affiche correctement. Comme vous pouvez le voir dans la fonction readSerialData(), j'ai une boucle qui, à chaque caractère reçu, l'affiche dans la console, ce qui fonctionne parfaitement. Cependant, lorsque j'ajoute ce caractère à la variable "result", celle-ci reste toujours vide... Et c'est ici le problème : il m'est impossible de faire fonctionner la concaténation et de stocker le scan dans une variable.

Je ne comprend vraiment pas l'erreur, mon code est vraiment petit je ne devrais pas avoir de soucis de mémoire, et d'après ce que j'ai pu lire sur internet ma manière de faire devrait être fonctionnel.

String readSerialData() {
  String result = "";
  while (mySerial.available()) {
    char input = mySerial.read();
    Serial.print(input); // <-- Ici j'ai bien chaque caractere du scan 'A', 'B', 'D' qui s'affiche dans la console successivement
    result += String(input); // <-- Ici j'ai result qui reste vide
    delay(3); 
  return result; // <-- Ici je renvoi toujours un result vide
}
void loop() {
  String receivedData = readSerialData();
  if (receivedData.length() > 0) { // Ici je ne rentre jamais car receivedData est toujours vide
    Serial.println("Scan reçu");
    callWebhook(receivedData);
  }
}

Bonsoir,

Et en écrivant:

result.concat(input);

Cf. l'utilisation de concat()

A suivre...

Bonjour

Ton programme ne compile pas. il manque un } dans la fonction readSerialData

Effectivement un petit oublie mais uniquement ici sur le poste, certainement lié à la fatigue de hier soir ^^

Je viens de test la procédure que tu propose avec "concat()" et rien à faire...
Toujours le même probleme !

Voici le code actualiser :

String readSerialData() {
  String result = "";
  while (mySerial.available()) {
    char input = mySerial.read();
    Serial.print(input); 
    result.concat(input);
    delay(3); 
  }
  Serial.println("Result:");
  Serial.print(result);
  return result; 
}

Voici le résultat de la console :
IP Address: 192.168.1.115 Boot ok [...] <-- J'ai supprimé des lignes ici Result: https://url.site/params Result: [...] <-- J'ai supprimé des lignes ici

J'ai test ta proposition avec "concat()" et cela ne donne rien.
J'ai toujours le même probleme.

Voici le code à jour :

String readSerialData() {
  String result = "";
  while (mySerial.available()) {
    char input = mySerial.read();
    Serial.print(input); 
    result.concat(input);
    delay(3); 
  }
  Serial.println("Result:");
  Serial.print(result);
  return result; 
}

Voici ce qui sort de la console quand je scanne un qrcode :

IP Address: 192.168.1.115
Boot ok
Result: <-- de nombreuse fois
https://urlsite....
Result: <-- de nombreuse fois

Je ne pense pas que le problème vient de la concaténation. Vérifie (en ajoutant des Serial.print de débogage) que ton while a bien des données à traiter :

String readSerialData() {
  String result = "";
  if(mySerial.available()) {
    while (mySerial.available()) {
      char input = mySerial.read();
      Serial.print(input); 
      result.concat(input);
      delay(3); 
    }
    Serial.println("Result:");
    Serial.print(result);
  }
  else {
    Serial.println("No Data Available");
  }
  return result;

C'est bien la concaténation qui pose problème...
Voici le resultat de ton code :

No Data Available
No Data Available
https://monlien.frResult:
No Data Available
No Data Available

Fais l'essai (dans Wokwi par exemple) avec Serial à la place de mySerial pour vérifier le dysfonctionnement (chez moi, ça fonctionne correctement)

Pour plus de clarté, j'aurais dû inverser print et println et écrire :

String readSerialData() {
  String result = "";
  if(mySerial.available()) {
    while (mySerial.available()) {
      char input = mySerial.read();
      Serial.print(input); 
      result.concat(input);
      delay(3); 
    }
    Serial.println();
    Serial.print("Result: '");
    Serial.print(result);
    Serial.print("' (");
    Serial.print(result.length());
    Serial.println(" char)");
  }
  else {
    Serial.println("No Data Available");
  }
  return result;

Toujours le même problème... J'ai bien le qrcode caractère par caractère mais ma variable qui concatène reste vide. Comme mentionné plus haut j'utilise un lecteur de qrcode qui communique en TTL.

Je vous laisse ci-dessous le code complet de l'application. Je suppose maintenant que mon problème doit venir d'une librairie qui provoque un conflit de mémoire...

#include <SoftwareSerial.h>
#include <UIPEthernet.h>
#include <HttpClient.h>

// Initialisation du port série pour le scanner
SoftwareSerial mySerial(3, 4); // RX, TX

// Configuration Mac réseau
byte mac[] = {
    0xDE,
    0xAD,
    0xBE,
    0xEF,
    0xFE,
    0xED
};

// Adresse IP statique à ajuster selon votre réseau
IPAddress ip(192, 168, 1, 115);

// Configuration API
String API_URL = "https://monapi.fr?qrcode=";

  
// Configuration porte
#define DOOR_RELAY_PIN 6

EthernetClient client;

void setup() {
    // Initialisation console
    Serial.begin(9600);

    // Initialisation scanner
    mySerial.begin(9600); // set the data rate for the SoftwareSerial port

    // Initialisation porte
    pinMode(DOOR_RELAY_PIN, OUTPUT);
    digitalWrite(DOOR_RELAY_PIN, LOW);

    // Connexion réseau
    Ethernet.begin(mac, ip);

    Serial.print("IP Address: ");
    Serial.println(Ethernet.localIP());

    Serial.println("Boot ok");

}

String readSerialData() {
  String result = "";
  if(mySerial.available()) {
    while (mySerial.available()) {
      char input = mySerial.read();
      Serial.print(input); 
      result.concat(input);
      delay(3); 
    }
    Serial.println();
    Serial.print("Result: '");
    Serial.print(result);
    Serial.print("' (");
    Serial.print(result.length());
    Serial.println(" char)");
  }
  else {
    Serial.println("No Data Available");
  }
  return result;
}

void loop() {
  String receivedData = readSerialData();
  if (receivedData.length() > 0) { // Check if any data was received
    Serial.println("Scan");
    callWebhook(receivedData); // Print the received data
  }
}

void openDoor() {
    // Envoi signal ouverture porte
    digitalWrite(DOOR_RELAY_PIN, HIGH);
    delay(3000);
    digitalWrite(DOOR_RELAY_PIN, LOW);
}

void callWebhook(String qrcode) {

    Serial.print("QrCode: ");
    Serial.println(qrcode);

    // Construction de l'URL de l'API
    String urlPath = String(API_URL) + String(qrcode);

    Serial.print("URL request: ");
    Serial.println(urlPath); 

    // Initialisation de HttpClient avec SSL (HTTPS)
    HttpClient http(client, "monsite.fr", 443); // Utilisation de port 443 pour HTTPS

    http.get(urlPath);

    // Gestion de la réponse
    int statusCode = http.responseStatusCode();
    String response = http.responseBody();

    Serial.print("HTTP Response code: ");
    Serial.println(statusCode);
    Serial.print("HTTP Response body: ");
    Serial.println(response);

    if (statusCode > 0) {
        if (response == "1") {
            // Ouverture de la porte
            Serial.println("Open door");
            openDoor();
        } else {
            Serial.println("Bad response");
        }
    } else {
        Serial.println("Api error");
    }

    delay(3000);

}

Bonsoir thony67

Pourquoi ne pas lire le port série "d'un coup" avec Serial.readString()

Penser a mettre un Timout au port serie, Serial.setTimeout(), 50 suffit.

Cordialement
jpbbricole

Alors finalement j'ai réussi à concaténé le string il y à 20mn, le soucis provient bien d'un problème de mémoire ou similaire, j'ai supprimer une fonction et grâce à cela mon code à réussi à s'exécute correctement mais je bloque plus loin dans d'autres concaténation qui elle fonctionne pourtant de manière autonome.

C'est peut être aussi un problème de carte ... Je vais la remplacer demain pour voir ce que cela donne.

vous êtes sur quel Arduino ? que dit le compilateur sur la mémoire utilisée quand vous compilez ?

la classe String n'est pas très sympa lorsque la mémoire vient à manquer, bien souvent l'application ne plantera pas (sur AVR) mais l'opération (concaténation etc) demandée ne s'effectuera pas.

ne pas mettre de delay() dans la lecture du port série, si trop de données arrivent d'un coup vous allez remplir le buffer et au bout d'un moment perdre des données.

Pour la gestion d'une communication asynchrone comme le port série, vous pouvez jeter un oeil à mon petit tuto sur le sujet

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.