Таймер MATLAB действует в функции иначе, чем в командном окне - PullRequest
0 голосов
/ 08 января 2019

У меня есть код, который выполняет измерения от внешнего устройства, и я хочу проводить измерения в течение определенного периода времени. Мне нужно записать измерения вместе с отметками времени, поэтому я собрал цикл while для запуска во время выполнения таймера с условием выхода из цикла, когда таймер достигнет нуля.

Переменная «meter» является дескриптором внешнего устройства, и разговаривать с ним не проблема.

Проблема в том, что цикл while никогда не завершается, когда код выполняется внутри функции, даже если "Finished!" Метод успешно отображает. Код работает нормально, если я запускаю его один в командном окне, и в коде нет других экземпляров таймеров, поэтому я понятия не имею, почему происходит такое другое поведение. Я бы использовал паузу, чтобы следить за временем, но я хочу снять как можно больше показаний в течение 10 секунд, чтобы он просто не летал.

fprintf('\nCollecting 10 s data from detector...');
i = 1;
t1 = timer('TimerFcn','stat=false; fprintf(''\nFinished!'')','StartDelay',10);
start(t1);
stat = true;
while(stat==true)
    Timestamps{i} = datetime('now');
    fprintf(meter,':READ?');
    Current(i) = str2num(fscanf(meter));
    i = i + 1;
end

Любые мысли о том, почему это может вести себя по-разному, когда внутри функции?

1 Ответ

0 голосов
/ 08 января 2019

Ваша проблема связана с переменной областью видимости . Когда ваш код запускается в функции, переменная stat существует в локальной рабочей области этих функций, а не в базовой рабочей области (то есть рабочей области командного окна). Когда вы предоставляете функцию обратного вызова строки для функции таймера, код в этой строке выполняется в базовой рабочей области. Поэтому, когда ваш таймер срабатывает, он печатает сообщение и изменяет переменную stat в базовой рабочей области, но переменная stat в рабочей области локальной функции не изменяется.

Я предпочитаю справиться с этим, чтобы создать вложенную функцию для обратного вызова таймера, вложенную в вашу большую функцию, содержащую цикл. Например:

function Current = collect_data(meter)

  fprintf('\nCollecting 10 s data from detector...');
  i = 1;
  t1 = timer('TimerFcn', @timer_callback, 'StartDelay', 10);
  start(t1);
  stat = true;

  while (stat == true)
    Timestamps{i} = datetime('now');
    fprintf(meter, ':READ?');
    Current(i) = str2num(fscanf(meter));
    i = i + 1;
  end

  function timer_callback(~, ~)
    stat = false;
    fprintf('\nFinished!');
  end

end

В этом случае переменная stat совместно используется функциями collect_data и timer_callback, и цикл завершается, как и ожидалось, когда срабатывает таймер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...