Recuperer des byte d'un char

Bonjour,

Je communique via série sur un module qui me renvoie une valeur, DATA=123

J'aimerai uniquement récupérer la valeur 123 (qui varie de 000 à 255)

Je ne sais pas trop comment "nettoyer" char de "DATA="
(ou bien plus proprement récupérer les 3 derniers caractères que je dois convertir de 0 à 9 après ...)

//Test debug sur ecran 2x16

void get_level()
{
   char levelbuf[10];  // buffer
   int countlen=0;   // counter for received bytes

   do
 {
     Serial.println("DATA?"); 
     countlen=dra_serial.readBytesUntil('\n',levelbuf,9);
   } while(countlen==0);    // ask until answer is received
   levelbuf[countlen-1]=0;  // remove cr character
   levelbuf[countlen]=0; // remove last byte & end string

   lcd.setCursor(8, 0);
   lcd.print("        ");
   lcd.setCursor(0, 0);
   lcd.print(levelbuf);
}

Salut
Recherche simplement le caractère '=' avec strchr().
Ajoute +1 au pointeur et utilise sscanf pour convertir en entier.

@+

Si tu as un tableau de char

char levelbuf[10];

qui contient une chaîne de caractères
par exemple

char levelbuf[10]="DATA=123";

levelbuf[5] pointe sur le premier chiffre du résultat. Ou bien tu utilises la méthode proposée par hbachetti qui est plus souple.

Le C dispose d'une fonction atoi() qui permet de retourner le nombre codé dans une chaîne de caractères.

int mon_nombre;
char levelbuf[10]="DATA=123";
char *ptr_nombre;

ptr_nombre = &levelbuf[5]; // on pointe sur le premier digit
mon_nombre = atoi(ptr_nombre);

ou plus court

int mon_nombre;
char levelbuf[10]="DATA=123";
mon_nombre = atoi(&levelbuf[5]);

ATTENTION, atoi() retourne 0 si la chaîne n'est pas interprétable.

hbachetti:
Recherche simplement le caractère '=' avec strchr().
Ajoute +1 au pointeur et utilise sscanf pour convertir en entier.

Même si ça fonctionne, dans l'absolu il vaut mieux éviter sscanf() ça ajoute massivement à la taille de votre binaire

si vous regardez ce programme

char message[] = "DATA=123\r\n";

void setup() {
  int valeur;
  Serial.begin(115200);
  sscanf(message, "DATA=%d", &valeur); // http://www.cplusplus.com/reference/cstdio/sscanf/
  Serial.println(valeur);
}

void loop() {}

la compilation (sur un UNO ici) dira

Sketch uses 3562 bytes (11%) of program storage space

Si vous faites par contre

char message[] = "DATA=123\r\n";

void setup() {
  int valeur;
  Serial.begin(115200);
  valeur = atoi(message + 5); // http://www.cplusplus.com/reference/cstdlib/atoi/?kw=atoi
  Serial.println(valeur);
}

void loop() {}

la compilation (sur un UNO ici) dira

Sketch uses 1822 bytes (5%) of program storage space

--> l'usage de sscanf() vous coûte 1740 octets de mémoire programme.

bien sûr il faut traiter les erreurs, ce que je n'ai pas fait dans les exemples ci dessus. comme ici les données sont simples, un petit travail manuel permet de traiter cela et on gagne encore en mémoire:

char message[] = "DATA=123\r\n";

boolean lireData(int &data)
{
  boolean erreur = true;
  size_t i = 0;
  while ((message[i] != '\0') && (message[i] != '=')) i++; // on cherche le '='
  if (message[i] == '=') { // si on l'a trouvé
    i++; // on passe au caractère suivant
    if ((message[i] >= '0') && (message[i] <= '9')) { // si c'est bien un chiffre
      data = 0; // on initialise notre valeur
      erreur = false; // on sait que la lecture retournera au moins queqlue chose de correct
      while ((message[i] != '\0') && (message[i] >= '0') && (message[i] <= '9')) {
        data = data * 10 + (message[i++] - '0'); // on construit notre entier
      }
    }
  }
  return erreur;
}

void setup() {
  int valeur = 0;
  Serial.begin(115200);
  if (!lireData(valeur)) Serial.println(valeur);
}

void loop() {}

donc ici non seulement on teste si le format est correct mais on a encore gratté un peu de mémoire (44 octets ! :-)) , la compilation (sur un UNO ici) dira

Sketch uses 1778 bytes (5%) of program storage space.

Si tu maîtrises aussi l'envoi des données et leur format, tu peux t'arranger pour que les valeurs commencent toujours au même indice. Par exemple avoir :

DATA   = 123
LONGIT = 12.54789
LATITU = -56.36852
TIME   = 12.4563

Ici c'est l'indice 9 qui marque le début des données chiffrées.

sujet résolu, merci a vous

j'ai retenu la solution de fdufnews