Convertir un String en byte[]

Bonjour @ tous :slight_smile:

Mon père m'a fait découvrir l'univers Arduino et maintenant, étant en terminale SI, je dois mener à bien un projet.
Dans le cadre de ce projet, j'utilise une carte arduino UNO et une carte Mega.
Elles communiquent entre elles par RF (module NRF24L01).
http://playground.arduino.cc/InterfacingWithHardware/Nrf24L01

Mon problème est le suivant... J'ai besoin de pouvoir transférer des chaînes de caractères entre les 2 cartes.
Je cherche donc à convertir un String en byte[] sur une carte et inversement sur l'autre...
J'ai trouvé cette fonction getBytes (getBytes() - Arduino Reference) qui permet de transformer la String en byte[].
Cependant, je ne sais pas du tout comment m'y prendre pour faire l'inverse...

Pourriez-vous m'aider ? :slight_smile:

Merci d'avance

Aie aie les String ... Pas bien !! J'en ai jamais eu besoin alors pas de raison que toi si :wink:

Poste ton code on va arranger ça .)

Pour avoir beaucoup galéré sur un projet "un peu" semblable, j'ai finalement réussi à m'en sortir avec parse (parseint dans mon cas, parsebyte dans le tien ?).
Pour faire l'inverse, peut-être créer une string qui ajoute byte + ","+byte etc...

Bonne continuation !

Rien ne t'oblige à travailler avec des objets String.
Tu peux très bien utiliser des tableaux de char avec les fonctions strcat, strcpy pour manipuler des caractères.

Alors, effectivement, finalement, je n'utilise plus les String, mais des tableaux de char maintenant.

Et j'arrive aussi à convertir un tableau de char en byte[] par contre, lors de la fonction inverse, ça plante...

Voici mon programme :

/*************
 * Module RF *
 *************/
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

// Préfixe pour le module RF : "RF_"

#define RF_MEGA_CE    48
#define RF_MEGA_CSN   49

#define RF_UNO_CE     8
#define RF_UNO_CSN    7

#define RF_PAYLOAD    25
#define RF_CHANNEL    1

  // Adresse à pointer pour envoyer (cliente)
#define RF_MEGA    (byte *)"ICAREproject_client"
  // Adresse définie pour recevoir (serveur)
#define RF_UNO     (byte *)"ICAREproject_serveur"

/*
 * RF_msgT : Message qui sera envoyé par RF
 * RF_msgR : Message qui sera reçu par RF
 */
char RF_msgT[RF_PAYLOAD] = "";
char RF_msgR[RF_PAYLOAD] = "";

/*
 * RF_bArray : tableau d'octet pour la transmission
 */
byte RF_bArray[RF_PAYLOAD];

/**
 * Fonction permettant d'envoyer une chaîne de caractère
 * @param msg    Message à envoyer
 */
void RF_send () {
  // On converti la chaîne à envoyer en octets
  strcpy( (char *)RF_bArray, RF_msgT );
  
  Serial.println("Message transmis :\n\t" + String(RF_msgT));
  
  // On envoie
  Mirf.send( RF_bArray );
  while (Mirf.isSending()) {}
  Serial.println("\t!!Envoi terminé!!");
}


/**
 * Fonction permettant d'envoyer une chaîne de caractère
 * @return Message en cours de réception
 */
boolean RF_receive () {
  if(!Mirf.isSending() && Mirf.dataReady()) {
    Mirf.getData(RF_bArray);
    
    strcpy( RF_msgR, (char *)RF_bArray );
    Serial.println("Message recu :\n\t" + String(RF_msgR));
    return true;
  }
  else
    return false;
}


void setup() {
  /*
   * Initialisation du port série
   */
  Serial.begin(115200);
  Serial.println("Programme du projet ICARE sur Arduino Mega");
  
  /*
   * Initialisation du module RF
   */
  Mirf.cePin = RF_MEGA_CE;
  Mirf.csnPin = RF_MEGA_CSN;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  
  Mirf.channel = RF_CHANNEL;
  Mirf.payload = RF_PAYLOAD;
  Mirf.config();
  
  // La carte MEGA envoie ses données à la carte UNO
  Mirf.setTADDR( RF_UNO );
  // On définit l'adresse de la carte MEGA
  Mirf.setRADDR( RF_MEGA );
  
  Serial.println("\t- Module RF initialise");
  
  /*
   * Autre initialisations
   */
}


void loop() {
  RF_receive();
  delay(50);
}

Le programme sur la carte UNO est quasiment identique à celui-ci, sauf la fonction loop :

void loop() {
  strcpy(RF_msgT, "TEST");
  RF_send();
  delay(3000);
}

Je suppose que mon problème vient de cette ligne (dans la fonction RF_receive()) :

    strcpy( RF_msgR, (char *)RF_bArray );

Pouvez-vous m'aider ?

Merci d'avance :slight_smile:

byte et char ont la même taille (en fait byte est un typedef équivalent à char).

Pour utiliser strcpy, il faut que le tableau à copier contienne un zéro de fin de chaîne inclus dans le tableau. Est-ce le cas ?

Sinon, utilise memcpy.

Préférer la fonction strncpy qui permet de maîtriser le nombre maximum de caractères copiés pour éviter les débordements de tampon.

Je suppose que tu ne nous a montré qu'un morceau du programme parce que là les chaînes sont vides.

Effectivement, je ne vous ai montré qu'un morceau du programme. Le chaîne sont remplies évidemment ^^

Bon, alors, j'ai réussi avec les fonctions strcpy et strncpy à faire ce que je voulais faire...
Cependant, je viens de me rendre compte d'un autre problème...

Il me faut aussi pouvoir envoyer des int et des byte (j'ai un joystick qui commande un moteur dans le mode manuel du projet)...
Et donc, avec cette solution de faire avec des char[], je ne vois aps comment faire pour transmettre ces données...
Mon problème est qu'il me faut pouvoir transmettre les 2 voire 3 types de données en même temps (dans la même ligne transmise) car je dois transmettre le mode de fonctionnement et les infos de commandes en fonctions de ce mode.

Par exemple, pour le mode manuel, j'aimerai que ma trame ressemble à ceci :

M1:MA:X:G:Y

avec :

  • M1 : mode 1 (manuel)
  • MA : octet indicateur de marche avant (ou booléen, mais sachant que la librairie transfère des byte, autant mettre en byte direct, non ?)
  • X : octet de vitesse moteur
  • G : octet indicateur pour tourner à gauche (ou booléen)
  • Y : octet de vitesse de rotation

Voici mes fonctions de transmissions :

/*
 * RF_msgT : Message qui sera envoyé par RF
 * RF_msgR : Message qui sera reçu par RF
 */
char RF_msgT[RF_PAYLOAD] = "";
char RF_msgR[RF_PAYLOAD] = "";

/*
 * RF_bArray : tableau d'octet pour la transmission
 */
byte RF_bArray[RF_PAYLOAD];


/**
 * Fonction permettant d'envoyer une chaîne de caractère
 * @param msg    Message à envoyer
 */
void RF_send () {
  // On converti la chaîne à envoyer en octets
  strcpy( (char *)RF_bArray, RF_msgT );
  
  Serial.println("\nMessage en cours de transmission :\n\t" + String(RF_msgT));
  
  // On envoie
  Mirf.send( RF_bArray );
  while (Mirf.isSending());
  Serial.println("\t!!Envoi termine!!");
}


/**
 * Fonction permettant d'envoyer une chaîne de caractère
 * @return Message en cours de réception
 */
boolean RF_receive () {
  if(!Mirf.isSending() && Mirf.dataReady()) {
    Mirf.getData(RF_bArray);
    
    strcpy( RF_msgR, (char *)RF_bArray );
    Serial.println("\nMessage recu :\n\t" + String(RF_msgR));
    return true;
  }
  else
    return false;
}

Je ne vois pas du tout comment faire...
Quels conseils pourriez-vous me donner ?

Merci d'avance

PS : La trame que j'ai proposé ci-dessous n'est pas vraiment optimisée et je vais sûrement envoyer la vitesse de rotation du moteur gauche et la vitesse du moteur droite ainsi que leur sens de rotation.

Edit : J'ai trouvé la fonction :

char *  itoa ( int value, char * str, int base );

Je pense qu'elle peut m'être utile, mais je ne vois pas comment l'utiliser, mis à part en concaténant des tableaux de char et je pense qu'il y a plus optimisé et plus simple...

Finalement, voici la solution que j'adopte pour l'instant pour constituer ma chaîne de caractères.

  char work[sizeof(int)];
  strcpy(RF_msgT, "M1:");
  
  itoa(JOY_MA, work, 10);
  strcat(RF_msgT, work);
  strcat(RF_msgT, ":");
  
  itoa(JOY_x, work, 10);
  strcat(RF_msgT, work);
  strcat(RF_msgT, ":");
  
  itoa(JOY_gauche, work, 10);
  strcat(RF_msgT, work);
  strcat(RF_msgT, ":");
  
  itoa(JOY_y, work, 10);
  strcat(RF_msgT, work);
  RF_send();
  delay(100);

Qu'en pensez-vous ?
Merci d'avance et bonne soirée