ENVOIE TRAME DE DONNEES

Bonjour,

J'explique mon projet :

j'ai une trame de données provenant d'un pic dont je fais l'acquisition sur arduino et que j'aimerais envoyer sur labview.

Sur l'arduino, je veux faire l'acquisition de cette trame (23octets) et la renvoyer à LabVEW en représentation HEX. Pour ce faire j'ai le code suivant, mais j'ai deux problèmes : Lorsque j'affiche ma trame en HEX j'ai des zéros qui n'apparaissent pas, j'ai alors essayé une ligne de code qui devait me permettre de les rajouter mais celle ci rajoute des octets dans ma tram.
L'autre problème c'est que j'affiche bien ma tram dans le serial monitor de l'arduino IDE mais impossible de lire quelque chose sous LabVEW.

#include <SoftwareSerial.h>

SoftwareSerial mySerial (5, 6);

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
  mySerial.begin(1200);
   
}
void loop() {
  static byte buffer[23];
 
  if (mySerial.available() > 0)
  {
    byte octet=mySerial.read();
   
    //Serial.print(octet, HEX);
    if (octet==0x13)
    {
      buffer[0] = 0x13;  // range le premier octet
      
      byte nbOctets = mySerial.readBytes(buffer + 1, sizeof buffer - 1); // lit les 23 octets suivants

      for (int i = 0; i < nbOctets+1; i++) {
        // if (i < 0x16) Serial.print('0');// Fonctionne pas ou mal nombre d'octets =25 au lieu de 23
       Serial.print(buffer[i], HEX);
       Serial.print(" ");
        
      }
       Serial.print("\n");
      

    }
  }
}

Pour la trame elle doit etre :130A2C013206A700060248000A0B513D0100215FDA7FFF

Merci par avance de votre aide

Bonjour,
Ce n'est pas

if (i < 0x16) Serial.print('0');

mais

if (i < 0x10) Serial.print('0');

qu'il faut faire

J'ai choisi d'utiliser un format %02x de c, plutôt que les contorsions (imaginez que vous ayez des mots de 32 bits à convertir, avec les zeros qu'il faut, en hexa) d'arduino

#include <stdio.h>
#include <stdint.h>

unsigned char
trame[] = {0x13, 0x0A, 0x2C, 0x01, 0x32, 0x06, 0xA7, 0x00, 0x06, 0x02, 0x48,
  0x00, 0x0A, 0x0B, 0x51, 0x3D, 0x01, 0x00, 0x21, 0x5F, 0xDA, 0x7F, 0xFF};

int main() {
  char tampon[7]; // un peu sur dimensionné
  uint8_t i;
  for (i = 0; i <  sizeof(trame); i++) {
     snprintf(tampon,6,  "%02x", trame[i]);/ // format hexa sur 2 chiffres, avec si besoin un zero devant
     printf("%s", tampon); // specifique au PC; sur Arduino, faudra mettre Serial.print(tampon);
  }
  printf("\n"); // devient Serial.println sur arduino
  return 0;
}

qui me sort

 gcc trame.c && ./a.exe
130a2c013206a700060248000a0b513d0100215fda7fff

Edit : la solution de Kamil est plus jolie.. si vous n'avez pas des mots de 64 bits.

Merci pour vos réponses.

J'ai essayé les deux formules mais je n'obtiens pas ma trame.
Pour la dernière solutions je ne peux pas faire cette solution car les valeurs de la trame varient au cours du temps. il y a que le carac de début "0x13" de fixe et le carac de fin "0xFF"

Je suppose, mais ton explication n'est pas claire, que tu veux ajouter un 0 en tête des code ASCII inférieurs à 0x10.

Ton code

      for (int i = 0; i < nbOctets+1; i++) {
        // if (i < 0x16) Serial.print('0');// Fonctionne pas ou mal nombre d'octets =25 au lieu de 23
       Serial.print(buffer[i], HEX);
       Serial.print(" ");
        
      }

Tu fais le test sur i, mais c'est sur la valeur dans buffer qu'il faut faire ce test

      for (int i = 0; i < nbOctets+1; i++) {
         if (buffer[i] < 0x10) Serial.print('0');
       Serial.print(buffer[i], HEX);
       Serial.print(" ");
        
      }

"Pour la dernière solutions je ne peux pas faire cette solution car les valeurs de la trame varient au cours du temps"

Normal: je l'ai testée sur un PC et la partie utile (creer un petit buffer de 7 caractères;
employer un format standard de c %02X ou %02x pour encoder en hexa -MAJUSCULE ou minuscule la trame (qui correspond à buffer chez vous; je trouve que "trame" est moins ...generique
l'imprimer avec print (sur PC) ou serial.print) doit être extraite. Ce principe (passer par les utilitaires standard de C pour contourner les fantaisies de formatage d'arduino sans tester les puissances de 10 ou 16....) est lourd, mais assez general.

Merci pour vos réponses j'arrive à recevoir ma trame correctement ! :smiley: :smiley:
Par contre maintenant j'aimerais l'envoyer toutes les x ms sur le logiciel LabVIEW. La fonction serial write est-elle la bonne solution ?

Qu'attend LABVIEW?
des caractères ASCII? du binaire? autre?

A-t-il une fonction de débugging (crier/ faire rougir une LED s'il reçoit des chaînes abominables) ?

(désolé, mais il est peut être un peu difficile de pifomètrer les formats d'interface de tous les logiciels possibles et imaginables: c'est vous l'expert -au moins pour trouver / fournir un lien exploitable...-)

Du côté de Labview je veux recevoir ma trame en représentation Hexa. Apres je peux en faire ce que je veux.
Labview me permet de lire le port série de l'arduino et ensuite j'en ferais le traitement.
Labview est un logiciel de programmation graphique. Je renseigne les parametres de la liaison série (debits, bit de stop..) et je fais l'acquisition de la trame. Mais je n'arrive plus a recevoir la trame.

Du côté de Labview je veux recevoir ma trame en représentation Hexa.

Certes, mais qu'est ce que Labview veut?

du binaire? (arduino fait des serial.write)
des représentations hexa? (arduino fait des serial.print)
autre?

LoicFondasol:
Merci pour vos réponses j'arrive à recevoir ma trame correctement ! :smiley: :smiley:

Suite à quelle modification?

LoicFondasol:
Par contre maintenant j'aimerais l'envoyer toutes les x ms sur le logiciel LabVIEW.
La fonction serial write est-elle la bonne solution ?

Ta question manque de clarté.
La question porte sur envoyer toutes les x ms ou sur un problème de format serial write est-elle la bonne solution

Dans un premier temps j'aimerais bien envoyer ma trame à labview donc est ce que c'est avec serial write ou une autre fonction. Sachant qu'avec serial print je n'ai rien.
Une fois ce problème résolu c'est de l'envoyer toutes les x périodes. C'est avec LabVIEW que j'effectuerais tous le traitement de la trame.

Est ce que labview a une documentation consultable? (ou se sont ils limités, comme il y a 40 ans, à des manuels papier confidentiels?)
Parce que c'est une façon de savoir ce que labview accepte via la jonction serie....

Maintenant on trouve beaucoup de documentation sur internet.

http://tpil.projet.free.fr/TP_Labview/Labview_VISA_serie.html

Ce lien qui explique un peu la communication entre labview et un arduino. Normalement c'est assez simple mais je pense que le format buffer[] n'est pas pris en compte et qu'il faudrait créer un string ou autre avec un format définis. Mais je ne sais pas comment faire

Bon:
si j'ai bien compris, labview accepte, si la vitesse de transmission est bien définie, des formats du type
, , .. \n
càd des lignes ASCII -csv-, se terminant par \n (et seulement par \n) du type
63,558,2

il faudrait créer un string ou autre avec un format définis

Mais qui va définir le format (on ne sait pas
a) ce que sort le pic (des chaines de bits sans queue ni tête? arduino peut très bien les décoder et leur donner un sens éventuel),
b) ce que vous voulez en faire,
c) comment/si vous avez relié votre arduino au PC supportant labview,
d) si vous avez fait des essais simples)?

C'est ca labview peut communiquer une fois que la vitesse et le port com sont identifier.
L'arduino est relié par câble à l'ordinateur pour le moment, mais je dispose d'un module bluetooth que je voudrais utiliser par la suite mais je verrais plus tard.

Ce que je veux c'est envoyer ma trame en hexa à LabVIEW.

Ce qui arrive sur l'arduino est une suite de bits à 1200 bauds. Avec l'arduino je veux faire l'acquisition de la trame et la renvoyer sur LabVIEW, tous le traitement s'effectuera sur LabVIEW.

Il faut être clair hexa c'est un mode de représentation des données.
Tu communiques par une liaison série asynchrone de type UART.
Sur une liaison de ce type, les données sont émises sur 8 bits + des bits de protocole.
Les 8 bits en question peuvent représenter n'importe quoi.
Si tu envoies des chaines de caractères, le plus souvent, tu les encodes en utilisant le code ASCII. C'est ce que fait print().
Si tu envoies des données brutes sans aucun encodage tu utilises write().

Tu peux donc très bien envoyer de l'hexa sous forme de chaine de caractères avec print()
33 2F AD ......
un octet de donnée sera envoyé sur 2 caractères ASCII plus éventuellement un séparateur (ici un espace mais ce pourrait être une virgule ou n'importe quel caractère de ton choix, voir aucun séparateur).
ou tu peux envoyer de l'hexa avec write() dans ce cas l'octet de donnée est placé dans le registre de l'UART et émis directement.

Les données envoyées par print() sont affichables directement dans un terminal puisque c'est en fait du texte
Les données envoyées par write() ne sont pas affichables directement.