[RESOLUT] lecture caracteres liaison série et action

Bonsoir à tous, je sais qu'on a mainte et mainte fois abordé ce sujet mais comme étant novice, je tente quand même :wink:

Explication : sur la liaison série, je recoit d'un capteur toutes les 10s environ, la chaine suivante "R470", le "R" est le nom du capteur et le "470" la valeur qu'il mesure qui varie de 000 à 999.
Note : la fin de la phrase est ponctuée par "un retour chariot LF (Line Feed)" (10 en décimal)

Ce qu'on doit faire : la détection du "R" en début de phrase doit "ranger" la mesure "470" dans une étiquette qu'on va appeller "redox"

Voili voilou ! tres simple !

voici le code qui me permet d'afficher sur le moniteur série "R470"

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

void loop()
{
    char carlu = 0; //variable contenant le caractère à lire
    int cardispo = 0; //variable contenant le nombre de caractère disponibles dans le buffer
    
    cardispo = Serial.available();
    
    while(cardispo > 0) //tant qu'il y a des caractères à lire
    {
        carlu = Serial.read(); //on lit le caractère
        Serial.print(carlu); //puis on le renvoi à l’expéditeur tel quel
        cardispo = Serial.available(); //on relit le nombre de caractères dispo
    }
    //fin du programme
}

MErci pour vos retour !!!

bonjour,
fonction substring ou strok de mémoire

Allez lire et comprendre ( si vous lisez l'anglais) http://forum.arduino.cc/index.php?topic=396450

Ouch ! Merci je vais essayer de digérer tout ça :wink:

Un code qui devrait marcher :

  if (Serial.available()) {

if(Serial.read() == 'R')

    char buffer[10];
    int i = 0;
    byte newMessage = 0;

    memset(buffer, NULL, sizeof(buffer));

    unsigned long start = millis();

    do {

      if (Serial.available()) {
        
        char c = Serial.read();
        
        if (c == '\n') {
          newMessage =1;
          break;
        }
        
        buffer[i++] = c;
        
      }

    }  while ((millis() < start + 20) && i<sizeof(buffer));

    if (newMessage) {

int maValeur = atoi(buffer);

    } 

    }

  }

Grosso modo :

Si des données sont dispo, on lit le premier caractère. Si c’est un R on passe à la suite. On réceptionne tout ce qui est derrière jusqu’à détecter un caractère LF ou bien avec un timeout (ça évite de rester bloquer indéfinimment. Ensuite on convertir ce qu’on a reçu (logiquement 470) en “vrai” valeur numérique avec atoi().

Impecc ça marche nickel avec qq petites modif :

char buffer[10];
int i = 0;
byte newMessage = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
}

void loop() {
  if (Serial.available()) {
    if (Serial.read() == 'R')
      i = 0;
      newMessage = 0;
    memset(buffer, NULL, sizeof(buffer));
    unsigned long start = millis();
    do {
      if (Serial.available()) {
        char c = Serial.read();
        if (c == '\n') {
          newMessage = 1;
          break;
        }
        buffer[i++] = c;
      }
    }  while ((millis() < start + 20) && i < sizeof(buffer));
    if (newMessage) {
      int redox = atoi(buffer);
      Serial.print("redox = ");    // new for this version
      Serial.print(redox);   Serial.println("mv");    // new for this version
    }
  }
}

Si je laisse la declaration des variables dans le code il me dit qu’elles ne sont pas déclarées du coup je les ai ajoutée avant mon SETUP

MERCIIIII B@too !!!

Sinon j’avais quand même bossé le lien de J-M-L qui m’a fait un petit peu progresser :slight_smile:

const byte numChars = 10;
char receivedChars[numChars]; // déclaration de tableau de taille 10 byte "R470"
// 5 ok , 4 marche pas !!??
boolean newData = false;
char capteur = 0;             // quel est le capteur qui emet ?
int redox = 0;             // nombre converti de "R470"
int c = 0;                      // centaines
int d = 0;                      // dixaines
int u = 0;                      //unites

void setup() {
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
}

void loop() {
  recvWithStartEndMarkers();
  showNewNumber();
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void showNewNumber() {

  if (newData == true ) {
    redox = 0;             // new for this version
    Serial.print("Reception ASCII ... ");
    Serial.println(receivedChars);
    capteur = receivedChars [0];  // capteur ? "R" =52
    c = receivedChars [1];  // aff 52 pour "4"
    d = receivedChars [2];  // aff 55 pour "7"
    u = receivedChars [3];  // aff 48 pour "0"
    c = c - 48; d = d - 48; u = u - 48; // converti Hex(ascii) => nombre
    if (c <= 9 && c >= 0 && d <= 9 && d >= 0 && u <= 9 && u >= 0 ) { // FILTRE parasite NIV2
      if (capteur == 'R') {                  // on recoit du REDOX ?
        redox = c * 100 + d * 10 + u ; // converti 4 + 7 + 0 en 470
        Serial.print("redox = ");    // new for this version
        Serial.print(redox);   Serial.println("mv");    // new for this version
      }
    }
    newData = false;
    Serial.println("Wait ... ");    // new for this version

  }
}

J’ai le choix now …Cool !

Bravo!

Dans le second code

    c = receivedChars [1];  // aff 52 pour "4"
    d = receivedChars [2];  // aff 55 pour "7"
    u = receivedChars [3];  // aff 48 pour "0"
    c = c - 48; d = d - 48; u = u - 48; // converti Hex(ascii) => nombre

Généralement on code ça plutôt comme cela pour la lisibilité

    c = receivedChars [1] - '0';  // aff 52 pour '4' -> converti Hex(ascii) => nombre
    d = receivedChars [2] - '0';  // aff 55 pour '7'-> converti Hex(ascii) => nombre
    u = receivedChars [3] - '0';  // aff 48 pour '0'-> converti Hex(ascii) => nombre

Merci J-M-L je prends :wink: