Concentration sur une partie d'une chaine de caractère

Bonjour, le sujet n'est peut-être pas clair, mais je vais tenter de vous expliquer. Je suis en terminal et j'ai un projet en elec pour la fin de l'année qui consiste à permettre l'irrigation d'une serre via smartphone. J'ai donc mon Arduino Uno et le shield GSM. Il faut donc pouvoir envoyer des arrosages en envoyant par exemple "1" sur telle vanne, puis "2" sur une autre vanne etc... Mon problème réside dans les durées d'arrosage. En effet il faudra pouvoir parametrer les durées d'arrosages pour les électrovannes (4 en tout). Donc il faudrait que par exemple j'envoie par sms : am13s30. J'explique ce charabia. Le a correspondrai à la vanne n°1 (la vanne a) le m correspondrai à minutes, ici 13 et le s correspondrait à secondes, ici 30. Donc je déclarerai une variable minutes et une variable secondes qui correspondrai à celles envoyer dans le message am13s30. Ma question est, comment faire pour faire comprendre à l'Arduino quelle est la partie du message qu'il devra lire pour la variable minutes et la variable secondes ?
J'espère que je ne me suis pas trop mal exprimer :confused:

D'avance merci.

Yep!

Plusieurs solutions sont à ta portée.

Soit la longueur du message est strictement identique, dans ce cas là, on remplit un tableau avec les données reçues et on interroge les index du tableau pour savoir quoi correspond à qui et combien de temps.

am13s30 devient

char tableau[3] = { a, 13, 30 };

Soit le message est variable et dans ce cas là on prévoit un séparateur entre les variables à étudier. On remplit toujours un tableau sauf que le séparateur sert à classer les variables.

a;13;30

On peut aussi s'assurer que le message est complet en ajoutant un caractère de de début et de fin de chaîne. Par exemple les caractères # et !

#a;13;30!

Si tu penses travailler avec les heures, minutes, secondes ou plus, tu allonges ton message en circonstance. Exemple, enclencher la vanne z dans 1 heure 30 minutes pendant 45 secondes :

#z;01;30;45!

Etudies la manière dont on accède aux données d'un tableau et tu auras des pistes sérieuses :

http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.Tableaux

@+

Zoroastre.

zoroastre:
Yep!

Plusieurs solutions sont à ta portée.

Soit la longueur du message est strictement identique, dans ce cas là, on remplit un tableau avec les données reçues et on interroge les index du tableau pour savoir quoi correspond à qui et combien de temps.

am13s30 devient

char tableau[3] = { a, 13, 30 };

Soit le message est variable et dans ce cas là on prévoit un séparateur entre les variables à étudier. On remplit toujours un tableau sauf que le séparateur sert à classer les variables.

a;13;30

On peut aussi s'assurer que le message est complet en ajoutant un caractère de de début et de fin de chaîne. Par exemple les caractères # et !

#a;13;30!

Si tu penses travailler avec les heures, minutes, secondes ou plus, tu allonges ton message en circonstance. Exemple, enclencher la vanne z dans 1 heure 30 minutes pendant 45 secondes :

#z;01;30;45!

Etudies la manière dont on accède aux données d'un tableau et tu auras des pistes sérieuses :

Référence Arduino français Main/Tableaux

@+

Zoroastre.

Bonjour, tout d'abord merci pour ton aide.

Je pense avoir saisi le principe, mais donc si j'ai bien compris, si j'envoie am13s30 à l'Arduino, il faudrait qu'il arrive lui même à classer ces caractères dans un tableau c'est ça ? Et on récupérerai ces caractères dans le tableau par la suite ?

Bonjour, j’ai essayé de remplir un tableau avec des valeurs. Je me suis inspiré du code ReceiveSMS d’Arduino pour voir si le tableau se remplissait bien avec ces valeurs. Ce n’est pas le cas :frowning: Voici mon code :

// include the GSM library
#include <GSM.h>

// PIN Number for the SIM
#define PINNUMBER "1608"

// initialize the library instances
GSM gsmAccess;
GSM_SMS sms;

// Array to hold the number a SMS is retreived from
char senderNumber[20];  

void setup() 
{
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  } 

  Serial.println("SMS Messages Receiver");
    
  // connection state
  boolean notConnected = true;
  
  // Start GSM connection
  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }
  
  Serial.println("GSM initialized");
  Serial.println("Waiting for messages");
}

void loop() 
{
  char c;
  char tableau[4];
  
  // If there are any SMSs available()  
  if (sms.available())
  {
    Serial.println("Message received from:");
    
    // Get remote number
    sms.remoteNumber(senderNumber, 20);
    Serial.println(senderNumber);

    // An example of message disposal    
    // Any messages starting with # should be discarded
    if(sms.peek()=='#')
    {
      Serial.println("Discarded SMS");
      sms.flush();
    }
    
    // Read message bytes and print them
    while(c=sms.read())
      Serial.print(c);
      
    Serial.println("\nEND OF MESSAGE");
    
    Serial.println(tableau[0]);
    Serial.println(tableau[1]);
    Serial.println(tableau[2]);
    
    // Delete message from modem memory
    sms.flush();
    Serial.println("MESSAGE DELETED");
  }

  delay(1000);

}

J’ai envoyé le message {a,13,30} et le Serial ne reçoit que des rectangles… Une chose qui saute aux yeux dans mon code ?

Merci d’avance pour toute aide reçue.

Bonjour, j’ai essayé de remplir un tableau avec des valeurs. Je me suis inspiré du code ReceiveSMS d’Arduino pour voir si le tableau se remplissait bien avec ces valeurs. Ce n’est pas le cas :frowning: Voici mon code :

// include the GSM library
#include <GSM.h>

// PIN Number for the SIM
#define PINNUMBER "1608"

// initialize the library instances
GSM gsmAccess;
GSM_SMS sms;

// Array to hold the number a SMS is retreived from
char senderNumber[20];  

void setup() 
{
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  } 

  Serial.println("SMS Messages Receiver");
    
  // connection state
  boolean notConnected = true;
  
  // Start GSM connection
  while(notConnected)
  {
    if(gsmAccess.begin(PINNUMBER)==GSM_READY)
      notConnected = false;
    else
    {
      Serial.println("Not connected");
      delay(1000);
    }
  }
  
  Serial.println("GSM initialized");
  Serial.println("Waiting for messages");
}

void loop() 
{
  char c;
  char tableau[4];
  
  // If there are any SMSs available()  
  if (sms.available())
  {
    Serial.println("Message received from:");
    
    // Get remote number
    sms.remoteNumber(senderNumber, 20);
    Serial.println(senderNumber);

    // An example of message disposal    
    // Any messages starting with # should be discarded
    if(sms.peek()=='#')
    {
      Serial.println("Discarded SMS");
      sms.flush();
    }
    
    // Read message bytes and print them
    while(c=sms.read())
      Serial.print(c);
      
    Serial.println("\nEND OF MESSAGE");
    
    Serial.println(tableau[0]);
    Serial.println(tableau[1]);
    Serial.println(tableau[2]);
    
    // Delete message from modem memory
    sms.flush();
    Serial.println("MESSAGE DELETED");
  }

  delay(1000);

}

J’ai envoyé le message {a,13,30} et le Serial ne reçoit que des rectangles… Une chose qui saute aux yeux dans mon code ?

Merci d’avance pour toute aide reçue.

Salut ...

La première chose qui saute aux yeux c'est que tu ne mets rien dans ton tableau[0] [1] ... Donc ton message ne peut pas s'y trouver par magie ...

Ton message "arrive" dans ton code lors de while ( c= sms.read()) ...

Actuellement tu ne fais qu'afficher le message caractère par caractère avec serial.print(c) (normalement tu devrais le voir dans ta console ... Sinon il y a un souci qq part (je ne connais pas les fonctions gsm))

Il faudrait que tu traites un peu plus les caractères que tu reçois ... Par exemple

Byte index = 0;
While (c=sms.read()) {
If (c != ´,´) {
Tableau[index] = c; //on stocke les caractères différents d'une virgule
index++;
}
}

Il faudra vérifier que tu ne dépasses jamais la taille du tableau ... Donc prévoir un grand tableau pour commencer

B83s:
Salut ...

La première chose qui saute aux yeux c'est que tu ne mets rien dans ton tableau[0] [1] ... Donc ton message ne peut pas s'y trouver par magie ...

Ton message "arrive" dans ton code lors de while ( c= sms.read()) ...

Actuellement tu ne fais qu'afficher le message caractère par caractère avec serial.print(c) (normalement tu devrais le voir dans ta console ... Sinon il y a un souci qq part (je ne connais pas les fonctions gsm))

Il faudrait que tu traites un peu plus les caractères que tu reçois ... Par exemple

Byte index = 0;
While (c=sms.read()) {
If (c != ´,´) {
Tableau[index] = c; //on stocke les caractères différents d'une virgule
index++;
}
}

Il faudra vérifier que tu ne dépasses jamais la taille du tableau ... Donc prévoir un grand tableau pour commencer

Bonjour, effectivement j'ai tenté l'impossible... Le message s'affiche bien dans le moniteur série donc pas de problème de ce côté là. J'ai bien compris ton code et je vais m'en inspirer merci :slight_smile: par contre est-ce normal que les apostrophes autours de la virgule dans le if soit penché comme ça ? Chez moi elles sont droites, c'est bien le même caractère ?

Pour les apostrophes j'écris sur tablette alors c'est un peu aléatoire ...

Donc si ton message s'affiche bien dans la console, il suffit de faire comme je t'ai dit : tu stockes chaque caractère (sauf les virgules) dans un tableau ... Mais attention, si tu lui envoies 13 ... Ca tient sur 2 caractères...

B83s:
Pour les apostrophes j'écris sur tablette alors c'est un peu aléatoire ...

Donc si ton message s'affiche bien dans la console, il suffit de faire comme je t'ai dit : tu stockes chaque caractère (sauf les virgules) dans un tableau ... Mais attention, si tu lui envoies 13 ... Ca tient sur 2 caractères...

Merci pour tes réponses elles m'aident énormément... J'ai réussi à classer le message da1330 donc 6 index pour le tableau. Maintenant il faut que j'arrive à concatener l'index 3 et 4 pour obtenir 13 et l'index 5 et 6 pour obtenir 30, mais je vais y arriver :slight_smile:

Bon j’ai finis exactement ce que je voulais faire. Je donne la solution qui pourra peut-être aider quelqu’un, en fait je n’ai pas réussi à vraiment concatener les index du tableau (faire tableau[3,4] ne fonctionnait pas) du coup j’y suis aller un peu bizarrement mais ça fonctionne, j’ai déclarer des variable minutes et secondes en int, et j’ai fais des calculs :

dizaines_minutes = (tableau[2]-48)*10;
     unites_minutes = (tableau[3]-48);
     dizaines_secondes = (tableau[4]-48)*10;
     unites_secondes = (tableau[5]-48);

Pour ceux qui se demande d’où vient le -48, et bien c’est tout simplement que ma valeur est un int, donc le Serial ne me lira pas le nombre que je lui ai envoyé mais la valeur en décimal qui lui correspond (vu que les nombres dans le serial sont en ascii). Essayez avec la valeur 5 par exemple, 5 en ascii correspond à 53 en decimal, donc 53-48 = 5. C’est pas très orthodoxe comme méthode mais ça fonctionne ;D

Ensuite il ne nous reste plus qu’a convertir les minutes et les secondes en millisecondes, vu que la fonction delay() s’exprime en ms, donc voilà :

minutes = (dizaines_minutes+unites_minutes)*60000;
     secondes = (dizaines_secondes+unites_secondes)*1000;

Voilà merci pour toute votre aide ! :wink:

Navymud