Bonjour à tous,

J'ai un problème de démarrage de Timer. Je pensais avoir résolu mon problème avec ce que j'ai posté ici mais finalement, non.

J'obtiens l'erreur suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
Error while evaluating TimerFcn for timer 'timer-5' 
 
Attempt to reference field of non-structure array.
Dans ma fonction principale, je déclare les timers suivants :
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
%% Periode des Timers
% graphique
per_graph = 1;
% save acc
per_acc = 0.5;                 
% save data acc
per_data_acc = 30;
 
%% pour mettre à jour le graphique
guit.timer_graph = timer(...
    'ExecutionMode', 'fixedRate', ...       % Run timer repeatedly
    'Period', per_graph, ...                % Initial period is per_graph sec.
    'TimerFcn', @Update_Display);           % Specify callback function
 
%% declaration du timer pour acquerir les donnees de l'accelero
guit.timer_acc = timer(...
    'ExecutionMode', 'fixedRate', ...       % Run timer repeatedly
    'Period', per_acc, ...                  % Initial period is per_acc sec.
    'TimerFcn', @Acq_Acc);                 % Specify callback function
 
%% declaration du timer pour enregistrer les donnees de l'accelero de manière automatique
guit.timer_auto_save_acc = timer(...
    'ExecutionMode', 'fixedRate', ...       % Run timer repeatedly
    'Period', per_data_acc, ...             % Initial period is per_data_acc sec.
    'TimerFcn', @Auto_Save_Data_Acc);       % Specify callback function
 
%% declaration du timer pour connaitre le temps restant
guit.timer_tps_restant=timer(...
    'ExecutionMode', 'fixedRate', ...       % Run timer repeatedly
    'Period', 1, ...                        % Initial period is 1 sec.
    'TimerFcn', @Tps_Restant);              % Specify callback function
Puis, dans une fonction imbriquée, je veux démarrer/arrêter deux de ces timers suite à l'action sur un togglebutton. D'un point de vue théorique, je devrais faire juste ceci :

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
function Acc_Data(obj,event)
        if strcmp(get(gui.acc_data,'String'),'DATA ACCELERO')               % si il est affiche "DATA ACCELERO" sur l'interrupteur 
            % on met a jour l'interface
            set(gui.acc_data,'String','ACQUISITION');                       % on change le nom inscrit sur l'interrupteur pour indiquer l'acquistion
            % on déclenche les timers
            start(guit.timer_graph);                                         % on lance le timer pour raffraichir les graphiques
            start(guit.timer_acc);                                           % on lance le timer pour aller lire les donnes de le buffer du port serie
        else
            % on met à jour l'interface
            set(gui.acc_data,'String','DATA ACCELERO');                     % on change le nom inscrit sur l'interrupteur pour indiquer son etat de repos
            % on arrete les timers
            stop(guit.timer_graph);                                          % on arrete le timer lie au graphique
            stop(guit.timer_acc);                                            % on arrete le timer lie a la lecture du buffer du port serie
        end
    end
Or, ça ne déclenche qu'un des timers sur les deux. Alors, j'ai fait du bricolage comme ceci dans cette fonction :
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
      function Acc_Data(obj,event)
        guit=getappdata(hgui,'handguit');
        if strcmp(get(gui.acc_data,'String'),'DATA ACCELERO')               % si il est affiche "DATA ACCELERO" sur l'interrupteur 
            % on met a jour l'interface
            set(gui.acc_data,'String','ACQUISITION');                       % on change le nom inscrit sur l'interrupteur pour indiquer l'acquistion
            % on déclenche les timers
            start(guit.timer_graph);                                        % on lance le timer pour raffraichir les graphiques
            % on s'assure que les timers sont lancés
            if strcmp(get(guit.timer_graph,'Running'),'off')                % si le timer n'est pas lance
                delete(guit.timer_graph)                                    % on efface le handle du timer
                guit.timer_graph = timer(...                                % on le redefinit
                    'ExecutionMode', 'fixedRate', ...
                    'Period', per_graph, ...         
                    'TimerFcn', @Update_Display);    
                start(guit.timer_graph);                                    % on le relance
            end
            start(guit.timer_acc);                                          % on lance le timer pour aller lire les donnes de le buffer du port serie
            if strcmp(get(guit.timer_acc,'Running'),'off')                  % si le timer n'est pas lance
                delete(guit.timer_acc)                                      % on efface le handle du timer
                guit.timer_acc = timer(...                                  % on le redefinit
                    'ExecutionMode', 'fixedRate', ...     
                    'Period', per_acc, ...                
                    'TimerFcn', @Acq_Acc);                
                start(guit.timer_acc);                                      % on le relance
            end
        else
            % on met à jour l'interface
            set(gui.acc_data,'String','DATA ACCELERO');                     % on change le nom inscrit sur l'interrupteur pour indiquer son etat de repos
            % on arrete les timers
            stop(guit.timer_graph);                                         % on arrete le timer lie au graphique
            stop(guit.timer_acc);                                           % on arrete le timer lie a la lecture du buffer du port serie
            %on s'assure que les timers sont bien stopes
            while strcmp(get(guit.timer_acc,'Running'),'on')                % tant que le timer n'est pas arrete alors
                stop(guit.timer_acc);                                       %   on lui demande de stopper
            end
            while strcmp(get(guit.timer_graph,'Running'),'on')              % idem pour le deuxieme timer
                stop(guit.timer_graph);                                     %   on lui demande de stopper
            end
        end
    end
Ca ne suffit toujours pas...

Alors, au début de chaque fonction callback de chaque timer, je lui redemande de lancer son "frère" :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
if strcmp(get(guit.timer_acc,'Running'),'off')                  % si le timer n'est pas lance
     delete(guit.timer_acc)                                      % on efface le handle du timer
    guit.timer_acc = timer(...                                  % on le redefinit
        'ExecutionMode', 'fixedRate', ...     
        'Period', per_acc, ...                
        'TimerFcn', @Acq_Acc);                
    start(guit.timer_acc);                                      % on le relance
end
Et là, de manière ambiguë, il arrive au bout de quelques secondes à me lancer le "frère" qui ne s'était pas lancé jusqu'à maintenant.

Sans la communication avec le port série, je n'ai pas rencontré ce problème.
Je me demande si je ne devrais pas lancer les timers avant de me connecter au port série pour m'assurer de leur lancement...

Ca semblait si joli de faire du timer plutôt que des "while", "tic" et "toc"...

Si vous avez des propositions, je suis preneur.

Cordialement,

Christophe