Comment résoudre le problème de pile pleine cosé par un DoEvents

Signaler
Messages postés
12
Date d'inscription
lundi 26 mars 2007
Statut
Membre
Dernière intervention
27 juin 2009
-
Messages postés
12
Date d'inscription
lundi 26 mars 2007
Statut
Membre
Dernière intervention
27 juin 2009
-
Bonjour à tous
Faut dire que je suis vraiment coincée
aidez moi s'il vous plaît
J'ai écrit un petit bout de code qui, lorsqu'un message arrive  sur le modem
il affiche  sur un textbox  +CMTI : "MT",
correspond à l'index de chaque nouveau message entrant dans le modem
Mon code recupère cet index à chaque fois qu'un message arrive et doit l'afficher
sur un textbox,  mais c'est là le problème  déja la recupération de l'index  n'est pas stable
en plus quand je lance la commande  ModemGSM.Output="AT+CMGR" & index & chr$(13)
le logiciel m'affiche plusieurs fois cette commande jusqu'a ce que la pile soit pleine
et lorsque je fait le débogage il me met le curseur sur le premier DoEvents dans le code avec la couleur jaune
J'ai mis la propriété multiligne des textbox à True et ajouté un ScrollBars vertical sur chaque textbox
au fait je programme en vb6 voici le code ci-dessous

Private Sub ModemGSM_OnComm()
  With ModemGSM
    If .PortOpen Then .PortOpen = False
    .CommPort = 6
    .Settings = "9600,N,8,1"
    .DTREnable = True
    .RTSEnable = True
    .Handshaking = comNone
    .RThreshold = 1
    .SThreshold = 0
    .InBufferCount = 0
                                   '.OutBufferCount = 0
                                   '.InputLen = 0
    .PortOpen = True
  End With
    

index = ""
Text2.Text = ""
Do
DoEvents
If ModemGSM.CommEvent = comEvReceive Then


ModemGSM.InputLen = 0

If ModemGSM.InBufferCount Then

   InString = ModemGSM.Input

   Text1.Text = Text1.Text & InString

End If
End If


index = Mid$(Text1.Text, InStrRev(Text1.Text, ",") + 1)
 Loop Until InStr(Text1.Text, index)

index = Mid$(Text1.Text, InStrRev(Text1.Text, ",") + 1)
Text2.Text = index
    ModemGSM.Output = "AT+" & "CMGR=" & Text2.Text & Chr$(13)
    
  'à ce niveau je cherche la lettre M,  si je trouve sa position, je la recupère et l'affiche dans Text2.Text  
Do
DoEvents
If ModemGSM.InBufferCount > 0 Then
ModemGSM.InputLen = ModemGSM.InBufferCount
Text1.Text = Text1.Text & ModemGSM.Input
End If
Loop Until InStr(Text1.Text, "OK")
    
   MyPos1 = InStr(Text1.Text, "M")
 
    If MyPos1 <> 0 Then
DM1 = Mid(Text1.Text, MyPos1, 1)
End If
Text2.Text = DM1
End Sub

Merci

9 réponses

Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
78
Salut
Encore avec tes histoires d'index ?
La raison de cette saturation vient de ta boucle Loop-Do (d'ailleurs obsolète) :
Tu fais une boucle tant que la chaine contenue dans Text1 renferme ton index.
Ok, mais à l'intérieur de ta chaine, rien ne modifie Text1
La condition reste donc valable jusqu'à la nuit des temps !
Il faut donc que tu modifies Text1dans cette boucle afin de faire disparaitre l'index que tu viens de traiter
A toi de jongler avec les Mid, Left, Right ...

Apprends à debuguer avec l'arrêt sur instruction F9, l'instruction par instruction F8 et regarder ce que valent tes variables au fur et à mesure en les survolant avec la souris. Tu ne vas pas venir ici à chaque fois que tu alignes 3 lignes !

Rappel : Il faut TOUJOURS mettre un DoEvents à l'INTERIEUR d'une boucle (For, Do, Goto ...) si tu n'es pas sûr de pouvoir en sortir, sinon tu ne pourras même pas demander à VB de stopper le programme !

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
12
Date d'inscription
lundi 26 mars 2007
Statut
Membre
Dernière intervention
27 juin 2009

merci de votre aide


sachez déjà que le bout de code posté n'est qu'une infine partie de l'appication que je developpe


c'est juste à ce niveau que j'ai encore un problème


je vais essayer de suivre vos instructions mais SVP soyez  plus explicite dans vos reponses car je ne suis encore qu'une debutante. 


merci
Messages postés
12
Date d'inscription
lundi 26 mars 2007
Statut
Membre
Dernière intervention
27 juin 2009

J'ai éssayé autrement, et j'ai supprimé index dans la boucle mais
j'ai toujours cette boucle infinie qui sature la pile
je tiens à préciser que le problème se pose uniquement lorsque
j'écris la ligne de commande   ModemGSM.Output = "AT+" & "CMGR=" & Text2.Text & Chr$(13)
Voici le bout de code ci-dessous
SVP proposez des solutions avec des modifications sur ce bout de code 

Do
DoEvents
If ModemGSM.CommEvent = comEvReceive Then


' Retrieve all available data.
ModemGSM.InputLen = 0
  'liste des erreurs possibles
 
  ' Check for data.
If ModemGSM.InBufferCount Then
   ' Read data.
   InString = ModemGSM.Input
   'If Len(InString) > 0 Then
   Text1.Text = Text1.Text & InString
   'End If
End If
End If


                'index = Mid$(Text1.Text, InStrRev(Text1.Text, ",") + 1)
                'Text1.Text = right(Text1.Text, 7)
 
  Loop Until InStr(Text1.Text, ",")


 index = Mid$(Text1.Text, InStrRev(Text1.Text, ",") + 1)
Text2.Text = index
  ModemGSM.Output = "AT+" & "CMGR=" & Text2.Text & Chr$(13)
 
Merci
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
78
Non, je ne corrigerais pas ton code, je ne ferais que t'expliquer pourquoi.
Codes-Sources n'est pas une école, juste un site d'échange; c'est à toi de faire l'effort de comprendre ce que tu écris.

La question que je me pose, c'est pourquoi tu fais une boucle ?
Le composant MSComm déclenche lui même un évènement _OnComm lorsque des données sont disponibles. C'est donc dans cet évènement qu'il faut mettre la partie réception --> Voir l'aide

Actuellement, tu fais une boucle Do-Loop Until en surveillant l'apparition d'une virgule dans le contenu de Text1.
Es-tu sûr que ce soit le bon terme à utiliser pour sortir de ta boucle ?
Reflechis, je ne peux pas le faire à ta place !

Avec le code que tu présentes ici, je ne vois pas pourquoi la pile se saturerait puisque tu ressortis le Output de la boucle ... à moins que le code présenté soit lui même à l'intérieur d'une autre boucle.
Désolé, je ne suis pas Marabou.
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
78
Non, correction :
   Loop Until InStr(Text1.Text, ",")
veut dire que ça va boucler tant qu'il y a une virgule dans Text1.
Or, dans tes lignes, tu ne fais que rajouter du texte à Text1.
Comment veux-tu que ta boucle se termine ?

La programmation, ce n'est pas simplement mettre des instructions les unes derrière les autres, il faut quand même comprendre un minimum ce que tu écris.
Si tu as un doute ou que tu n'es pas sûr du fonctionnement d'une instruction :
-1- Lis l'aide : tout y est expliqué
-2- Crée un nouveau projet pour tester cette instruction

Apprends à débuguer (rappel) : Regarde ce que font les touches F9 et F8.
Apprends à utiliser la fenêtre d'exécution (Ctrl-G) pour visualiser le contenu de tes variables pendant que le programme est suspendu, par exemple :
   ? Text1.Text
Messages postés
12
Date d'inscription
lundi 26 mars 2007
Statut
Membre
Dernière intervention
27 juin 2009

merci encore
je fais une boucle parceque, lorsque je reçois +CMTI: "MT", index


je n'arrive pas à recupérer l'index sans faire de boucle avec:  
index = Mid$(Text1.Text, InStrRev(Text1.Text, ",") + 1)
c'est justement ce que j'ai d'abord fait avant de decider de mettre une boucle, le problème n'est pas l'affichage de +CM...


mais plutot de pouvoir récuperer l'index après l'affichage toujours de +CM.... dans le textbox. ce qui était impossible avant que je ne mette la boucle.


oui je sors effectivement de ma boucle mais c'est uniquement lorsque j'écris :
 ModemGSM.OutPut = "AT+.... que le problème se pose. j'ai pensé, ce que je suis d'ailleurs en train de faire
utiliser un timer pour l'exécution de la commande AT.
merci
Messages postés
12
Date d'inscription
lundi 26 mars 2007
Statut
Membre
Dernière intervention
27 juin 2009

ok
je continu à bosser

merci
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
78
Je pense qu'il faudrait que tu découpes les actions que tu as faire :
Tu y gagnerais en clarté, car là, on ne sait jamais si tu parles du contenu ou de la méthode

- Recevoir les données, en plusieurs fois
Comme je te le suggèrais fortement : laisse faire l'évènement OnComm.
A chaque fois qu'il se déclenche et que le déclenchement est dû à l'arrivée de données, tu stockes les données reçues dans un buffer déclaré dans la partie "déclaration" de ta forme/module, comme ça, la variable ne perdra pas sa valeur entre deux déclenchements de l'évènement.
Une fois que ça sera au point, tu pourras poursuivre.

- Regarder si, dans la chaine reçue, tu obtiens les infos nécessaires
Relire cycliquement (avec un Timer par exemple) le contenu de ton buffer.
Après utilisation de la donnée, tu la supprimes du buffer.

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

<hr />Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
12
Date d'inscription
lundi 26 mars 2007
Statut
Membre
Dernière intervention
27 juin 2009

bonsoir,
j'ai utilisé un timer comme je vous l'avais dit la dernière fois et maintenant mon code fonctionne

merci