Interpréter mes commandes reçues

Bonjour a tous,

Je développe une communication serie entre Labview et un arduino (UNO et MEGA 2560).

AUcun probleme pour remonter des valeurs de capteur du arduino vers Labview.

Pour aller plus loin , je souhaiterai envoyer des consignes de Labview a mon Arduino.

Pour Labview aucun problemes (Developpeur confirmé)...mais pour le Arduino... :confused:

En fait, je voufrais envoyer des consignes de type:

Tim=2000 ou "Tim" est la commande et "2000" est la consigne de cette commande.

Je crois que je dois decouper la chaine recu "Tim=2000" au niveau du égale pour séparer commande et consigne, mais je sais pas faire.

Ensuite dans le cas ou j'ai des dizaines de consigne, je souhaiterai ne pas avoir des "IF" a l'infini..

Voici mon code qui gère aujourd'hui 3 requetes

void ProcessCmd(){
  
    //Serial.print( "ProcessCmd for [" );
    //Serial.print( cmd );
    //Serial.println( "]" );
    
    if(cmd.equals("tem")){
         Serial.print("tem=");
         Serial.println(TemCom);
         clearCmd();
      }
      else if(cmd.equals("lum")){
         Serial.print("lum=");
         Serial.println(LumCom);
         clearCmd();
      }
      else if(cmd.equals("pow")){
         Serial.print("pow=");
         Serial.println(PowCom);
         clearCmd();
      }
      else{
         // toutes les autres commandes sont ignorées.
         Serial.println("unknown command!");
         clearCmd();
      }

Merci

Salut
Ci-joint une petite lib qui fait ce genre de chose.
L’utilisation ressemble à ça :

#include <SerialComm.h>
SerialComm s;

void setup() {
  s.begin(9600);   //Initialisation de la liaison serie
  s.attach('A', actionLed1);     //Affecte le caractere A à la fonction actionLed1
  s.attach('B', actionLed2);     //Affecte le caractere B à la fonction actionLed2
}

void serialEvent() {
  s.read();
}

void actionLed1(void) {
  digitalWrite(led1, 1 - digitalRead(led1));
}

void actionLed2(void) {
  digitalWrite(led2, 1 - digitalRead(led2));

J’ai simplifié…
Il y a un exemple de fourni.
Je suis en train de la réécrire, un peu plus élaborée…

David.

SerialComm.zip (5.25 KB)

Bonjour et bienvenue,

Peut-être un truc dans ce style: LURVfT - Online C++ Compiler & Debugging Tool - Ideone.com

edez66:
Je crois que je dois decouper la chaine recu “Tim=2000” au niveau du égale pour séparer commande et consigne, mais je sais pas faire.

Il faut utiliser strtok() pour faire ça.

Oulala merci a tous, je n'avais pas vu les reponses!

-tahitibob35: c'est un peu le principe , sauf que je voudrais rajouter un argument (consigne a l'action).

-guix: merci beaucoup , malheureusement, ce code n'est pas renseigné...et je n'y comprend :astonished: rien je vais faire mon possible et ecrire a coter lol .
j'aprehende juste les tableaux....et le %&!== sont des inconnus .....aller au boulot!! :grinning: :grinning:

-fdufnews:effectivement je suis tombé pas mal de fois sur la fonction strtok mais sans arrivé a mes fins..malgré tous les exemples..... :roll_eyes: il va falloir que je maitrise ça aussi ça semble un bon outil....

Je vais deja m'atteler a la fonction de guix qui me parrait decouper les taches d'une manière que j'aime bien!

La méthode popInt permet de récupérer un entier :

void actionLed1(void) {
  digitalWrite(led1, 1 - digitalRead(led1));
  int valeur1;
  valeur1 = s.popInt();     //Recup 1er parametre
  int valeur2;
  valeur2 = s.popInt();     //Recup parametre suivant
}

Bon , je reviens vers GUIX , ta solution me plais vraiment, si j’ai bien compris, je gere mes commandes et mes consigne sous forme d’un tableau 2D de tableau 1d(les commandes) et de valeur(les consignes)? :smiley:

mes question a coté du code!

#include <stdio.h>
#include <string.h>

struct Consigne                //struct est ce une instruction connu de Arduino?
{
	char nom[8];           //je suppose un tableau de char de longeur 1D de 8,Ok
	long valeur;           // variable long , Ok
};

// les consignes et leurs valeurs par défaut.
Consigne consignes[] =
{
	{ "tem", 2000 },       //première Consigne du tableau? un tableau de char et une valeur????j'ai bon?
	{ "lum", 1000 },       //seconde Consigne ""
	{ "pow",  500 }        //troisieme Consigne ""
};

int main()                                                                                //fonction main
{
	char entree[] = "pow=5000";                                                       //tableau qui contient la consigne  recues ex: pow=5000
	
	Consigne consigne;                                                                // je comprend pas ce que ca fait la!?
	if ( sscanf( entree, "%7[^ =]%*[ =]%ld", consigne.nom, &consigne.valeur ) == 2 )  //ça: "%7[^ =]%*[ =]%ld", j'arrive pas a dechiffrer, sscanf met un pointeur au debut de entree[],decoupage avant "=" de nom et valeur 
	{
		bool consigneInconnue = true;                                             // par defaut avant recherche de consigne.nom, la consigne est inconnu , ok
		for ( int i = 0; i < sizeof(consignes) / sizeof(Consigne); i++ )          //du debut a la fin des caractères de consigne, mais je comprens pas les deux consignes et Consigne
		{
			if ( !strcmp( consignes[i].nom, consigne.nom ) )                  //on compare la consigne.nom avec les consignes declarées existantes dans le tableau du debut ,Ok
			{
				consigneInconnue = false;                                  //la consigne est trouvé, donc consigne inconnue = faux , Ok
				consignes[i].valeur = consigne.valeur;                    //on a trouvé la consigne donc i est à l'indice de cette consigne, on complete le tableau avec la valeur de la consigne recue
				printf( "Consigne \"%s\" modifiée à %ld.\n", consigne.nom, consigne.valeur );// affiche "consigne" sous forme de string, et "modifiée" puis????
				break;
			}
		}
		if ( consigneInconnue )
		{
			printf("Consigne \"%s\" inconnue.\n", consigne.nom );
		}
	}
	else
	{
		printf("Commande \"%s\" inconnue.\n", entree );
	}

	return 0;
}

tahitibob35:
Salut
Ci-joint une petite lib qui fait ce genre de chose.
L’utilisation ressemble à ça :

#include <SerialComm.h>

SerialComm s;

void setup() {
  s.begin(9600);  //Initialisation de la liaison serie
  s.attach(‘A’, actionLed1);    //Affecte le caractere A à la fonction actionLed1
  s.attach(‘B’, actionLed2);    //Affecte le caractere B à la fonction actionLed2
}

void serialEvent() {
  s.read();
}

void actionLed1(void) {
  digitalWrite(led1, 1 - digitalRead(led1));
}

void actionLed2(void) {
  digitalWrite(led2, 1 - digitalRead(led2));




J'ai simplifié....
Il y a un exemple de fourni.
Je suis en train de la réécrire, un peu plus élaborée.....

David.

SerialComm s ca veux dire que s prend la valeur SerialComm ?

je vais me renseigner sur SerialCOmm attach j’ai un peu de mal a comprendre

SerialComm s ça veux dire que s prend la valeur SerialComm ?

Bonjour,
c'est l'inverse ... pour éviter de réécrire SerialComm dans les suites

Bonjour,

SerialComm s ca veux dire que s prend la valeur SerialComm ?

Ça veut dire qu'on crée un objet de class (type) SerialComm qui s'appelle s.

Ça veut dire qu'on crée un objet de class (type) SerialComm qui s'appelle s.

Merci Kamill,
cela peut m'être utile : sais-tu où ce procédé est décrit (propre à arduino, c++, c) ?

c'est le cas général de déclaration d'une variable en c++

type nom_variable;

type peut être un type simple (char, int ...) ou une class, struct, union ...

edez66:
malheureusement, ce code n’est pas renseigné

Oui c’est fait exprès :smiley_cat:… Si tu as un code sans commentaires et que tu ne comprends pas, ça t’oblige à faire quelques recherches, ce qui permet d’apprendre. C’est ma méthode ^^. Bon d’accord j’explique un peu mon code:

  • Le site ideone ne peut pas compiler un sketch pour arduino, mais arduino utilise le langage C/C++ donc il y a très peu de modifications à faire pour que mon code fonctionne sur l’arduino. En gros, il suffit de changer “main” en “loop”, d’ajouter un “setup”, changer les “printf” en “Serial.print”… et voilà.

  • struct défini un nouveau type de variable (comme int, bool, etc…). J’ai appelé ce nouveau type de variable Consigne, et une Consigne est définie par un nom de maximum 7 caractères (+1 pour le caractère NULL à la fin, ce qui permet d’en faire un string valide) et une valeur de type long.

Consigne consigne;
if ( sscanf( entree, "%7[^ =]%*[ =]%ld", consigne.nom, &consigne.valeur ) == 2 )
  • On scanne l’entrée pour, si possible, y trouver un nom et une valeur, et les stocker dans une Consigne

  • “%7[^ =]%*[ =]%ld” se décompose en trois parties:

  • “%7[^ =]” : trouver des caractères (maximum 7), qui ne soient pas un espace ou un signe égal,

  • “%*[ =]” : puis ignorer les espaces et les signes égal,

  • “%ld” : puis trouver un nombre de type long.

  • Si sscanf retourne 2, ça veut dire que l’entrée a été correctement séparée en un nom et une valeur, et stockée dans la variable consigne.

for ( int i = 0; i < sizeof(consignes) / sizeof(Consigne); i++ )

sizeof(consignes) / sizeof(Consigne) permet de calculer le nombre d’éléments dans le tableau “consignes”.

  • sizeof(Consigne) retourne la taille d’une consigne, soit 8 caractères pour le nom (8 bytes), et 1 long (4 bytes), soit 12 bytes
  • sizeof(consignes) retourne la taille du tableau “consignes” (soit 36 bytes puisqu’il y a 3 consignes de 12 bytes)
  • Si on divise la taille du tableau par la taille d’une Consigne, on obtient le nombre d’éléments dans le tableau. Tu pourrais bêtement écrire 3, mais calculer ce nombre est plus pratique car ça évite de devoir modifier ce 3 quand tu ajoutera d’autres consignes dans le tableau. car si tu oublie de modifier le 3, alors ton code sera buggé. Voilà pourquoi il est préférable de laisser ton arduino calculer ce nombre lui-même :wink:

Tu sembles avoir compris le reste… :wink:

Bonjour,
merci Kamill !