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 :
Dans ma fonction principale, je déclare les timers suivants :
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.
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
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
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 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
Ca ne suffit toujours pas...
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
Alors, au début de chaque fonction callback de chaque timer, je lui redemande de lancer son "frère" :
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.
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
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
Partager