Why program hangs - callback during timer works

Hello, I have a problem with building my app with appdesigner. I have a timer with perdiod set to 100 Hz. Timer function is plotting data from Arduino in real time. What i want to do is to set a value with slider using his callback. So basicly i have something like that :
% Callback function: PitchSlider
function PITCH_Change(app, event)
value = app.PitchSlider.Value;
app.EditPitch.Value = value;
fprintf(app.serial_COM, '%f','p');
fprintf(app.serial_COM, '%f',value);
drawnow;
end
function transCallback(app,serial_port)
fprintf(serial_port, '%s','?'); % wysyła znak do arduino
data = fscanf(serial_port, '%s'); % odbiera dane od arduino
data = strsplit(data,','); % parsuje pobrane dane za pomocą przecinka
Pitch = str2double(data(1)); % przypisanie odpowiednich danych do zmiennych
Roll = str2double(data(2));
Yaw = str2double(data(3));
Altitude = str2double(data(4));
Time = toc; % przypisanie upłyniętego czasu do zmiennej Time
olddata = app.dane_tab.Data; % pobranie starych wartości z tabeli
app.newdata = [olddata ; Pitch, Roll, Yaw, Altitude, Time]; % uaktualnienie macierzy danych (dodanie kolejnego wiersza)
app.dane_tab.Data = app.newdata; % przypisanie nowej macierzy do tabeli
plot(app.UIAxes,app.newdata(:,5),app.newdata(:,1),app.newdata(:,5),app.newdata(:,2),app.newdata(:,5),app.newdata(:,3),app.newdata(:,5),app.newdata(:,4)); % plotowanie
legend(app.UIAxes,'Pitch','Roll','Yaw','Altitude');
legend(app.UIAxes,'Location','north','Orientation','horizontal');
xlabel(app.UIAxes,'Czas [s]');
ylabel(app.UIAxes,'Kąt [stopnie]/Wysokość [cm]');
app.UIAxes.XLim = [(app.newdata(end,5)-10) app.newdata(end,5)]; % limit w osi x (wykres się przesuwa - okienkowanie danych)
drawnow; pause(0.001);
end
Unfortunately when i try to change a value with slider program hangs. Any ideas what i done wrongly?

8 个评论

So which of the two functions is the actual slider callback. I assume it's Pitch_Change. It's not clear what transCallback is.
Have you tried interrupting the program with CTRL+C ? If you do, which line of which function does it stop in?
Pitch_change function is slider callback. Just as you said. transCallback is function of timer. More precisly it's callback of TimerFcn function. I tried ctrl+C. Message that i receive:
Warning: Unsuccessful read: A timeout occurred before the Terminator was reached.. Error while evaluating TimerFcn for timer 'timer-1'
Also for better understand of my code I'm posting fragment of my Arduino code with transmission.
if true
if(Serial.available()>0)
{
if(Serial.read() == '?')
{
Serial.println(String(Kalman_angle_y)+","+String(Kalman_angle_x)+","+String(magn_direct_tilt)+","+String(Distance));
}
if(Serial.read() == 'p')
{
ZADANE_pitch = Serial.read();
// lcd.setCursor(6,1);
// lcd.print(ZADANE_pitch);
}
}
end
so I receive data from arduino every 10 ms, and when i change exact value with slider Arduino should read that value, and than return to receiving data from Arduino. If you need more information or something is not clear than i will try to be more precisely. Thanks for your answer by the way.
Are both callbacks sending data to the arduino? What would happen if both callbacks executed at the same time? (I doubt that could be the case since matlab is single-threaded).
To make it easier to find where it hangs, you could try adding some logging messages to both callbacks, e.g.:
function PITCH_Change(app, ~)
fprintf(2, 'PITCH_Change: Enter\n'); %using 2 will make the text red
value = app.PitchSlider.Value;
app.EditPitch.Value = value;
fprintf(2, 'PITCH_Change: Sending ''p''\n');
fprintf(app.serial_COM, '%f','p');
fprintf(2, 'PITCH_Change: Sending %f\n', value);
fprintf(app.serial_COM, '%f',value);
fprintf(2, 'PITCH_Change: Updating UI\n');
drawnow;
fprintf(2, 'PITCH_Change: Exit\n');
end
Same for the timer callback.
Tojmak comment mistakenly posted as an answer moved here:
Yeah, so i tried that and i've got something like this :
So it looks like it's problem with assigning all that data to table? Also i saw that program hangs on "Timer FCN : send "?"". Than with appearing of Error and Warning also appears "Timer FCN : getting data from Arduino".
Do you have any idea?
Well, if it's really stuck on getting data from arduino it looks like the problem is on the arduino. I would suspect your arduino code is in an invalid state for some reason.
If you can't figure out what's really going on, I suggest that you install some serial port monitoring software to see what's actually being sent to and from the arduino.
If the order of the log is to be believed, you have a problem though. As you can see you have two Pitch_Change events inside a TIMER_FCN event. And it looks like the 2nd Pitch_Change event starts before the first Pitch_Change event is finished (which is very puzzling, hence why i write if it is to be believed).
If the two events can interrupt each other as the log would imply, you may run into a case where one event starts transmitting and is then interrupted by the other that also starts transmitting. In the end you would get messages being sent and received out of order.
I have no idea how you work around that in matlab.

Tojmak comment mistakenly posted as an answer moved here:

Yeah i wonder why there's two Pitch_Change events. I'm clicking only once ;d. I will try with serial port monitor. Also i think i will play around a little with debugging. Thanks for your time. Tommorow i will try to do something and give you some info if you still will be willing to help me :). Thanks a lot.

Tojmak comment mistakenly posted as an answer moved here:

Hi, so I download serial monitor. After I found a small thing that I did wrongly Pitch_Change is running now only once. But there's still an error and warning.

I find out that propably the problem is that after Pitch_change function execute all data are combine. Just like on picture :

Last line shows the problem. "p", value, and "?" are put together. So I think that's the problem. Arduino gets that data and don;t know what to do. I tried to add some new line character but it doesnt't work. I tried :

-> fprintf(app.serial_COM, '%s\n','p'); -> fprintf(app.serial_COM, '%s\n\r','p'); -> fprintf(app.serial_COM, '%s','p'); fprintf(app.serial_COM, '\n'); But none of them works. "\n" is being replace with a single dot. Picture above shows that (for example "p" and value have dot between them). Then i tried send new line command from Arduino with Serial.println(""). Now I have that :

if true
  if(Serial.available()>0)
{
    zmienna_com = Serial.read();
    if(zmienna_com == '?')
    {
      Serial.println(String(Kalman_angle_y)+","+String(Kalman_angle_x)+","+String(magn_direct_tilt)+","+String(Distance));
    }
    else if(zmienna_com == 'p')
    {
      Serial.println("");
      ZADANE_pitch = Serial.read();   
      lcd.setCursor(6,1);
      lcd.print(ZADANE_pitch);
      Serial.println("");
      }
}
  end

That was for Arduino, and now Matlab part :

if true
  function PITCH_Change(app, event)
            fprintf(2,'Pitch_change: Enter\n');
            value = app.PitchSlider.Value;
            app.EditPitch.Value = value;
            fprintf(2,'Pitch_change: Sending \n');
            fprintf(app.serial_COM, '%s','p');
           %fprintf(app.serial_COM,'\n');
             pause(2);
             fscanf(app.serial_COM,'%s'); 
            fprintf(2,'Pitch_change: Sending %f\n', value)
           fprintf(app.serial_COM, '%.2f',value);
          % fprintf(app.serial_COM,'\n\r');
            pause(2);
            fscanf(app.serial_COM,'%s');  
           fprintf(2,'Pitch_change: Updating UI \n');
           % drawnow;
           fprintf(2,'Pitch_change: Exit \n');
        end
  end

But something is still missing because I've got that :

So, firstly I think I found some kind of sollution but it isn;t work perfectly because value and "?" are still together. And secondly I know that sollution is stupid and I should seperate all that data using matlab instead Arduino. Any ideas?

Disclaimer: I've never used the app designer.
You have a problem in that you have two different events that can occur at any time, even in the middle of each other it seems. Since both events try to communicate through the serial port they may end up talking over each other. I'm a bit puzzled by that since I thought that matlab was single threaded.
As far as I know, matlab does not provide any of the common mechanisms that other languages use to prevent that (critical sections, semaphores, ...) so I'm not sure how you'd work around that in matlab. You need to somehow ensure that only one event at a time communicates over the port. It may be that you should do all the communication with the timer event only, queuing the pitch change messages to be sent over by the timer.

请先登录,再进行评论。

回答(0 个)

类别

帮助中心File Exchange 中查找有关 MATLAB Support Package for Arduino Hardware 的更多信息

提问:

2018-4-16

编辑:

2018-4-23

Community Treasure Hunt

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

Start Hunting!

Translated by