Serial.print D au lieu de 0D et D0 au lieu de 0D

Bonjour,

J'essaie de créer un petit boitier avec 2 ports série (1 in et 1 out). Ce boitier à pour but de s'intercaler entre 2 appareils (1 automate et 1 appareil à piloter en port série(vidéoprojecteur, écran, ici nous prendrons VP pour vidéoprojecteur) dans le cas ou le VP à piloter est remplacé par un autre modèle qui ne comporte pas les même codes de pilotage. Pour pouvoir modifier les codes à comparer entre l'ancien et le nouveau modèle, un fichier texte sur la carte SD est nécessaire. La structure d'une ligne dans ce fichier est celle ci :

command \x0D*pow=on#\x0D = PWR ON

Pour mes test j'utilise un automate qui envoi par exemple le code

\x0D*pow=on#\x0D

Les \x indiquent à l'automate qu'il doit envoyer de l'hexa si pas \x il considère que c'est de l'ASCII.

A partir des exemples ci-dessus l'ancien VP nécessite la commande \x0D*pow=on#\x0D pour s'allumer, le nouveau nécessite PWR ON

J'arrive en string à lire les valeurs reçues les comparer et les renvoyer. La où je bute c'est pour lire les valeurs hexadécimal.

Avec le code ci-dessous si l'automate envoi \x0D*pow=on#\x0D j'obtiens dans le Serial.print les bonnes valeurs hexa à l'exception du \x0D soit 0x0D de début et de fin. Voici le code dans le print :

D	2A	70	6F	77	3D	6F	6E	23	D	0

Le D du début devrait être précédé d'un 0 et les 2 derniers devrait être 0D et non D0.

Mon code vous semblera surement très brouillon, je suis débutant et j'assemble des morceaux de code étape par étape pour arriver à mes fins. (Il n'y a pas la totalité du code, la suite concerne la comparaison avec le fichier texte et pour le moment mon problème concerne le print à réception).

#include <SdFat.h>
#include <SPI.h>

String Answer;
String keyword;
String commanderecue;

long aLong;


SdFat sd;
SdFile file;

const size_t LINE_DIM = 100; // Maximum line length plus space for zero byte

char line[LINE_DIM];

File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial1.begin(9600);
  Serial1.print("Connected to arduino1!");

  Serial2.begin(38400,SERIAL_8N1);
  Serial2.print("Connected to PC!");
  
  Serial1.print("Initializing SD card...");


    if (!sd.begin(4, SPI_FULL_SPEED)) {
    Serial1.println("initialization failed!");
    while (1);
  }
  Serial1.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
//  myFile = SD.open("test.txt", FILE_WRITE);

}

void loop() {


if(Serial1.available()>0)
  {
    
   keyword = Serial1.readStringUntil('\n');

    String str = keyword;
    int str_len = str.length() + 1;

    char char_array[str_len];

    str.toCharArray(char_array, str_len);
    
for (byte i = 0; i < str_len; i = i + 1) {

  aLong = strtol(char_array[0], NULL, 16);
  Serial.print(char_array[i], HEX);

  Serial.print("\t");
}



Une fois le problème résolu, j'aimerai discuter du fait de se passer des string, j'ai lu qu'il pouvait raccourcir la vie de l'Arduino en causant des problèmes mémoires. Mais je ne sais pas par où commencer pour supprimer la partie String.

Merci pour votre aide, la recherche google ne m'a pas permis de trouver de réponse à ce problème, 2 soirs (nuits) que je suis dessus.

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

Désolé pour cette erreur de débutant, je n'ai pas vu cette info lors de mon inscription. Mais je note pour la prochaine fois.

Ceci envoi en hexa la valeur, mais il n'y a pas les zéros non significatifs. C'est donc normal que l'envoi de 0x0D donne que D. Il suffit de rajouter le zéro manquant si le nombre est plus petit que 16. Par exemple remplacer la ligne ci dessus par:

if (char_array[i] < 0x10) Serial.print('0');
Serial.print(char_array[i], HEX);

L'avant dernier doit bien être D soit 0D avec la correction, mais il y a un nombre 0 en plus(compte les caractères. Je suppose que l'automate envoie une chaine qui se termine par un 0.

1 Like

Merci énormément pour cette réponse limpide, fonctionnelle et si rapide.

Au passage j'ai édité mon post car dans la ligne

aLong = strtol(char_array[0], NULL, 16);

initialement j'avais mis

aLong = strtol(char_array[0], 0, 16);

pour faire un test.

Je n'arrive pas à trouver l'explication de la fonction de ce NULL? lorsque je cherche la définition de strol, je ne tombe pas sur des explications claire sur ce point.

Je suppose que l'automate envoie une chaine qui se termine par un 0.

Je vais vérifier cela, sinon je peux le supprimer.
Dois-je le supprimer juste avant le Serial.print ou je peux modifier

    int str_len = str.length() + 1;

par

    int str_len = str.length();

Je pense que ma proposition ne fonctionnera pas car il va pas supprimer le dernier caractère.

Après test cela supprime le dernier 0D et non pas le 00.

Si la chaine à convertir contient des lettres, par exemple "3 ptits chats", la fonction va retourner 3. L'espace n'étant pas un nombre elle s'arrête. Mais elle peut aussi donner un pointeur sur la chaîne qui ne peut être convertie. Ici en l'occurrence " ptits chats". Ceci permet une analyse de la chaine par exemple si il y a plusieurs paramètres.
En passant NULL, on n'utilise pas cette possibilité.

1 Like

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