Synchronisation affichage dans une boucle pendant acquisition

Signaler
Messages postés
6
Date d'inscription
lundi 15 mars 2010
Statut
Membre
Dernière intervention
18 mars 2010
-
Messages postés
14757
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
14 janvier 2021
-
Bonjour a tous,
je suis entrain de faire un programme qui va acquérir des données (une par seconde) a partir d'une interface gpib et ensuite me les afficher sur un graphe, dans des textbox et dans un fichier.
Je rencontre des problemes dans l'affichage dans les textbox. Seule la valeur finale s'affiche a la fin de l'acquisition alors que le graphe s'actualise en temps reel(un point par seconde) et le fichier probablement fait de meme (la version finale du fichier est bonne). Dans l'une des text box, je voudrais faire apparaitre la "yvalue" du graphe, dans une autre textbox la "xvalue" et dans une autre le temps depuis le debut de l'acquisition.
Je pense que mon probleme a un rapport avec la synchronisation et le multi threading, mais, je n'y connais rien (je lance une piste?).
Y aurait-il une bonne ame sur ce forum qui pourrait me sortir de ce probleme? Jusqu'a present, j'avais aussi des problemes de "program not responding" qui gelait l'affichage de la courbe mais enregistrait bien les points. J'ai resolu le probleme en me debattant pour liberer de la memoire (variable="").

Merci enormement a tous ceux qui m'apporteront une aide.

Public filenameee As String
Public duree, biasvoltage, steptime As Single
Public gpib0%
Public BDNAME As String
Public Keithley487%
Public keith487ValueStr As String * 1024
Public keith487DisplayStr As String
Public cmd1 As String
Public cmd2 As String
Public cnt,tempo As Single
Public ncycle As Integer
Public yvalue As Single


Private Sub Command2_Click()

 tempo = 0
 cnt = 0 

Timer1.Enabled = True
Timer1.Interval = 1000

Label1.Enabled = True
Label2.Enabled = True
Label3.Enabled = True

''''''''''contact avec l'interface gpib''''''''''''''''
    BDNAME = "GPIB0" 
    Call ibfind(BDNAME, gpib0%)
    Call ibclr(gpib0%)
    If gpib0% < 0 Then
        Print "Error"
        End
    End If
    BDNAME = ""

''''''''''''''''contact par gpib avec un Keithley487 (noté K487 apres)''''''''''' 
    BDNAME = "DEV8"
        cmd1 = "Y0W1S1K0F0P0G1C0B0T0R0X"
        
        Call ibfind(BDNAME, Keithley487%)
        If Keithley487% < 0 Then
            Print "Error"
            End
        End If
        Call ibclr(Keithley487%)
        If ibsta% < 0 Then
            Print "Status Error"
        End If
        Call ibwrt(Keithley487%, cmd1) 

''''''''''''''ouvrir le fichier et parler avec le K487''''''''''''''
 Open filenameee For Output As #1 
        
            Call ibwrt(Keithley487%, "V" & Str$(biasvoltage) & ",0,1O1X")


'''''''''''''gestion des parametres du graphe''''''''''''''''''''''
            Graph1.BottomTitle = "time (sec)"
            Graph1.LeftTitle = "I(A)"
             Graph1.GraphType = gphScatter
                Graph1.GraphStyle = 0
                Graph1.NumPoints = 2
               Graph1.ThisPoint = 1
                Graph1.XPosData = 0
                Graph1.GraphData = 0
                Graph1.DrawMode = 2
                Graph1.ThisPoint = 2
                Graph1.XPosData = 0
                Graph1.GraphData = 0
                Graph1.DrawMode = 2
               
            
'''''''''''''''''''la boucle d'acquisition de données'''''''''''''''''''''''''''

            ncycle = 0
            For cnt = 0 To duree Step steptime
                ncycle = ncycle + 1
                Call ibwrt(Keithley487%, "V" & Str$(biasvoltage) & ",0,1X")
                Sleep (steptime * 1000)  ''''''''attendre une seconde entre chaque mesure
                ilrd Keithley487%, keith487ValueStr$, Len(keith487ValueStr$) 
                yvalue = Val(keith487ValueStr)
                
''''''''''''''''''''affichage dans label 1, 2 et 3 '''''''''''''''''''''
                Label1.Caption = Trim(Str$(yvalue))
                Label2.Caption = Trim(Str$(cnt))
                Label3.Caption = tempo & " sec"

'''''''''''''''enregistrement dans fichier'''''''''''''''''''''''''''''''
                Write #1, cnt, yvalue
            
            
''''''''''''''traçage du graphe'''''''''''''''''''''''''''
                   
                Graph1.NumPoints = ncycle + 2
                Graph1.ThisPoint = ncycle + 2
                Graph1.XPosData = cnt
                Graph1.GraphData = yvalue
                Graph1.DrawMode = 2
    
                keith487ValueStr = ""
    
            Next
 ''''''''''''''apres la boucle je ferme le fichier et reinitialise mon K487''''''''''''''''       
            Close #1
            Call ibwrt(Keithley487%, "V0,0,0L0O0X")
            frmgraphjt.Caption = "Done!"
            Timer1.Enabled = False
End Sub
'''''''''''''''''''''''la main sub'''''''''''''''''''''
Private Sub Form_Load()
Timer1.Enabled = False
End Sub

'''''''''''''''''''''''''''''le timer'''''''''''''''''''''''''''''''''

Private Sub Timer1_Timer()
tempo=tempo + 1
End Sub

9 réponses

Messages postés
14757
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
14 janvier 2021
151
Bonjour,

Pour synchroniser l'affichage, tu peux utiliser la fonction : Doevents

Sinon pour la déclaration :
Public duree, biasvoltage, steptime As Single
duree et biasvoltage sont des Variant, voici la bonne déclaration :
Public duree As Single, biasvoltage As Single, steptime As Single

De base évite ce genre d'écriture, c'est moins lisible.

Mon site
Messages postés
6
Date d'inscription
lundi 15 mars 2010
Statut
Membre
Dernière intervention
18 mars 2010

Cool, merci infiniment Henry, ca marche tres bien maintenant et j'ai appris quelquechose.
Messages postés
6
Date d'inscription
lundi 15 mars 2010
Statut
Membre
Dernière intervention
18 mars 2010

Hum, apparemment, mon probleme n'est pas tout a fait resolu..

Le Label3 est censé afficher le temps absolu en seconde depuis le debut de l'acquisition (pour le comparer ensuite au temps supposé de l'acquisition (appelé cnt dans mon programme) en fonction du steptime).
La realité est differente. Le label3 m'affiche le numero du pas de la boucle(en gros, c'est comme si le timer interval n'est pas de 1 sec mais de la durée d'une boucle ( 1 correspond a 1 boucle, 2 a 2 boucles, etc.)). Ca m'embete parce que j'ai l'impression que je dois faire appel a un autre programme (genre ouvrir un chronometre) pour avoir la mesure absolue du temps.

Pouvez-vous m'aider de nouveau? Je n'arrive pas a comprendre ou se trouve le probleme..J'ai mis des DoEvents un peu partout pour tester si quelquechose ne se faisait pas mais je n'ai rien trouvé.
Messages postés
6
Date d'inscription
lundi 15 mars 2010
Statut
Membre
Dernière intervention
18 mars 2010

ok, je vais meme etre encore plus precis.

Le temps dans mon programme est donné par un timer (nommé timer1) qui a pour effet d'augmenter la variable "tempo" de 1 a chaque 1000msec.
Apres qqs tests, j'ai remarqué que tempo augmentait de 1 a chaque cycle de la boucle for jusqu'a la fin de la boucle puis tempo augmentait normalement (donc 1 chaque 1000msec) quand la boucle etait terminée.

La encore les DoEvents ne font rien quand ils sont placés dans la sub du timer ou encore dans la sub de la command2. Je ne comprends pas pourquoi. C'est la tout mon probleme. Encore merci pour toute l'aide que vous pourrez m'apporter.
Messages postés
14757
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
14 janvier 2021
151
Bonjour,

Pour les durées, préfère Timer (secondes passées depuis minuit) ou TickCount (API, nombre de millisecondes passées depuis le démarrage du PC).

Mon site
Messages postés
6
Date d'inscription
lundi 15 mars 2010
Statut
Membre
Dernière intervention
18 mars 2010

Bonjour et merci pour le conseil et l'info. Mais dans le cas present, tu as une idée de la raison pour laquelle timer ne joue pas son role dans mon programme? Est ce le script qui n'est vraiment pas optimisé ou est ce l'acquisition qui ralentit la machine ou est ce un petit detail que j'aurai oublié? Est ce que j'ai un moyen de savoir ce que ca pourrait etre (par exemple, avec des msgbox ou autre)?

Pour résumer mon probleme: pendant la boucle for, j'observe un timer.interval du temps d'une boucle et quand la boucle se termine le timer.interval est de nouveau 1000msec (ce que je veux). Ce n'est pas normal.
Pour donner un exemple, mon compteur de temps(la variable tempo dans timer1) s'incremente de un toutes les (steptime*1000)msec pendant la boucle et de 1000msec apres. Pourquoi?

Merci encore de toute votre aide.
Messages postés
14757
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
14 janvier 2021
151
Bonjour,

Le timer ne peut pas s'enclencher toutes les 1000 ms précisément, car :
- Il s'agit un évènement Windows, donc il peut être décalé par le simple fait du changement entre processus (environ 15ms)
- Si ton programme ne relâche par la main (DoEvents) suffisamment souvent (et si ton programme relâche la main à 950 ms, le timer ne s'enclenchera que lors de la prochaine libération)

De fait, utiliser un contrôle timer pour compter le temps est une méthode à proscrire.

Note :
Sleep
fait une pause dans l'exécution du programme mais ne rend pas la main pour gérer les évènements (comme le Tick du timer).

D'autre part concernant ton codage :
- Limiter la porté des variables, car tu déclare toutes tes variables en globale, essaye de réduire au max leur visibilité (en les déclarant dans la fonction qui les utilises si elle ne sont utilisées que dans cette fonction)
- Les utilisations de Call peuvent être retirées (plus de clarté du code) :
Call ibfind(BDNAME, gpib0%)
devient
ibfind BDNAME, gpib0%
(retrait du Call et des ( ) )
- Pourquoi forcer le type des variables ( gpib0% )?
Si tu veux passer des paramètres, dans la mesure du possible, passe-les en ByVal et pas en ByRef.

Mon site
Messages postés
6
Date d'inscription
lundi 15 mars 2010
Statut
Membre
Dernière intervention
18 mars 2010

Merci bcp pour ta reponse!

J'ai appris bcp et ca devrait m'aider a m'en sortir..la, j'ai juste un probleme avec l'interface gpib (qqn a touché a qqc sans me le dire et j'ai une erreur qui apparait avec ibclr) qui m'empeche de tester mon programme.
Mais, dans qqs jours, mon probleme sera resolu(j'espere) et je pourrai dire enfin si tout marche pour le mieux!

a+ et encore merci
Messages postés
14757
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
14 janvier 2021
151
Bonjour,

Ne sachant pas ce qu'est cette interface, je ne peux pas t'aider, désolé.

Mais peut être avec un peu de debug tu y arrivera :)

Bonne chance .

Mon site