Simulateur de capteur, envoie de trame de données sur liaison série

on ne voit plus de 0x95 suivi du 0x55 mais que des 0x95 0xD5

0x95,0xD5,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xD5,0xFF,0xFF,0xFF,0xD7,0x61
0x95,0xD5,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xDF,0xD5,0xFF,0xFB,0xD1,0x8D
0x95,0xD5,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAB,0x91,0xFF,0xF9,0xFF,0xDD
0x95,0xD5,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x0D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0xBF,0xFF,0xF9,0x27,0x36
0x95,0xD5,0xDF,0xFD,0x0B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xD5,0xFF,0xFF,0xFF,0xD7,0x53,0x00
0x95,0xD5,0xDF,0xFD,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xDF,0xD5,0xFF,0xFB,0xD1,0x81,0x00
0x95,0xD5,0xFF,0xFD,0x05,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAB,0x91,0xFF,0xF9,0xFF,0xD7,0x00
0x95,0xD5,0xFF,0xFD,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xED,0xFD,0x6B,0x0B,0x72
0x95,0xD5,0xEF,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xF9,0xCF,0xD7,0x9F,0xD1,0x00
0x95,0xD5,0xFF,0xFF,0xFF,0xFF,0xAB,0x91,0xFF,0xF9,0xFF,0xE1
0x95,0xD5,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xED,0xFD,0x6B,0x0B,0x06
0x95,0xD5,0xEF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xF5,0xD1,0xD7,0x81,0xF3
0x95,0xD5,0xEF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF5,0x0D,0x5D,0x3B
0x95,0xD5,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0xFB,0x00
0x95,0x05
0x95,0xD5,0xDF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xD5,0xFF,0xFF,0xFF,0xD7,0x75
0x95,0xD5,0xDF,0xFF,0xE1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xDF,0xD5,0xFF,0xFB,0xD1,0xA7
0x95,0xD5,0xFF,0xFF,0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAB,0x91,0xFF,0xF9,0xFF,0xFF
0x95,0xD5,0xFF,0xFF,0xD3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xED,0xFD,0x6B,0x0B,0x0F
0x95,0xD5,0xEF,0xFF,0xCD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xD1,0xCF,0xD7,0x7F,0x49

➜ avez vous changé quelque chose ?

si il du highByte, lowByte perdu au milieu de tout ca et que je n'ai pas la bonne trame c'est mort ?

Autre solution, créer une fonction pour enregistrer ce qui sort de mon capteur ( je fait varier les valeurs pendant l'acquisition) et ensuite je rebalance en boucle mon enregistrement.
Il me faudrait 15-20 seconde d'enregistrement .... en terme de place, je sais pas...

c'est un peu moins évolué que ce que je voulais faire initialement mais ca pourrais faire le boulot.

Après c'est peut être plus simple à dire qu'a faire.

A priori ca dépend,

Le 95 ou D5, correspond peut être à un état du capteur, que j'ai fait varier pendant l'acquisition

0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x01 0x00 0x00 0x00 
0xFB 0x00 0x95 0x55 0xFB 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x01 0x00 0x00 0x00 
0xFD 0x00 0x95 0xD5 0xFB 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x01 0x00 0x00 0x00 
0xFF 0x00 0x95 0x55 0xFB 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xFF 0x01 0x74 0xFF 0xF9 0x27 
0x02 0x95 0xD5 0xDF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xFB 0xD5 0xFF 0xFF 0xFF 0xD7 
0x61 0x95 0x55 0xDF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xFB 0xDF 0xD5 0xFF 0xFB 0xD1 
0x8D 0x95 0xD5 0xFB 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xAB 0x91 0xFF 0xF9 0xFF 0xDD 
0x95 0x55 0xFB 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
0xFF 0xFF 0xFF 0xFF 0xDD 0xED 0xFD 0x6B 0x0B 0x06 
0x95 0xD5 0x6F 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 

mis en forme en enlevant les trames (supposées) non complètes ça donne cela

0x95,0x55,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0xFD,0x00
0x95,0xD5,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0xFF,0x00
0x95,0x55,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x74,0xFF,0xF9,0x27,0x02
0x95,0xD5,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xD5,0xFF,0xFF,0xFF,0xD7,0x61
0x95,0x55,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xDF,0xD5,0xFF,0xFB,0xD1,0x8D
0x95,0xD5,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAB,0x91,0xFF,0xF9,0xFF,0xDD
0x95,0x55,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xED,0xFD,0x6B,0x0B,0x06

les 55 alternent avec les D5

qu'est-ce que vous "touchez" pour obtenir cette alternance?

les trames ne sont pas non plus de taille fixe..

faudrait trouver la vraie doc de votre capteur (à commencer par l'info sur la liaison série : débit en bauds, stop bits , parité etc...)

sinon un peu avant vous nous aviez dit

cette trame vient d'où ? les flags semblent être AA 55...

le CHK byte ne semble correspondre à rien de connu non plus si on ne prend que les octets listés en excluant ou pas les 2 flags...

sans la spec que vous ne pouvez pas partager, difficile de vous aider....

C'est un exemple de trame fournit par le document destinée aux integrateurs.
Mais comme a premières vu ils personalisent la trame a la demande du client [distributeur du capteur en question ] difficile de s'y retrouver.
Ca m'embête de partager un document floqué confidentiel sur un forum.
Et a priori on ne peut pas vous l'envoyer en direct.

Il faudrait que tu fasse tourner un peu l'acquisition en faisant varier les valeurs de ton capteurs, pour essayer de pouvoir repérer des éléments clés.
par exemple le 95 55 et 95 D5 semple un point clé.

Au vu de ta documentation, il y a le ID qui doit tourner entre 00 et 09.
Il faudrait chercher des trucs comme cela.

L'autre solution, c'est d'envoyer cette trame, vérifier que le récepteur crois bien que c'est une sonde valide.
Puis dans un second temps, changer certaine valeur, pouvoir comment le récepteur réagit.

est-ce qu'ils décrivent précisément le calcul du check sum?

Oui c'est ce que je voulais faire, mais y'a un truc qui me perturbe, pas d'indicateur lumineux quand l'arduino envoi de la data via
#include <SoftwareSerial.h> SoftwareSerial RS232(5, 6);

du coup j'ai un doute ?

voila le code :

#include <SoftwareSerial.h>
SoftwareSerial RS232(5, 6);  // RX, TX
unsigned char id = 0;        // doit vaier
byte sb1;                    // byte 1 a faire varier en fonction de l'id


void setup() {
  Serial.begin(9600);
  RS232.begin(9600);  //9600 selon doc
}
void loop() {
  byte tamp = 0;  // remetre tamp à 0
  byte sum = 0;   // pour le calcul du check sum uniquement pour la vérification
  ++id %= 2;
  byte CB2;
  static uint32_t n = 0;


  switch (id) {

    case 0:
      CB2 = 0x55;
      break;
    case 1:
      CB2 = 0xD5;
      break;
  }

  unsigned char frame[20];
  frame[0] = 0x95; /* Start flag 1 */
  frame[1] = CB2;  //Start flag 2 // variable
  frame[2] = 0xFB;
  frame[3] = 0xFF;   // STS byte 0 no breath 1 Breath restera fixe
  frame[4] = 0xFF;   // >> 8; // waveform value BIG BYTE
  frame[5] = 0xFF;   // & 0xFF;// waveform value 5 LOW BYTE
  frame[6] = 0xFF;   // waveform value BIG BYTE
  frame[7] = 0xFF;   // waveform value 5 LOW BYTE
  frame[8] = 0xFF;   // waveform value BIG BYTE
  frame[9] = 0xFF;   // waveform value 5 LOW BYTE
  frame[10] = 0xFF;  // waveform value BIG BYTE
  frame[11] = 0xFF;  // waveform value 5 LOW BYTE
  frame[12] = 0xFF;  // waveform value BIG BYTE
  frame[13] = 0xFF;  // waveform value 5 LOW BYTE
  frame[14] = 0x01;  // slow data byte 1
  frame[15] = 0x00;  // slow data byte 2
  frame[16] = 0x00;  // slow data byte 3
  frame[17] = 0x00;  // slow data byte 4
  frame[18] = 0xFD;  // slow data byte 5

  /*byte de chck */
  for (int i = 1; i < 19; i++) {
    tamp += frame[i];
  }
  frame[19] = ~(tamp) + 1;  // inverse de la somme des bytes de la trame pour avoir chksum = 0



  /*  vérification du chksum */

  for (int i = 1; i < 20; i++) { /* Skip flag 1 and flag 2. */
    sum += frame[i];
    //Serial.println(frame[i],HEX); // pour vérifier
  }
  /* Checksum OK - use frame */
  if (!sum) {
    //Serial.println("Okk!!");  // pour vérifier
    for (int i = 0; i < 20; i++) {
      if (i > 19) {
        i = 0;
        break;
      }
      RS232.write(frame[i]);  // ecrit la trame de données sur le port série
                              // if ((n++ % 10) == 0) Serial.println();
      //Serial.print(F("0x"));
      //if (frame[i] < 0x10) Serial.write('0');
      //Serial.println(frame[i], HEX);
    }
  }
  /* Bad checksum - discard frame */
  else {
    //Serial.println("Pas bien!");  // pour vérifier
  }
  //Serial.println(id);
  //Serial.println(CB2);
  delay(50);

  //if (RS232.available()){Serial.println(RS232.read(),HEX); }
}

avec du copier coller le la trame, et juste variation 55/D5

oui j'ai utiliser le code de la doc pour "valider"ma trame :
voilà ce qu'ils mettent :
The frame checksum, CHK is calculated as the two-complement of the sum over all bytes in the
frame except the bytes FLAG1, FLAG2 and CHK (CHK = −( bytes)).
In the C-code example below, the VerifyChecksum function is used to validate a data frame
sent from the sensor:

void VerifyChecksum(void)
{
unsigned char sum; /* sum must be a byte */
int i;
sum = 0;
for (i=2; i<21; i++) { /* Skip flag 1 and flag 2. */
sum += frame[i]; /* Note, last (checksum) byte */
} /* is included:
/* sum + checksum = 0 if OK */
if ( !sum ) {
/* Checksum OK - use frame */
} else {
/* Bad checksum - discard frame */
}
}

OK

j'ai revérifié et la trame décrite dans votre image



donne bien 0x33 comme checksum en appliquant leur formule

un petit code pour tester

uint8_t trameConnue[21] = {
  0xAA,                                 // FLAG1
  0x55,                                 // FLAG2
  0x02,                                 // ID
  0x02,                                 // STS
  0x01, 0xEA,                           // WaveForm 0
  0x00, 0x00,                           // WaveForm 1
  0x00, 0x00,                           // WaveForm 2
  0x00, 0x00,                           // WaveForm 3
  0x00, 0x00,                           // WaveForm 4
  0xFF, 0x26, 0x00, 0x00, 0x03, 0xB6,   // Slow Data
  0x33                                  // CHK
};

uint8_t trameRecue[] = {0x95, 0xD5, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xD5, 0xFF, 0xFF, 0xFF, 0xD7, 0x61};
// uint8_t trameRecue[] = {0x95,0x55,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0xFD,0x00};
// uint8_t trameRecue[] = {0x95,0xD5,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0xFF,0x00};
// uint8_t trameRecue[] = {0x95,0x55,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x74,0xFF,0xF9,0x27,0x02};
// uint8_t trameRecue[] = {0x95,0xD5,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xD5,0xFF,0xFF,0xFF,0xD7,0x61};
// uint8_t trameRecue[] = {0x95,0x55,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xDF,0xD5,0xFF,0xFB,0xD1,0x8D};
// uint8_t trameRecue[] = {0x95,0xD5,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAB,0x91,0xFF,0xF9,0xFF,0xDD};
// uint8_t trameRecue[] = {0x95,0x55,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xED,0xFD,0x6B,0x0B,0x06};

// uint8_t trameRecue[] = {0x95,0x55,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0xFD,0x00};
// uint8_t trameRecue[] = {0x95,0xD5,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0xFF,0x00};
// uint8_t trameRecue[] = {0x95,0x55,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x74,0xFF,0xF9,0x27,0x02};
// uint8_t trameRecue[] = {0x95,0xD5,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xD5,0xFF,0xFF,0xFF,0xD7,0x61};
// uint8_t trameRecue[] = {0x95,0x55,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xDF,0xD5,0xFF,0xFB,0xD1,0x8D};
// uint8_t trameRecue[] = {0x95,0xD5,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAB,0x91,0xFF,0xF9,0xFF,0xDD};
// uint8_t trameRecue[] = {0x95,0x55,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xED,0xFD,0x6B,0x0B,0x06};


uint8_t cksum(const uint8_t trame[], size_t n) {
  uint8_t cksum = 0;
  for (size_t index = 0; index < n; index++) cksum += trame[index];
  return ~cksum + 1;
}

void setup() {
  uint8_t ck;
  Serial.begin(115200);

  Serial.print(F("Taille de trameConnue = ")); Serial.println(sizeof trameConnue);
  ck = cksum(trameConnue + 2, (sizeof trameConnue) - 3);
  Serial.print(F("CKSUM SANS HEADER de trameConnue = 0x")); Serial.println(ck, HEX);
  if (ck == trameConnue[(sizeof trameConnue) - 1]) Serial.println(F("le cksum est correct"));
  else Serial.println(F("le cksum est incorrect"));
  Serial.println(F("--------"));

  Serial.print(F("Taille de trameRecue = ")); Serial.println(sizeof trameRecue);
  ck = cksum(trameRecue + 2, (sizeof trameRecue) - 3);
  Serial.print(F("CKSUM SANS HEADER de trameRecue = 0x")); Serial.println(ck, HEX);
  if (ck == trameRecue[(sizeof trameRecue) - 1]) Serial.println(F("le cksum est correct"));
  else Serial.println(F("le cksum est incorrect"));
  Serial.println(F("--- FIN ---"));
}

void loop() {}

j'ai essayé avec toutes les trames que vous avez listé et le cksum n'est pas bon. êtes vous sûr qu'il est toujours activé ?

➜ il y a quelque chose qui ne fonctionne pas bien dans ce que vous recevez. cela vient soit du montage, soit du fait que vous ne suivez pas exactement la spec / configuration. êtes vous sûr des 9600 bauds en 8N1 ?

ça c'est normal.

La doc indique 2 vitesses,

J'ai essayer en 38400 au cas ou, mais je ne vois pas les flags non plus !

Transmission characteristics for the serial data to and from the sensor:
 Rate: 9600 bps normally,
38400 bps when high data frame rate has been selected.
 Format: 1 start bit, 8 data bits, no parity, 1 stop bit
 Flow control: No hardware or software handshake is used.

Il est très probable que les flags et/ou la vitesse de communication ne soient pas ceux énoncés dans la doc, j'essaie davoir linfo, mais ca peut prendre du temps...:santa:

J'ai l'impression que je ne vais pas pouvoir faire grand chose sans plus d'info

oui donc c'est du 8N1, c'est ce que fait SoftwareSerial

bon ça devrait être 9600 sauf si vous avez bidouillé...

Je ne sais pas si c'est possible, cela serait-il possible de dériver le RX sur ton récepteur sur voir les trames envoyés dans un environnement normal.
Car je crois que tu as parlé de trame de commande, le récepteur n'envois t'il pas une trame pour configurer ton capteur?

L'hote n'envoi de commande que sur demande de calibration (fonction sur le dispositif effective que si Rx capteur est branché)

L'hote detecte le capteur et recoit/affiche les données du capteur même branché sauvagement après initialisation du capteur ( alimenté en 5v par l'arduino ou L'hote et juste avec les pin Gnd et Tx du capteur ).

Bon une petite dernière pour la fin d'année, après je lâche jusqu'à avoir les "bonnes" infos.
Avec un Mega 2560 ( 4 Rx,Tx), et le bout de code suivant, je suis sensé recevoir quelque chose sur mon hôte si le rate à 9600 est le bon ? Si c'est pas le cas c'est que la vitesse n'est pas correcte ?

void setup() {
  Serial1.begin(9600);   //9600 selon doc
  Serial2.begin(9600);
}
void loop() {
  
  if (Serial1.available()) {
    Serial2.write(Serial1.read());
  }
  if (Serial2.available()) {
    Serial1.write(Serial2.read());
  } 
}

Merci pour tout en tout cas :pray:

Qu’est-ce qui est connecté sur Serial1 et Serial2?
Pour écrire sur le moniteur série c’est Serial qu’il faut utiliser

Désolé si j'ai manqué de précision, Serial1(19,18) mon capteur Co2 émetteur, Serial2( 17,16)l'hôte recepteur , l'idée cetait de faire un convertisseur série/série aucun intérêt en soit sauf pour confirmer que je m'agace pour rien.

J'ai lu qu'avec serialsoftware si l'émetteur etait trop bavard, ca pouvait poser problème, dans le doute j'ai essayer ca.

Sans succès !

Si c'est ce que l'on appel, un hack par man in the middle, c'est une bonne idée :slight_smile: