Struct contents reference from a non-struct array object.

2 vues (au cours des 30 derniers jours)
Noah Acosta
Noah Acosta le 4 Jan 2018
Commenté : Noah Acosta le 5 Jan 2018
I am trying to control a microfluidic syringe pump. I want to create a timer to stop the liquid extrusion after it starts. Here is part of my code in which I am getting errors. I have more code, which I could provide if this isn't enough
% Create Timer to STOP flow after it has started
CONSTANT.color = 'cygm';
CONSTANT.channel = 1;
CONSTANT.serial = 1123;
CONSTANT.command = 1;
CONSTANT.test_channel = 1;
sample_period = 5; %5 was chosen arbitrarily for testing purposes; may need to be chaged
timer_period = sample_period / length(CONSTANT.channel);
timer_period = timer_period + mod(timer_period, 0.001);
CONSTANT.timer1 = timer('ExecutionMode','fixedRate',...
'Period',timer_period,...
'TimerFcn',{@timer_update_fcn},...
'StartDelay',0,...
'StartFcn', {@timer_start_fcn}, ...
'StopFcn', {@timer_stop_fcn},...
'BusyMode','drop');
% 'BusyMode','error',...
% 'ErrorFcn',{@timer_error_fcn});
The line that states:
'TimerFcn',{@timer_update_fcn},...
is calling a function script I have which has code ( i also have more code of this but am only posting up to where i get errors):
function timer_update_fcn(hObject,eventdata)
global CONSTANT MUTATE DATA QUEUE
MUTATE.last_update_time = toc(CONSTANT.timer_start_tic);
% tic
%%increment sequence (timer throw error for any missed update)
seq = MUTATE.next_sequence;
if seq < length(CONSTANT.channel)
MUTATE.next_sequence = seq + 1;
elseif seq == length(CONSTANT.channel)
MUTATE.next_sequence = 1;
else
MUTATE.next_sequence = 1;
end
% toc
%%find out what to write to CONSTANT
include = find(CONSTANT.test_channel == CONSTANT.channel(seq),1);
if isempty(include)
w = CONSTANT.command.mean;
else
w = interp1(CONSTANT.command.time,CONSTANT.command.value,MUTATE.last_update_time);
end
I am getting this error:
Error while evaluating TimerFcn for timer 'timer-1'
Struct contents reference from a non-struct array object.
The error seems to arise at the line:
%%find out what to write to CONSTANT
include = find(CONSTANT.test_channel == CONSTANT.channel(seq),1);
if isempty(include)
w = CONSTANT.command.mean;
else
w = interp1(CONSTANT.command.time,CONSTANT.command.value,MUTATE.last_update_time);
end
I think it has to due with me declaring CONSTANT.command = 1; because i took part of this code from the syringe pump code examples, I am not sure what value CONSTANT.command should equal. but they noted in the documents that
"% @ command is a structure containing input signal to the pump that
% will be sampled by the timer"

Réponses (1)

Walter Roberson
Walter Roberson le 4 Jan 2018
Your posted code does not "global CONSTANT" before initializing CONSTANT.
Using global is not recommended.
  6 commentaires
Walter Roberson
Walter Roberson le 5 Jan 2018
It appears that it needs to be a struct with fields mean and time and value . The time and value fields should be vectors the same length, but mean should be a scalar.
I have to wonder if it is going to work, though: the value to interpolate at is going to depend upon toc() since a value that is not defined in the code, so it would not be surprising if the toc() happened to exceed the largest value in the time field. By default interp1() will return nan instead of interpolating beyond the existing data.
Once you have w, your posted code ignores it.
Your posted code hints that CONSTANT.timer_start_tic might need to be updated, but your posted code does not do that. If it is not updated then you will get the nan problem for sure.
Noah Acosta
Noah Acosta le 5 Jan 2018
If it makes anything clearer, here is the full code of the timer_update_fcn:
function timer_update_fcn(hObject,eventdata)
global CONSTANT MUTATE DATA QUEUE
MUTATE.last_update_time = toc(CONSTANT.timer_start_tic);
% tic
%%increment sequence (timer throw error for any missed update)
seq = MUTATE.next_sequence;
if seq < length(CONSTANT.channel)
MUTATE.next_sequence = seq + 1;
elseif seq == length(CONSTANT.channel)
MUTATE.next_sequence = 1;
else
MUTATE.next_sequence = 1;
end
% toc
%%find out what to write to CONSTANT
include = find(CONSTANT.test_channel == CONSTANT.channel(seq),1);
if isempty(include)
w = CONSTANT.command.mean;
else
w = interp1(CONSTANT.command.time,CONSTANT.command.value,MUTATE.last_update_time);
end
% toc
%%write and read
mfcs_set_auto(CONSTANT.handle,w,CONSTANT.channel(seq));
wt = toc(CONSTANT.timer_start_tic);
% toc
[r,chrono] = mfcs_read_chan(CONSTANT.handle,CONSTANT.channel(seq));
rt = double(chrono)*0.025 - CONSTANT.pump_start_time;
% toc
%%check bad read
if rt == MUTATE.pump_last_read_time(seq)
display('bad read')
end
MUTATE.pump_last_read_time(seq) = rt;
%%store
DATA(CONSTANT.channel(seq)).in_value = [DATA(CONSTANT.channel(seq)).in_value; w];
DATA(CONSTANT.channel(seq)).in_time = [DATA(CONSTANT.channel(seq)).in_time; wt];
DATA(CONSTANT.channel(seq)).out_value = [DATA(CONSTANT.channel(seq)).out_value; r];
DATA(CONSTANT.channel(seq)).out_time = [DATA(CONSTANT.channel(seq)).out_time; rt];
% toc
%%queue
QUEUE(CONSTANT.channel(seq)).in_value =...
[QUEUE(CONSTANT.channel(seq)).in_value(2:end); w];
QUEUE(CONSTANT.channel(seq)).in_time =...
[QUEUE(CONSTANT.channel(seq)).in_time(2:end); wt];
QUEUE(CONSTANT.channel(seq)).out_value =...
[QUEUE(CONSTANT.channel(seq)).out_value(2:end); r];
QUEUE(CONSTANT.channel(seq)).out_time =...
[QUEUE(CONSTANT.channel(seq)).out_time(2:end); rt];
% toc
if MUTATE.last_update_time >= CONSTANT.command.duration
if strcmp(get(CONSTANT.timer1, 'Running'), 'on')
stop(CONSTANT.timer1)
end
end

Connectez-vous pour commenter.

Catégories

En savoir plus sur Code Execution dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by