[Résolu]Liaison série

Bonjour à tous,
Débutant dans le langage Arduino et le le langage informatique, je recherche des infos depuis quelques temps sur la réception de trame série et là je bug. J’ai bien trouvé quelques projets un peu ressemblant au mien mais sans succes d’adaptation , merci donc de votre indulgence si je suis passé à coté d’un topic.

Mon projet:
Carte UNO en liaison avec un appareil équipé d’un port série.
Liaison série via XBEE série 1.
J’ai identifié les trames de requettes et de réponses. Elles sont du style 0x01, 0x2F, 0x3F, 0x5F, 0x2E (longueur tjrs identique)
J’arrive à envoyer un ordre:

const char statut[6]= {0x0F, 0x01, 0xF1, 0x0F, 0x01};// La trame depart
void setup() {
Serial.begin(9600); // ouvre le port série et règle le debit à 9600 bps
}
void loop() {
if (Serial.available() > 0) {
Serial.write(statut);
delay(2000);

Mon probleme est dans la réception de la trame, je m’y perd, je souhaiterais simplement envoyer ma trame de requette et lire le buffer et le comparer sans traitement pour le moment.
EX:
on envoie {0x0F, 0x01, 0xF1, 0x0F, 0x01};

on lit le buffer et
si buffer={0x0F, 0x01, 0xF1, 0x0F, 0x03}
//je fais une action
si buffer ={0x0F, 0x01, 0xF1, 0x0F, 0x0C}
//je fais une autre action

voilà, désolé si c’est une question idiote mais là je sèche.
Merci d’avance.
Sébastien.

Bon voila je me lance, un petit programme qui ne marche pas... le but serait de tester la réception et la lecture d'une trame.
Si Arduino reçoit 0x40, 0x11, 0x01, 0x0F, 0x01 on envoi 0x2F et on allume la led
en 12 pendant 1s
Si Arduino reçoit 0x40, 0x11, 0x01, 0x0F, 0x01 on envoi 0x3F et on allume la led
en 11 pendant 1s
Si arduino reçoit 5 Hexa autre on renvoit 0x00, y'a que ça qui marche....

const char instart[6] = {
0x40, 0x11, 0x01, 0x0F, 0x01};
const char instop[5] = {
0x40, 0x11, 0x01, 0x0F, 0x02};
const int ledPin12 = 12;
const int ledPin11 = 11;

void setup() {
Serial.begin(9600);
}

void loop() {

if(Serial.available() >= 5) {

char buffer[5];
Serial.readBytes(buffer, 5);
if(memcpy(buffer, instart, 5) == 0) {
Serial.write(0x2F);// si en start on renvoi 2F
digitalWrite(ledPin12, HIGH);//led 12 allumée
delay(1000);
digitalWrite(ledPin12, LOW);//led 12 éteinte

}
if(memcpy(buffer, instop, 5) == 0) {
Serial.write(0x3F);// si en stop
digitalWrite(ledPin11, HIGH);//led 11 allumée
delay(1000);
digitalWrite(ledPin11, LOW);//led 11 éteinte
}
else
{
Serial.write(0x00);
}

}
}

Salut et bienvenue :slight_smile:

Tu devrais essayer la fonction memcmp (comparaison) au lieu de memcpy (copie) :slight_smile:

Et aussi tu dois utiliser une structure if, else if, else.

if (memcmp ...
{
}
else if (memcmp ...
{
}
else
{
}

Super, merci ça tourne nickel reste plus qu'a l'adapté à mon projet.
Le code qui fonctionne si ça intéresse quelqu'un...

const char instart[6] = {
  0x40, 0x11, 0x01, 0x0F, 0x01};
const char instop[5] = {
  0x40, 0x11, 0x01, 0x0F, 0x02};
const int ledPin12 =  12;
const int ledPin11 =  11;

void setup() {
  Serial.begin(9600);
}

void loop() {


  if(Serial.available() >= 5) {

    char buffer[5];
    Serial.readBytes(buffer, 5);
    if(memcmp(buffer, instart, 5) == 0) {
      Serial.write(0x2F);// si en start on renvoi 2F
      digitalWrite(ledPin12, HIGH);//led 12 allumée
      delay(1000);
      digitalWrite(ledPin12, LOW);//led 12 éteinte

    }
    else if (memcmp(buffer, instop, 5) == 0) {
      Serial.write(0x3F);// si en stop
      digitalWrite(ledPin11, HIGH);//led 11 allumée
      delay(1000);
      digitalWrite(ledPin11, LOW);//led 11 éteinte
    }
    else
    {
      Serial.write(0x00);
    }

  }
}

Une autre petite question, si c’est pas trop compliqué à réaliser:
Je reçois donc des trames Hexa, une des trames correspond à un chargement de batterie:
la trame:
0F 2E F4 01 51
0F 2E F4 sont fixes indique une trame “chargement”
01 51: correspondent a la tension 20737 soit 5101 en HEXA

est t’il possible de convertir la trame reçue dans une variable pour pouvoir la comparer à une valeur.
Peut etre serait il plus simple dans un premier temps d’extraire uniquement le dernier soit dans l’exemple le 51?
Le but étant de lancer une action avant la fin du chargement de la batterie, j’ai pas non plus besoin d’être super précis.
Si quelqu’un à une solution je suis preneur.

Si la valeur à convertir est dans un tableau de byte, il suffit de mettre les valeurs dans un unsigned int
si par exemple index pointe le premier élément de la valeur il faut écrire comme ça

unsigned int batterie;

     batterie = buffer[index] + buffer[index+1]<<8;

dans le cas de l’exemple que tu donnes buffer contient 01 51 et index pointe sur 01
batterie = 0x01 + 0x51* 256 = 0x5101

Désolé de ne pas avoir répondu mais livebox Hs (orage) et 3G tres lente chez moi.
Je comprend pas trop la ligne de code précédente.
Ce s

if(Serial.available() >= 5)
{ char buffer[5];
Serial.readBytes(buffer, 5);

Si on prends buffer:
0F 2E F4 01 51
Pour recupérer la valeur 0x5101
unsigned int batterie;
batterie = buffer[4] + buffer[5]<<8;

C est ça? Je comprends pas trop surtout le 8.

unsigned int batterie;  

batterie = (int)buffer[4] + (int)buffer[5]<<8;




C est ça? Je comprends pas trop surtout le 8.

<< c’est l’opérateur de décalage à gauche. Donc, en faisant buffer[5]<<8 on décale buffer[5] de 8 bits vers la gauche (ce qui est équivalent à une multiplication par 256 mais c’est plus rapide).

Maintenant l’index des tableaux commençant à 0 en C. Si on prend l’exemple que tu donnes :
0F 2E F4 01 51
il vaudrait mieux écrire

batterie = (int)buffer[3] + (int)buffer[4]<<8;

Edit: j’ai ajouté un cast en int devant buffer car c’est un tableau de char et on perdrait l’octet de poids fort dans le décalage.

ça tourne nickel,
merci merci merci.

En faite ça marche mais j’ai fait une petite modif (trouvé tout seul :))

 bat= (int)buffer2[4]<<8;
      bat= (int)buffer2[3] + bat;

en deux lignes, sinon les deux bites sont x256.