From 2b285db0e4464c3e2daff1990df2b8c885ffea61 Mon Sep 17 00:00:00 2001 From: Dominik Mehlem <mehlem@ient.rwth-aachen.de> Date: Fri, 9 Dec 2022 15:20:08 +0100 Subject: [PATCH] switch from MATLAB serial to MATLAB serialport --- source/EV3.m | 3 ++- source/Motor.m | 18 ++++++++--------- source/btBrickIO.m | 48 +++++++++++++++++++++++++++++++++------------ tools/connect.py | 22 ++++++++++++--------- tools/disconnect.py | 2 +- tools/rc.local.sh | 1 + 6 files changed, 62 insertions(+), 32 deletions(-) diff --git a/source/EV3.m b/source/EV3.m index a261347..4d94f08 100644 --- a/source/EV3.m +++ b/source/EV3.m @@ -268,9 +268,10 @@ classdef EV3 < MaskedHandle end % Delete handle to comm-interface - if isCommInterfaceValid(ev3.commInterface) && ev3.commInterface ~= 0 + if isCommInterfaceValid(ev3.commInterface) ev3.commInterface.delete(); end + pause(5); ev3.commInterface = 0; ev3.isConnected = false; diff --git a/source/Motor.m b/source/Motor.m index 950202d..a6d7cb8 100644 --- a/source/Motor.m +++ b/source/Motor.m @@ -769,14 +769,14 @@ classdef Motor < MaskedHandle & dynamicprops p.parse(varargin{:}); if ~isempty(fieldnames(p.Unmatched)) - A = fieldnames(p.Unmatched); - warn = 'The following input parameters were invalid: '; - warn = [warn A{1}]; - for i = 2:length(A) - warn = [warn ', ' A{i}]; - end - warning(warn) - end + A = fieldnames(p.Unmatched); + warn = 'The following input parameters were invalid: '; + warn = [warn A{1}]; + for i = 2:length(A) + warn = [warn ', ' A{i}]; + end + warning(warn) + end % Set properties if motor.init @@ -926,7 +926,7 @@ classdef Motor < MaskedHandle & dynamicprops if ~motor.ev3Handle.isConnected || ~motor.physicalMotorConnected success = false; return; - end; + end if motor.currentSpeedRegulation motor.handleCommand(@outputSpeed, true, 0, motor.port, power); diff --git a/source/btBrickIO.m b/source/btBrickIO.m index 161924b..bf275af 100644 --- a/source/btBrickIO.m +++ b/source/btBrickIO.m @@ -94,7 +94,8 @@ classdef btBrickIO < BrickIO % Set the connection handle try if strcmp(brickIO.backend, 'serial') - brickIO.handle = serial(brickIO.serialPort); + brickIO.handle = serialport(brickIO.serialPort, 9600); + pause(3); else brickIO.handle = Bluetooth(brickIO.deviceName,brickIO.channel); end @@ -115,7 +116,10 @@ classdef btBrickIO < BrickIO end % Open the connection - brickIO.open; + if ~strcmp(brickIO.backend, 'serial') + brickIO.open; + end + end function delete(brickIO) @@ -142,7 +146,9 @@ classdef btBrickIO < BrickIO % Open the bt handle try - fopen(brickIO.handle); + if ~strcmp(brickIO.backend, 'serial') + fopen(brickIO.handle); + end catch ME if strcmp(ME.identifier, 'MATLAB:serial:fopen:opfailed') % Throw only clean CommError to avoid confusion in upper layers @@ -170,7 +176,9 @@ classdef btBrickIO < BrickIO try % Close the close handle - fclose(brickIO.handle); + if ~strcmp(brickIO.backend, 'serial') + fclose(brickIO.handle); + end catch ME % Throw combined error because error did not happen due to communication % failure @@ -183,7 +191,7 @@ classdef btBrickIO < BrickIO end function rmsg = read(brickIO) - % Reads data from the brick through bluetooth via fread and returns the data in uint8 format. + % Reads data from the brick through bluetooth via read and returns the data in uint8 format. if brickIO.debug > 0 fprintf('\t(DEBUG) (BT read) \n'); @@ -191,12 +199,20 @@ classdef btBrickIO < BrickIO try % Get the number of bytes to be read from the bt handle - nLength = fread(brickIO.handle,2); + if strcmp(brickIO.backend, 'serial') + nLength = read(brickIO.handle,2,'uint8'); + else + nLength = fread(brickIO.handle,2); + end % Read the remaining bytes - rmsg = fread(brickIO.handle,double(typecast(uint8(nLength),'uint16'))); + if strcmp(brickIO.backend, 'serial') + rmsg = read(brickIO.handle,double(typecast(uint8(nLength),'uint16')),'uint8'); + else + rmsg = fread(brickIO.handle,double(typecast(uint8(nLength),'uint16'))); + end catch ME - if strcmp(ME.identifier, 'MATLAB:serial:fread:opfailed') + if strcmp(ME.identifier, 'MATLAB:serialport:read:opfailed') || strcmp(ME.identifier, 'MATLAB:serial:fread:opfailed') % Throw only clean CommError to avoid confusion in upper layers msg = 'Failed to read data from Brick via Bluetooth.'; id = [ID(), ':', 'CommError']; @@ -212,11 +228,15 @@ classdef btBrickIO < BrickIO end % Append the reply size to the return message - rmsg = uint8([nLength' rmsg']); + if strcmp(brickIO.backend, 'serial') + rmsg = uint8([nLength rmsg]); + else + rmsg = uint8([nLength' rmsg']); + end end function write(brickIO,wmsg) - % Writes data to the brick through bluetooth via fwrite. + % Writes data to the brick through bluetooth via write. % % Arguments: % wmsg (uint8 array): Data to be written to the brick via bluetooth @@ -227,9 +247,13 @@ classdef btBrickIO < BrickIO try % Write to the bluetooth handle - fwrite(brickIO.handle,wmsg); + if strcmp(brickIO.backend, 'serial') + write(brickIO.handle,wmsg, class(wmsg)); + else + fwrite(brickIO.handle,wmsg); + end catch ME - if strcmp(ME.identifier, 'MATLAB:serial:fwrite:opfailed') + if strcmp(ME.identifier, 'MATLAB:serialport:write:opfailed') || strcmp(ME.identifier, 'MATLAB:serial:fwrite:opfailed') % Throw only clean CommError to avoid confusion in upper layers msg = 'Failed to send data to Brick via Bluetooth.'; id = [ID(), ':', 'CommError']; diff --git a/tools/connect.py b/tools/connect.py index f0e0d99..1edfd50 100755 --- a/tools/connect.py +++ b/tools/connect.py @@ -204,11 +204,11 @@ def print_success(brick, device): # we can now use our bluetooth-EV3 with matlab print(f''' -################ USE WITH MATLAB ################ -## 1. b=EV3 ## -## 2. b.connect('bt','serPort','{device}') ## -## 3. use b ## -################################################# +################ USE WITH MATLAB ############ +1. b=EV3(); +2. b.connect('bt','serPort','{device}'); +3. b.beep(); +############################################# ''') @@ -258,13 +258,17 @@ def pair(brick, PIN, device, channel=1): # the purpose of doing this here is to do it in a controlled manner so it can be semi-automatic, # since the daemon does not automatically pop up a PIN request form upon receiving from the device. write(btctl, f'pair {MAC}') + print('Connecting...') + sleep(3) + write(btctl, f'{PIN}') # "enter" pin - print(f'Pairing {name}: accept at the device (PIN {PIN})') + print(f'Pairing {name}: accept at the device AND confirm PIN. (PIN {PIN})') sleep(1) - print('then press Enter to continue...') - input('If the prompt does not appear in a few seconds, abort and restart this script.') - + print('THEN press Enter to continue...') + input('If the prompt does not appear in a few seconds, press Enter to retry pairing.') + write(btctl, f'{PIN}') # "enter" pin + for c in range(5): print('.', end='', flush=True) sleep(1) diff --git a/tools/disconnect.py b/tools/disconnect.py index 46e1225..af596b1 100755 --- a/tools/disconnect.py +++ b/tools/disconnect.py @@ -78,7 +78,7 @@ def print_dc_menu(): try: print(f'\nClose matlab or make sure you disconnect /dev/{b.device} inside matlab,') - print('for example using "b.disconnect()".\n') + print('for example by using "b.disconnect()".\n') input('Then press Enter to continue.') except: print() diff --git a/tools/rc.local.sh b/tools/rc.local.sh index de41686..ac25f11 100755 --- a/tools/rc.local.sh +++ b/tools/rc.local.sh @@ -6,6 +6,7 @@ for i in /opt/mindstorms/tools/*; do ln -s $i /usr/local/bin/ done +apt-get -y update # copy laboratory documentation echo "Copying documentation ..." -- GitLab