IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MATLAB Discussion :

Timer indépendant ? [Débutant]


Sujet :

MATLAB

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 22
    Points
    22
    Par défaut Timer indépendant ?
    Bonjour à tous,

    J'ai actuellement un programme Matlab (GUI) qui pilote un autre programme (Labview), en boucle.

    Je souhaite créer une horloge qui affiche dans mon GUI le temps écoulé entre le moment où j'appuie sur un pushbutton de mon GUI et le moment où le programme s'arrête.

    J'ai créé une variable "counter" si s'incrémente dans ma boucle while. Le problème est que dans cette fameuse boucle j'ai d'autres boucles while imbriquées et même des temporisations (commande 'pause').

    Du coup, et ben mon compteur ne marche pas comme je le souhaiterais.

    Ma question est donc la suivante : comment créer un compteur qui soit indépendant de ma boucle while, qui démarre avec l'appui sur mon pushbutton et qui s'arrête sur condition ??

    Merci d'avance pour vos idées.

  2. #2
    Membre éclairé Avatar de tubaas
    Homme Profil pro
    Acousticien
    Inscrit en
    Août 2009
    Messages
    641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Acousticien
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2009
    Messages : 641
    Points : 825
    Points
    825
    Par défaut
    Bonjour,
    as-tu essayé de créer un objet timer et de l'adapter à ton utilisation ?

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 22
    Points
    22
    Par défaut
    Bonjour tubaas,

    En effet j'ai pensé à l'objet timer mais j'avoue ne pas encore bien comprendre son utilisation. J'y travaille....

  4. #4
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 22
    Points
    22
    Par défaut
    Alors, j'ai réussi à créer un objet timer et à le lancer.

    Le problème concerne le rafraîchissement du handles (edit text) dans le GUI qui affiche le compteur.

    En effet, le compteur fonctionne correctement mais dès que j'entre dans une boucle, le handles se bloque (valeur reste figée).

    Dès que je sors de ma boucle, le compteur reprend à la bonne valeur...

    Je précise que mon programme contient plein de boucles imbriquées, avec des uiwait en plus...

    Alors soit le timer ne me permet pas de faire ce que je veux, soit mon "set(handles.edit_box,'String',compteur)" n'est pas situé au bon endroit...

  5. #5
    Membre éclairé Avatar de tubaas
    Homme Profil pro
    Acousticien
    Inscrit en
    Août 2009
    Messages
    641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Acousticien
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2009
    Messages : 641
    Points : 825
    Points
    825
    Par défaut
    salut
    sans voir ton code, difficile de t'aider plus. Cependant tu dis que tu as beaucoup d'uiwait... le problème peut venir de là.
    Une idée de solution : créer une figure séparée avec uniquement le compteur et (que tu synchronises avec ta figure principale) et son affichage.

  6. #6
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 22
    Points
    22
    Par défaut
    Salut, j'avais en effet songé à cette solution mais plutôt en créant un exécutable pour mon timer. Exécutable qui serait appelé par le GUI principal...

    Mais je pense que ta solution est meilleure...

  7. #7
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 22
    Points
    22
    Par défaut
    Bonjour, je reviens à la charge concernant l'utilisation d'un timer.

    En fait je ne suis pas certain de bien comprendre son fonctionnement.

    J'ai réalisé une petite interface qui lance l'acquisition de mesures par appui sur un bouton et qui stoppe l'acquisition par appui sur un autre.

    J'aimerais le faire avec un timer.

    Dans mon opening fonction je définis mon timer de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    % Create timer object for data acquisition
    handles.monitoring_timer = timer( ...
        'TimerFcn',         'acquisition_des_donnees', ...
        'Period',           0.01, ...
        'ExecutionMode',    'fixedDelay');
    Et la fonction réalisant l'acquisition appelée 'aquisition_des_données' :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    function acquisition_des_donnees
    AI_01 = DAQmxReadAnalogF64(lib,taskh.AI_01,numSampsPerChan,timeout,fillMode,numchan,numsample);
    Bon je ne vous ai mis ici q'une partie de la fonction. Mais en gros la commande 'DAQmxReadAnalogF64' permet de faire l'acquisition d'une mesure analogique à partir d'une carte National Instruments.

    le callback du pushbutton start :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    % --- Executes on button press in start_acquisition.
    function start_acquisition_Callback(hObject, eventdata, handles)
     
    start(handles.monitoring_timer);
    et le callback du pushbutton stop :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    % --- Executes on button press in stop_acquisition.
    function stop_acquisition_Callback(hObject, eventdata, handles)
     
    stop(handles.monitoring_timer)
    delete(handles.monitoring_timer)
    Et voici l'erreur que j'obtiens lors d'un appui sur START :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ??? Error while evaluating TimerFcn for timer 'timer-15' 
     
    Undefined function or variable 'acquisition_des_donnees'.
    Je pense que mon utilisation du timer n'est pas bonne...

    Pourriez-vous m'éclairer ?

  8. #8
    Invité
    Invité(e)
    Par défaut
    L'un des inconvénients d'avoir un callback sous forme de string...
    acquisition_des_donnees étant une sous-fonction, elle n'est pas accessible extérieurement, or un callback défini de cette manière s'exécute dans le workspace de base : il n'a donc pas accès à cette fonction.

    Un peu de lecture.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 22
    Points
    22
    Par défaut
    Merci Winjerome,

    J'ai modifié mon code en conséquence. Pour le timer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    % Create timer object for data acquisition
    handles.monitoring_timer = timer( ...
        'TimerFcn',         @acquisition_des_donnees, ...
        'Period',           0.01, ...
        'ExecutionMode',    'fixedDelay');
    Et pour la fonction appelée par le timer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    function acquisition_des_donnees(hObject, eventdata)
     
    taskh.AI_00 = getappdata(handles.figure1, 'taskh.AI_00');
    taskh.AI_01 = getappdata(handles.figure1, 'taskh.AI_01');
    lib = getappdata(handles.figure1, 'lib');
    numSampsPerChan = getappdata(handles.figure1, 'numSampsPerChan');
    timeout = getappdata(handles.figure1, 'timeout');
    fillMode = getappdata(handles.figure1, 'fillMode');
    numchan = getappdata(handles.figure1, 'numchan');
    numsample = getappdata(handles.figure1, 'numsample');
    v = getappdata(handles.figure1, 'v');        % A mettre à jour
    Pe0 = getappdata(handles.figure1, 'Pe0');    % A mettre à jour
    Xe0 = getappdata(handles.figure1, 'Xe0');    % A mettre à jour
    A = getappdata(handles.figure1, 'A');
    B = getappdata(handles.figure1, 'B');
    C = getappdata(handles.figure1, 'C');
    Q = getappdata(handles.figure1, 'Q');
    R = getappdata(handles.figure1, 'R');
    Te = getappdata(handles.figure1, 'Te');
    Rate = getappdata(handles.figure1, 'Rate');
    alarm = getappdata(handles.figure1, 'alarm');
    i = getappdata(handles.figure1, 'i');
     
    AI_00(i) = DAQmxReadAnalogF64(lib,taskh.AI_00,numSampsPerChan,timeout,fillMode,numchan,numsample);
    AI_01 = DAQmxReadAnalogF64(lib,taskh.AI_01,numSampsPerChan,timeout,fillMode,numchan,numsample);
    consigne = ceil((AI_01*200)/10);   % Récupération de la consigne en pression
    v(i) = (AI_00(i)*3000)/9.8;    % A mettre à jour
    setappdata(handles.figure1, 'v', v(i));
    M = -9.31017e-11*consigne^6+6.00593e-8*consigne^5-1.5198e-5*consigne^4+0.0019509*consigne^3-0.13374218*consigne^2+8.646759932*consigne+21.08686454;
    [Peqh(i),Xeqh(i),Yeqh(i),Veqh(i),flag(i)] = KF(Pe0,Xe0,v(i),A,B,C,Q,R,Te,Rate,M,alarm,15);
    Pe0 = Peqh(i);    % Mise en mémoire de la covariance pour le pas suivant
    Xe0 = Xeqh(i);    % Mise en mémoire de l'état estimé pour le pas suivant
    i = i + 1;
    % Mise à jour des sorties du filtre
    setappdata(handles.figure1, 'Yeqh', Yeqh(i));
    setappdata(handles.figure1, 'Peqh', Peqh(i));
    setappdata(handles.figure1, 'Veqh', Veqh(i));
    setappdata(handles.figure1, 'Xeqh', Xeqh(i));
    setappdata(handles.figure1, 'flag', flag(i));
    setappdata(handles.figure1, 'Pe0', Pe0);
    setappdata(handles.figure1, 'Xe0', Xe0);
    setappdata(handles.figure1, 'i', i);
    Cette fois, j'ai mis tout le code de ma fonction.

    Et voici le nouveau message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ??? Error while evaluating TimerFcn for timer 'timer-2' 
     
    Undefined variable "handles" or class "handles.figure1".
    Où 'figure1' est le tag associé à mon GUI.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Et c'est bien normal... tu as vu ta fonction ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function acquisition_des_donnees(hObject, eventdata)
    Pas de variable handles passée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    % Create timer object for data acquisition
    handles.monitoring_timer = timer( ...
        'TimerFcn',         {@acquisition_des_donnees handles}, ...
        'Period',           0.01, ...
        'ExecutionMode',    'fixedDelay');
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function acquisition_des_donnees(hObject, eventdata, handles)

  11. #11
    Membre éclairé Avatar de tubaas
    Homme Profil pro
    Acousticien
    Inscrit en
    Août 2009
    Messages
    641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Acousticien
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2009
    Messages : 641
    Points : 825
    Points
    825
    Par défaut
    salut
    une fois n'est pas coutume, je n'utiliserai pas la solution de Winjerome :
    si tu passes handles de cette façon je ne suis pas sûr que le handles que tu passes contienne handles.monitoring_timer et tu dois bien faire attention à déclarer tout les handles nécessaires AVANT de déclarer ton timer.

    Donc comme handles s'utilise généralement avec guidata :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    guidata(hfig, handles);
     
    function acquisition_des_donnees(hObject, eventdata)
    handles = guidata(gcbf);
    Un test pour montrer ce que je dis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function test
    hf=figure;
    handles.a=0;
    handles.gpb=uicontrol('parent',hf,'style','pushbutton','callback',{@test_int handles});
     
    function test_int(hObject, eventdata, handles)
    handles.a
    handles.gpb
    donnera avec ma version de Matlab lors du clic sur le pushbutton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ans =
     
         0
     
    ??? Reference to non-existent field 'gpb'.
     
    ??? Error while evaluating uicontrol Callback.
    Edit : (et c'est plus propre de stocker les choses à UN endroit et d'y accéder pour lecture/modification avec d'infinies précautions)

  12. #12
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par tubaas Voir le message
    si tu passes handles de cette façon je ne suis pas sûr que le handles que tu passes contienne handles.monitoring_timer
    C'est en effet le cas, mais tu as hObject sous la main

  13. #13
    Membre éclairé Avatar de tubaas
    Homme Profil pro
    Acousticien
    Inscrit en
    Août 2009
    Messages
    641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Acousticien
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2009
    Messages : 641
    Points : 825
    Points
    825
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    C'est en effet le cas, mais tu as hObject sous la main
    Tu as raison.

    Voir cependant mon édition de mon précédent message. Le handles que tu passes en argument ne correspond en fait à rien et à un moment tu ne sauras plus ce que c'est et le confondra avec autre chose (j'ai programmé comme ça à mes débuts), sans compter que ça enlève beaucoup de lisibilité à ton code pour un développeur autre.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Tout dépend en effet de l'endroit où est créé ce timer, de ce que contient la variable handles à ce moment, et des éventuelles modifications qui auront lieu, car ces changements ne seront pas répercutés.

    Il faut faire attention que c'est le callback TimerFcn d'un objet timer dont il est question ici, et non d'un objet enfant d'un objet Figure : gcbf renverra donc [].

    À savoir qu'ici nico974_0 ne l'utilise qu'en tant que handles.figure1, avec de fortes suppositions que cet objet aura peu de chance d'être changé et est déjà créé, on pourra faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    % Create timer object for data acquisition
    handles.monitoring_timer = timer( ...
        'TimerFcn',         {@acquisition_des_donnees handles.figure1}, ...
        'Period',           0.01, ...
        'ExecutionMode',    'fixedDelay');
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function acquisition_des_donnees(hObject, eventdata, handleFigure)
    et remplacer tous les handles.figure1 par handleFigure pour alléger la chose.

  15. #15
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 39
    Points : 22
    Points
    22
    Par défaut
    Merci à tous pour votre aide.

    J'ai effectivement remplacé le code du timer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    % Create timer object for data acquisition
    handles.monitoring_timer = timer( ...
        'TimerFcn',         {@acquisition_des_donnees handles}, ...
        'Period',           0.01, ...
        'ExecutionMode',    'fixedDelay');
    et celui de la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function acquisition_des_donnees(hObject, eventdata, handles)
    Et ça fonctionne. Enfin, j'ai d'autres erreurs mais qui sont liées à mon code...

    Je vais revoir tout ça.

  16. #16
    Membre éclairé Avatar de tubaas
    Homme Profil pro
    Acousticien
    Inscrit en
    Août 2009
    Messages
    641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Acousticien
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2009
    Messages : 641
    Points : 825
    Points
    825
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    À savoir qu'ici nico974_0 ne l'utilise qu'en tant que handles.figure1, avec de fortes suppositions que cet objet aura peu de chance d'être changé et est déjà créé, on pourra faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    % Create timer object for data acquisition
    handles.monitoring_timer = timer( ...
        'TimerFcn',         {@acquisition_des_donnees handles.figure1}, ...
        'Period',           0.01, ...
        'ExecutionMode',    'fixedDelay');
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function acquisition_des_donnees(hObject, eventdata, handleFigure)
    et remplacer tous les handles.figure1 par handleFigure pour alléger la chose.
    Je préfère de très loin cette solution (qui permet en outre si besoin de faire un petit guidata ). Ici la variable handleFigure contiendra bien ce que son nom semble indiquer.
    Une autre consiste à stocker systématiquement les handles de ses figures avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setappdata(0, 'HFIG', hfig);
    . Ainsi le handle est accessible depuis n'importe quelle fonction, dans n'importe quelle figure et même dans la fenêtre de commande ce qui peut avoir ses avantages lors de tests.
    Le choix entre les deux solutions n'est qu'une question de goût et d'habitude

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Timer à la µs indépendant de Windows
    Par haricot75 dans le forum C
    Réponses: 3
    Dernier message: 16/03/2006, 15h32
  2. Timer de précision
    Par guigui dans le forum MFC
    Réponses: 1
    Dernier message: 04/12/2002, 15h21
  3. Timer en µsecondes
    Par Dagobert dans le forum x86 16-bits
    Réponses: 3
    Dernier message: 25/11/2002, 00h59
  4. [Migratation] Application portable, indépendant du SGDB
    Par benouille dans le forum Décisions SGBD
    Réponses: 6
    Dernier message: 28/08/2002, 13h51
  5. Cherche composant Web Browser indépendant
    Par lancelot69 dans le forum Composants VCL
    Réponses: 2
    Dernier message: 31/07/2002, 11h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo