IOPort closes Screen

If a serial port name is not valid, IOPort errors. This can be caught using a try statement and dealt with. However if this happens IOPort also forcibly closes the window opened by screen. This means if you want to recover you must test, then reopen, the window. Why does the IOPort failure cause the screen to close? Is this expected/preferred behaviour?

Test case:

function ioporttest()

	screenSize = [0 0 1000 1000];
	bgColour = 0.5;
	port = '\dev\ttyACM100';

	ptb = mySetup(bgColour,screenSize);
	
	WaitSecs(1);
	fprintf('Try to open an invalid port, see if the window is closed:\n')
	conn = [];
	try
		conn=IOPort('OpenSerialPort',port,'BaudRate=115200');
	catch
		warning('Couldn''t open serial port interface...');
	end
	
	for i = 1:60
		Screen('gluDisk',ptb.win,[1 0 0],randi(ptb.winRect(3),1),randi(ptb.winRect(3),1),10);
		Screen('Flip', ptb.win);
	end
	
	if exist('conn','var') && ~isempty(conn)
		IOPort('Close',conn);
		IOPort('CloseAll');
	end
	
end

function ptb = mySetup(bgColour, size)
	ptb.cleanup = onCleanup(@myCleanup);
	PsychDefaultSetup(2);
	PsychImaging('PrepareConfiguration');
	[ptb.win, ptb.winRect] = PsychImaging('OpenWindow', 0, bgColour, size, [], [], [], 4);
	ptb.ifi = Screen('GetFlipInterval', ptb.win);
	ptb.halfisi = ptb.ifi / 2;
	ptb.fps = 1 / ptb.ifi;
	Screen('BlendFunction', ptb.win, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	disp('Screen Settings: ');
	disp(ptb);
end

function myCleanup()
	disp('Clearing up...')
	Priority(0);ListenChar(0);
	sca
end

Yes, by design. The assumption was that a failure like that should not leave the user stranded in front of a frozen screen.

-mario

Is there any way to avoid this behaviour (apart from recompile my own version
of IOPort)? I handle different I/O systems and need to be able to try catch my way to a working interface. At the moment I will add in logic to reopen the screen but this is not ideal. Thanks!

I think it would be good if its behavior is consistent with failures in Screen and other mex files, at least by default (or in this case by option to not introduce a breaking change). I can have a look into making that optional. Would an environment variable be the way to go Mario? And preference for what that variable would be called?

Ian, have you tried to set IOPort(‘Verbosity’) to 0? Then it won’t err even if the port is unavailable.

Thanks, I haven’t tried verbosity=0 but I’ll try it when I get back to my PTB workstation (I’m travelling without computers at the moment)…

Thanks Dee for the suggestion, let me try the verbosity solution and if it works then I think that is a good solution.

I was surprised that the screen closes (perhaps it is described in the docs, and this is a RTFM), I don’t think that happens when e.g. psychaudio fails?

I can confirm Verbosity=0 stops screen from closing. The doc for verbosity currently doesn’t mention this:

>> IOPort Verbosity?

Usage:

oldlevel = IOPort('Verbosity' [,level]);

Set level of verbosity for error/warning/status messages. 'level' optional, new
level of verbosity. 'oldlevel' is the old level of verbosity. The following
levels are supported: 0 = Shut up. 1 = Print errors, 2 = Print also warnings, 3
= Print also some info, 4 = Print more useful info (default), >5 = Be very
verbose (mostly for debugging the driver itself). 

I will add this info and make a pull request. It is slightly counter-intuitive that a command to change the logging level can also control the screen, but this is already in-the-wild and there is a workaround…

No need to send a pull request. The verbosity zero behaviour of IOPort('OpenSerialPort') is already documented in its help text since years.

-mario