IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Lire une trame Controllino


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2016
    Messages : 4
    Points : 4
    Points
    4
    Par défaut Lire une trame Controllino
    Bonjour à tous !
    J'aurais besoin de vos petits conseils pour savoir si je suis bien partie car j'ai une petite problématique.

    Je possède un Controllino , qui est un automate programme basé sur le même IDE qu'arduino. Et je compte l'utiliser pour lire des trames en continu.
    Pour ce faire j'ai un lecteur de code qui va lire la séquence , la mettre sur un serveur et à l'aide du Controllino je vais lire cette séquence.

    Pour ce qui est de la lecture tous est bon , je l’aperçois bien sur mon moniteur Serie. Ensuite j'ai donc mis en place un système de comparaison.
    Je m'explique : Je lit ma première séquence, je retiens cette séquence et je fait une action. Quand arrive la deuxième séquence si elle est égale à la précédente alors je fait la même action , si par contre elle viens à changer je lance une autre action.

    Pour ce qui est de comparer la séquence que je lit avec une séquence que j'écrit en dur sur le programme ça fonctionne , mais je n'arrive pas à trouver la solution pour que le controllino le fasse sans que j'ai besoin de lui donné une séquence à comparer et qu'il le fasse tous seul. Pour ça j'utilise la fonction strcmp().

    Les séquences que je reçois sont comme ceci : "6056521585" : une suite de 10 chiffres.

    Alors du coup soit je demande peut être trop compliqué, soit mon programme n'est pas adapté à ce que je veux. Du coup je voudrais votre avis sur la question. Parce que je ne pense pas être très loin de la démarche à prendre.

    Voici mon code avec les commentaires.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    #define CMDBUFFER_SIZE 15   // Je definie la taille du buffer
    #include <Controllino.h>  // librairie pour le controllino
    #include <SPI.h>  // librairie pour la liaison Ethernet avec Ethernet.h
    #include <Ethernet.h>
     
    byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0xFC, 0x17}; // Adresse MAC du controllino
    IPAddress ip(192,168,23,154); // adresse IP du Controllino
    IPAddress server(192,168,23,153); // Adresse IP du serveur Lecteur
    EthernetClient client; // Je suis en mode Client
     
    void setup() // fonction Setup
    {
        pinMode (CONTROLLINO_D0, OUTPUT); // Mon port D0 en sortie
      pinMode (CONTROLLINO_D1, OUTPUT); // Mon port D1 en sortie
      pinMode (CONTROLLINO_D2, OUTPUT); // D2 en sortie
     
      Ethernet.begin(mac, ip); // Ethernet demarre avec les adresses mac et Ip donné
      Serial.begin(57600); // vitesse de lecture sur le moniteur serie
      while (!Serial){;} 
      delay(1000);
     
      Serial.println("connexion..."); // Un afficheur connexion
      if (client.connect(server,2111))  // si le client donc le controllino ce connecte sur le serveur sur le port 2111
      {
        Serial.println("connecte"); // alors j'affiche connecte
      } 
      else // sinon
      {
        Serial.println("connexion echoue"); // j'affiche que la connexion est echoue
      }
    }
     
    void loop() // boucle infini
    {
     static char cmdBuffer[CMDBUFFER_SIZE] = ""; // le caractère buffer est à 0
     char c; // variable c en tant que caractère
     while(client.available())  // pour un client est présent donc si on reçois un octet
     {
       c = processCharInput(cmdBuffer, client.read()); // c prend la valeur de ce que le seveur envoi 
       Serial.print(c); // on fait afficher c
       if (c == '\n') // si c arrive au dernier octet
       {
         Serial.println(); // on fait un saut de ligne
     
         if (strcmp("6047078288", cmdBuffer) == 0)  // On compare deux chaines de caractères , si elles sont égaux
         {
            digitalWrite(CONTROLLINO_D0,HIGH); // on active la sortie D0
            digitalWrite(CONTROLLINO_D1,LOW); // on desactive la sortie D1
            digitalWrite(CONTROLLINO_D2,LOW); // on desactive la sortie D2
         }
              else if (strcmp("NOREAD", cmdBuffer) == 0) // Si "NOREAD" est egale à la valeur du buffer alors 
         {
          digitalWrite(CONTROLLINO_D1,LOW); // on desactive la sortie D1
          digitalWrite(CONTROLLINO_D0,LOW); // on desactive la sortie D0
          digitalWrite(CONTROLLINO_D2,HIGH); // on active la sortie D2
         }
         else // sinon
         {
          digitalWrite(CONTROLLINO_D0,LOW); // on desactive la sortie D0
          digitalWrite(CONTROLLINO_D1,HIGH); // on active la sortie D1
          digitalWrite(CONTROLLINO_D2,LOW); // on desactive la sortie D2
         }
     
         cmdBuffer[0] = 0; // on remet le buffer à 0
       }
     }
     //delay(1); // on attend 1 millisecondes
    }
     
    char processCharInput(char* cmdBuffer, const char c)
    {
     
     if (c >= 32 && c <= 126) // J'ignore les charactères spéciaux
     {
       if (strlen(cmdBuffer) < CMDBUFFER_SIZE) // si la taille de mon buffer est inferieur à la taille de CMDBUFFER
       { 
         strncat(cmdBuffer, &c, 1);   //Ajoute au buffer 
       }
       else  //sinon
       {   
         return '\n'; // fin de ligne
       }
     }
     else if ((c == 8 || c == 127) && cmdBuffer[0] != 0)
     {
     
       cmdBuffer[strlen(cmdBuffer)-1] = 0;
     }
     
     return c;
    }
    Je vous remercie pour votre lecture , et vous souhaites une très bonne journée.

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Il te faut deux buffers pour stocker la commande courante ainsi que la commande précédente : avant de récupérer la prochaine commande on copie le contenu du premier dans le second (ou mieux, on inverse leurs pointeurs). Il ne reste qu'à prendre en charge le cas de la première commande, lorsqu'il n'y a pas encore de précédente avec laquelle la comparer.

    Par ailleurs, tes données sont toujours des chaînes C terminées par un caractère nul ? Si ce n'est pas le cas il te faudra utiliser memcmp en lieu et place de strcmp.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2016
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    Bonjour Matt_Houston ,

    J'ai lu ce que vous m'avez proposé, j'ai du coup écrit ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    void loop()
    {
    	static char buffer1[buffer_SIZE];
    	static char buffer2[buffer_SIZE];
    	short *b1;
    	short *b2;
     
    	b1 = buffer1;
    	b2 = buffer2;
     
    	char c;
    	 while(client.available())
    	 {
    		c = processCharInput(buffer1, client.read());
    		Serial.print(c);
     
    		if ( c == '\n')
    		{
    			Serial.println();
    			memcpy(buffer2, buffer1, 10*sizeof(short));
    		}
     
    	short *inv;
     
    	inv = b1;
    	b1 = b2;
    	b2 = inv;
     
    	if (strcmp(buffer1, buffer2) == 0)
    	{
    		digitalWrite(CONTROLLINO_D0, HIGH);
    	}
     
     
    }
    Est-ce dans cette logique ? J'ai regardé pour la fonction memcpy qui m'a l'air très intéressante.
    Du coup j'ai mis la choses en place , j'ai fait une inversion de pointeur comme vous me l'avez conseillé avec le (inv).

    N’hésitez pas à me dire si j'ai fait des erreurs. Je vous remercie.

    Edit : Je viens de me rendre compte en relisant mon code , que j'inverse les données du buffer 1 dans le buffer 2 , et qu'après j'inverse les pointeurs , du coup je ne change rien , peut être que du coup mon memcpy je doit le retirer ?

  4. #4
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Effectivement, ce sont deux solutions indépendantes : soit tu copies le contenu d'un tampon dans l'autre et les rôles de chaque tampon sont immuables (tu te sers toujours du même tampon pour la lecture), soit tu échanges leurs pointeurs. Faire les deux à la suite revient à annuler l'opération.

    C'est bien de t'être renseigné sur memcpy, c'est toujours un bon réflexe de vérifier en premier si l'opération que tu cherches à réaliser est déjà implémentée par la bibliothèque standard ou l'une de tes dépendances.

    Quelques remarques en vrac à propos de ton code :
    • il manque l'accollade de fin de while (ou de fin de fonction, c'est selon) ;
    • tu manipules des tableaux de type char [] via des pointeurs de type short *, pourquoi ??
    • Si processCharInput ressemble toujours à la fonction décrite dans ton premier post, tu dois impérativement initialiser ton buffer de lecture (tu le faisais précédemment). En effet tu utilises strlen sur son contenu, qui ne s'arrête que lorsque '\0' est rencontré.
    • Tu n'informes pas la routine de lecture de la taille du tampon de destination, assure-toi donc bien qu'aucune chaîne à récupérer ne peut être plus longue que buffer_SIZE - 1.

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2016
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    Alors pour répondre à vos remarques :

    il manque l'accollade de fin de while (ou de fin de fonction, c'est selon) ;
    C'est une petite erreur de copie colle, j'ai bien l'accolade pas de soucis la dessus merci.

    tu manipules des tableaux de type char [] via des pointeurs de type short *, pourquoi ??
    Pour aucune raison, j'avais mis ça pour comprendre comment il fonctionnais et je n'ai pas fait de modification, c'est chose faite !

    Si processCharInput ressemble toujours à la fonction décrite dans ton premier post, tu dois impérativement initialiser ton buffer de lecture (tu le faisais précédemment). En effet tu utilises strlen sur son contenu, qui ne s'arrête que lorsque '\0' est rencontré.
    Oui j'ai crée un autre programme donc il est vrai que je n'avais pas remis ce que j'avais écrit dans le nouveau.

    Voici donc mon nouveau code complet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    #include <SPI.h>
    #include <Ethernet.h>
    #include <Controllino.h>
    #define buffer_SIZE 15
     
    byte mac [] = {0x90, 0xA2, 0xDA, 0x0D, 0xFC, 0x17};
    IPAddress ip (192,168,23,154);
    IPAddress server(192,168,23,153);
    EthernetClient client;
     
    void setup()
    {
      pinMode (CONTROLLINO_D0, OUTPUT);
      pinMode (CONTROLLINO_D1, OUTPUT);
      pinMode (CONTROLLINO_D2, OUTPUT);
     
      Ethernet.begin (mac, ip);
      while (!Serial){;}
      Serial.println("Connexion ...");
      if (client.connect(server,2111))
      {
        Serial.println("Connecte");
      }
      else
      {
        Serial.println("Impoosible de ce connecter");
      }
      Serial.begin(57600);
    }
     
    void loop()
    {
      static char buffer1[buffer_SIZE];
      static char buffer2[buffer_SIZE];
      char *b1;
      char *b2;
     
      b1 = buffer1;
      b2 = buffer2;
     
      char c;
       while(client.available())
      {
        c = processCharInput(buffer1, client.read());
        Serial.print(c);
     
        if ( c == '\n')
        {
          Serial.println();
          memcpy(buffer2, buffer1, 10*sizeof(char));
        }
     
        char *inv;
     
        inv = b1;
        b1 = b2;
        b2 = inv;
     
     
        if (strcmp(buffer1, buffer2) == 0)
        {
          digitalWrite(CONTROLLINO_D0, HIGH);
          digitalWrite(CONTROLLINO_D1, LOW);
        }
        else 
        {
          digitalWrite(CONTROLLINO_D0, LOW);
          digitalWrite(CONTROLLINO_D1, HIGH);
        }
     
        buffer1[0] = 0; 
      }
     
     
    }
     
    char processCharInput(char* buffer1, const char c)
    {
     
     if (c >= 32 && c <= 126) // J'ignore les charactères spéciaux
     {
       if (strlen(buffer1) < buffer_SIZE) // si la taille de mon buffer est inferieur à la taille de buffer1
       { 
         strncat(buffer1, &c, 1);   //Ajoute au buffer 
       }
       else  //sinon
       {   
         return '\n'; // fin de ligne
       }
     }
     else if ((c == 8 || c == 127) && buffer1[0] != 0)
     {
     
       buffer1[strlen(buffer1)-1] = 0;
     }
     
     return c;
    }
    J'ai fait un test , j'ai donc bien D0 qui s'allume quand je passe une sequence. mais quand je change la sequence devant le lecteur , la sortie reste D0 et D1 ne s'enclenche pas.

    J'ai fait un test en mettant memcpy en commentaire et ensuite en mettant inversion des pointeurs en commentaire.
    Je vais continuer à regarder ce qui ne vas pas, si vous avez votre petite idée n'hesitez pas.

    Je vous remercie !

  6. #6
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Attention :
    • ta logique de traitement est maintenant à l'extérieur du bloc if (c == '\n'), autrement dit tu exécutes l'inversion des buffers et leur comparaison après la lecture de chaque caractère ;
    • tes buffers ne sont toujours pas initialisés avant d'entrer dans la boucle.

    Tu devrais :
    • mettre la boucle de lecture à part dans une petite fonction dédiée ;
    • ne pas dépendre du contenu de départ du buffer.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /* Reads at most bufsize - 1 bytes using client.read() and stores them into the memory area pointed to by buf, until a newline character or a zero byte is found.
     * Returns the number of non-zero bytes read, excluding newline character.
     * If bufsize is non-zero and buf is NULL, freed or uninitialized, the behaviour is undefined.
     */
    size_t read_sequence(char *buf, size_t bufsize) {
        if (bufsize == 0)
            return 0;
     
        size_t n = 0;
        char c;
        while (n < bufsize - 1 && (c = client.read()) != '\n' && c != '\0')
            buf[n++] = c;
     
        buf[n + 1] = '\0';
     
        return n;
    }

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2016
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    D'accord je vois tout à fait. J'ai refait mon code. Et là j'ai bien ma comparaison automatique qui se déclenche quand j'ai une différence.

    Par contre mon dernier soucis est la valeur de départ. Quand je lance la première lecture j'ai évidement une action qui ce lance car il compare le buffer1 avec le buffer2 qui lui est vide.

    Pourtant j'ai bien essayé de lui dire de ne pas prendre en compte si buffer2 est vide.

    Est ce que le code que vous avez posté est en rapport avec ça ?

    En tous cas merci de m'avoir mis sur la vois ! ça ma permis de connaitre quelques fonctions que je n'avais encore jamais vu et ça ma décoincé de mon petit problème !

Discussions similaires

  1. Lire une trame série contenant des sauts de lignes
    Par Jugulaire dans le forum Réseau
    Réponses: 4
    Dernier message: 03/04/2015, 09h33
  2. Lire une partie de trame sous LabVIEW
    Par neyo67 dans le forum LabVIEW
    Réponses: 11
    Dernier message: 01/04/2015, 17h10
  3. Lire une trame avec TcomPort
    Par makroute dans le forum C++Builder
    Réponses: 4
    Dernier message: 14/04/2008, 10h22
  4. [TP]lire une ligne de l'ecran et la stocker dans une chaine
    Par Bleuarff dans le forum Turbo Pascal
    Réponses: 26
    Dernier message: 02/07/2002, 11h08
  5. lire une image au format RAW
    Par Anonymous dans le forum OpenGL
    Réponses: 5
    Dernier message: 20/05/2002, 01h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo