shield GSM 2 : inconsistance de sms.flush()

Bonjour à tous,

J'aimerais simplement l'avis de vrais développeurs arduino sur le code suivant, car cela fait maintenant un bout de temps que je tourne en rond. :confused:


CE QUE JE SOUHAITE FAIRE

Mon programme reçoit des instructions par SMS. Or, lorsqu'il reçoit un SMS et qu'il traite le bout de code correspondant à l'instruction reçue, il est possible que d'autres instructions lui soient envoyées entre temps

D'après ce que je sais, les SMS en attente sont stockées dans la mémoire du modem du shield GSM mais je n'en suis pas sûr, je ne retrouve pas ma source.

J'aimerais que mon programme ignore ces instructions en attente, et donc, que les SMS reçus alors qu'il était déjà occupé à autre chose soient effacés.

C'est la fonction sms.flush() qui me pose problème. Cette fonction se trouve dans la librairie GSM.h, qui est intégrée à l'IDE Arduino par défaut.

  • Déjà première incompréhension : la page de référence affirme que flush() efface la mémoire du modem des "messages envoyés".
  • Mais d'un autre côté, l'exemple de réception de SMS officiel (ReceiveSMS) utilise bel et bien sms.flush() pour vider la mémoire du modem de messages reçus... Ce qui me laisse penser que la fonction vide simplement le modem (mais encore une fois, je ne suis pas certain puisque dans mon cas ça ne fonctionne pas complètement ; j'avais posé la question en anglais avant d'apprendre l'existence du forum français, mais je crois que je n'ai pas vraiment compris la réponse :grinning: ).

CE QUE J'AI FAIT

Voici mon code :

void SuppressionSMS(){
	int NbMessage = 0;
	Serial.print(F("["));
	do{
		sms.flush();
		NbMessage++;
	} while (sms.available() > 0);
	Serial.print(NbMessage);
	Serial.print(F(" message(s)"));
	Serial.println(F(" efface(s)]\n"));
}

La fonction SuppressionSMS est appelée après la fin d'un envoi de message.

  • Par exemple, l'arduino reçoit un SMS avec l'ordre d'allumer une LED
  • Il effectue l'opération
  • puis envoie un SMS indiquant que l'opération est effectuée, que la LED allumée
  • C'est là que SupressionSMS est appelée

Avec la fonction do(), j'espérais forcer l'arduino à effacer non seulement la première instruction reçue et le SMS de réponse envoyé, mais également toute instruction reçue entre temps.

Mais ce n'est pas le cas : si j'envoie 5 SMS avec des instructions, celles-ci sont traitées les unes après les autres, ce qui n'est pas ce que je veux. Y-a-t'il un souci dans mon utilisation de do() ?

Pourquoi est-ce que je veux effacer les instructions en attente ?
Parce que sinon, le programme plante souvent. Si ces mêmes instructions sont envoyées après que chacune d'entre elle ait reçue sa réponse de l'arduino, le programme ne plante pas.
Mais si j'envoie ces instructions les unes à la suite des autres sans me soucier de ce que le programme ait eu le temps de traiter celles déjà reçues ou pas, y a toujours un moment où ça coince.

Voilà pourquoi je cherche à éliminer les instructions reçues en attente de traitement.


LE MATOS

Arduino UNO + GSM Shield 2 (SIM Sosh)


Je vous remercie d'avance pour vos conseils... :frowning:

Ps : si quelqu'un sait où je peux trouver les fichiers GSM.h et GSM.cpp dans mon Mac, ça m'aiderait pour aller voir ce qui s'y trame...

This method clears the modem memory once the messages were sent.

Cette méthode vide la mémoire du modem lorsque les messages ont été envoyés.
Ils ne parlent pas des messages reçus!!

En même temps dans l'exemple juste en-dessous ils ont l'air de traiter les messages reçus.

fdufnews:
En même temps dans l'exemple juste en-dessous ils ont l'air de traiter les messages reçus.

Exactement ! Mais puisqu'ils l'utilisent pour les messages reçus également (cf. le croquis officiel ReceiveSMS), c'est qu'il doit bien s'agir de la méthode adéquate...

bonjour,
les sms sont gardés sur la sim

la commande envoyée est AT+CMGD= dans le fichier GSM3ShieldV1SMSProvider.cpp
tu peux utiliser une commande comme celle ci

mySerial.println("AT+CMGDA=\"DEL ALL\"");

ou encore

for (int position=0; position<50; position++){
 mySerial.print("AT+CMGD=");
  mySerial.print((position);  
  mySerial.print("\r");
}

flush() ne travaille que sur le SMS "courant" - c'est bien expliqué dans votre lien

quand on a un doute, le mieux est d'aller voir le code source :slight_smile:

void GSM3SMSService::flush()
{		
	theGSM3SMSProvider->flushSMS();
	waitForAnswerIfNeeded(1);
};

si vous suivez le code vous arrivez à

void GSM3ShieldV1SMSProvider::flushSMSContinue()
{
	bool resp;
	// 1: Deleting SMS
	// 2: wait for OK
	switch (theGSM3ShieldV1ModemCore.getCommandCounter()) {
    case 1:
		theGSM3ShieldV1ModemCore.setCommandCounter(2);
		theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+CMGD="), false);
		theGSM3ShieldV1ModemCore.print(idSMS);
		theGSM3ShieldV1ModemCore.print("\r");
		break;
	case 2:
		if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp))
		{
			if (resp) theGSM3ShieldV1ModemCore.closeCommand(1);
			else theGSM3ShieldV1ModemCore.closeCommand(3);
		}
		break;
	}
}

et vous retrouvez la commande AT que @infobarquee proposait et donc on voit bien que cela ne touche que le message N° idSMS

comme dit dans la doc

but you could iterate through a for loop, or identify a specific index number to remove, instead of the dummy # used below

si on veut tous les détruire, il faut faire une boucle

Merci J-M-L pour cette réponse complète, la première que j'ai avec ces détails bien que j'ai posé la question un peu partout.

J-M-L:
quand on a un doute, le mieux est d'aller voir le code source :slight_smile:

J'ai un gros souci sur mon Mac : impossible d'aller trouver le code source dont vous me parlez sur ma machine pour le modifier éventuellement.. Je me suis même rendu dans l'application Arduino où j'ai trouvé les librairies, mais il y a tout sauf la librairie GSM.h ou .cpp :frowning:
Mais je vais continuer à chercher.
Sinon j'imagine que je peux toujours le retélécharger sur GitHub, le renommer et faire un #include dans mon programme.

J-M-L:
comme dit dans la docsi on veut tous les détruire, il faut faire une boucle

Est-ce que la boucle doit se faire dans mon code téléversé dans Arduino ? Ou au sein du code source ?
Parce que dans le premier cas, je croyais que c'est ce que je faisais avec ma boucle do(), non ?

En tout cas, merci beaucoup, vous m'avez bien guidé dans le code source... :cold_sweat:

Merci aussi inforbarquee pour ces détails que je n'avaient jamais trouvé.

infobarquee:
les sms sont gardés sur la sim

la commande envoyée est AT+CMGD= dans le fichier GSM3ShieldV1SMSProvider.cpp

Juste une petite question : je n'y connais rien en commandes AT et je vais faire mes devoirs sérieusement en me renseignant, mais est-ce qu'elles sont utilisable autrement que par le moniteur série ? Car dans mon projet l'arduino n'est pas accessible, il doit faire son taf tout seul.
Je peux programmer ces commandes pour qu'elles soient lancées automatiquement n'est-ce pas ?

je t'ai mis le code pour effacer les sms, je vois large en prenant 50.
donc dès que ta commande est recue, traitée, tu lance cette boucle.

pour les commandes AT, vu que je t"ai donné un code, tu prends exemple dessus en prenant pour habitude de mettre un delay(1000) après chaque commande, le temps de traitement de la commande et u retour.

J'ai un gros souci sur mon Mac : impossible d'aller trouver le code source dont vous me parlez sur ma machine pour le modifier éventuellement.. Je me suis même rendu dans l'application Arduino où j'ai trouvé les librairies, mais il y a tout sauf la librairie GSM.h ou .cpp :frowning:

Sur votre Mac les librairies se trouvent à 2 endroits

1/ les librairies qui sont livrées en standard dans l'IDE Arduino sont cachées au sein de l'application Arduino. Je suppose que vous avez installé l'IDE dans le répertoire /Applications. Si vous allez sur l'application et faites un ctrl-click (click gauche) vous aurez un menu qui s'affiche qui vous dit "afficher le contenu du paquet"

choisissez cela et ensuite vous pouvez naviguer dans l'arborescence de l'application. ATTENTION à ne rien changer, vous pourriez vous retrouver avec un IDE non fonctionnel et ça sera écrasé par la prochaine mise à jour de l'IDE de toutes façons.

Par exemple vous trouverez les librairies matérielles ici

(vous pouvez voir aussi où est le répertoire des exemples juste au dessus de hardware)

et les librairies standard ici

(vous pouvez voir la librairie GSM par exemple dans cette capture d'écran 5ème répertoire à droite)

2/ les librairies que vous téléchargez depuis internet sont rangées dans un dossier "utilisateur" qui est défini par vos préférences de l'IDE

généralement dans vos Documents/Arduino

Vous retrouvez tout cela sur GitHub bien sûr à cette adresse: GitHub - arduino/Arduino: Arduino IDE 1.x par exemple la librairie GSM est dans Arduino/libraries/GSM/src/

--> Mais bien sûr pas forcément besoin de modifier la librairie, vous pouvez inclure une fonction dans votre code qui fait ce qu'il faut

Merci, j'ai donc trouvé la librairie GSM...
J'avais trouvé les librairies standard auparavant en affichant le contenu de l'app, mais je n'avais pas fouillé assez pour la partie hardware (je ne savais pas qu'elles étaient séparées en ces deux catégories).

Merci beaucoup !

infobarquee:
je t'ai mis le code pour effacer les sms, je vois large en prenant 50.
donc dès que ta commande est recue, traitée, tu lance cette boucle.

D'accord, donc je copie-colle tel-quel... Effectivement, 50 c'est large, mais les chiffres varient tellement (certains disent 20, d'autres 25, parfois 32 SMS sauvegardés sur une SIM), c'est tout aussi bien.

Donc si je comprends bien, pour utiliser ton code, j'initialise par un #include <SoftwareSerial.h> et dans mon void Setup() j'aurais une ligne mySerial.begin(9600);.

Seulement, dans toutes les explications que je trouve, <SoftwareSerial> est principalement utilisé pour ajouter un autre moyen (logiciel) de communication série quand le moniteur série hardware est occupé pour autre chose : et dans tous les exemples, il faut relier des pins de l'Arduino aux pins du matériel utilisé.

Je dois t'avouer être perdu sur la façon dont je met en place ça en hardware :confused:, car dans mon cas j'ai juste l'Arduino UNO sur le quel est pluggé le shield GSM. Le tout est dans une boite qui doit fonctionner en autonome, hors d'accès (bon là je l'ai récupérée pour bosser dessus).


EDIT : Oh purée, je vois ici qu'en fait je dois pas monter mon shield GSM sur mon Arduino en utilisant la structure du shield, mais relier pins à pins par des câbles, pour pouvoir ensuite faire un lien entre les deux pins qui joueront le rôle de Tx et Rx... :blush: :cold_sweat:

Bref, donc j'ai compris, je dois faire communiquer l'Arduino avec le module GSM par ce SoftwareSerial... Et d'ailleurs, j'imagine que quand je n'aurai plus besoin du moniteur série à des fins de débuggage, je pourrai me servir de ses connections pour faire le même boulot... Merci beaucoup donc !


EDIT 2 : Non mais je suis un noob... :frowning: :o :confused: Je viens de découvrir qu'en fait, les pins 2&3 du shield sont fait pour communiquer en SoftwareSerial depuis le début... Donc pas besoin de faire des connections bidons, le shield monté sur l'Arduino peut être contrôlé avec les commandes AT telles quelles...

Bon, c'était mon 1/4 d'heure de honte :stuck_out_tongue:

infobarquee:
pour les commandes AT, vu que je t"ai donné un code, tu prends exemple dessus en prenant pour habitude de mettre un delay(1000) après chaque commande, le temps de traitement de la commande et u retour.

D'accord, je ne savais pas l'intérêt du delay pour laisser le temps aux commandes AT d'être traitées par le shield GSM, bon conseil, je vais en prendre l'habitude :stuck_out_tongue_closed_eyes:

EDIT 2 : Non mais je suis un noob... :frowning: :o :confused: Je viens de découvrir qu'en fait, les pins 2&3 du shield sont fait pour communiquer en SoftwareSerial depuis le début... Donc pas besoin de faire des connections bidons, le shield monté sur l'Arduino peut être contrôlé avec les commandes AT telles quelles...

:slight_smile:

il y a peut-être même un jumper pour déplacer cela ailleurs - vous avez un lien sur votre shield?

Bon, alors je pensais avoir trouvé la solution avec vos commentaires, mais après 4h passées dessus sans résultat, je dois le reconnaître : je suis largué.

infobarquee:
tu peux utiliser une commande comme celle ci
mySerial.println("AT+CMGDA="DEL ALL"");

J'ai tourné le machin dans tous les sens, impossible de faire fonctionner cette commande AT. Je ne sais pas comment elle est sensée être employée.
Pour utiliser une commande AT, si je comprends bien, j'ai besoin de la librairie SoftwareSerial.h. Mais elle est incompatible avec GSM.h. Donc j'en ai trouvé une autre à la place : AltSoftSerial.

Mais ensuite, mon code ne fonctionne pas.

Est-ce que j'essaie comme il faut ? Voici en gros mon code (juste les parties liées à l'initialisation, déclaration, et utilisation de la commande AT) :

#include <GSM.h>
#include <AltSoftSerial.h>

(...)

AltSoftSerial CommandesAT(2,3);

(...)

void Setup(){
    Serial.begin(9600);
    CommandesAT.begin(9600);

    (...)
}

(...)

void SuppressionSMS(){
 CommandesAT.println("AT+CMGDA=");
}

Quelqu'un a une idée de la façon dont on utilise les commandes AT ?


J-M-L : pas de jumper de mon côté...

J-M-L:
:slight_smile:

il y a peut-être même un jumper pour déplacer cela ailleurs - vous avez un lien sur votre shield?

Mmmhh veux-tu dire qu'en fait, pour pouvoir envoyer des commandes AT, je devrais souder quelque chose ?

void SuppressionSMS(){
 CommandesAT.println("AT+CMGDA=\"DEL ALL\"");
}

ou

void SuppressionSMS(){
for (int position=0; position<50; position++){
 CommandesAT.print("AT+CMGD=");
  CommandesAT.print((position); 
  CommandesAT.print("\r");
}
}

lien du shield ou photo de bonne qualité

c'est ce shield?

Merci beaucoup !

Donc à part void SuppressionSMS, le code était bon pour toi ?

Pour le shield :

Et une photo :