1- %{
2- This program is free software: you can redistribute it and/or modify
3- it under the terms of the GNU General Public License as published by
4- the Free Software Foundation, version 3.
5-
6- This program is distributed WITHOUT ANY WARRANTY and without even the
7- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8- See the GNU General Public License for more details.
9-
10- You should have received a copy of the GNU General Public License
11- along with this program. If not, see <http://www.gnu.org/licenses/>.
12- %}
1+ % This program is free software: you can redistribute it and/or modify it
2+ % under the terms of the GNU General Public License as published by the
3+ % Free Software Foundation, version 3.
4+ %
5+ % This program is distributed WITHOUT ANY WARRANTY and without even the
6+ % implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7+ % See the GNU General Public License for more details.
8+ %
9+ % You should have received a copy of the GNU General Public License along
10+ % with this program. If not, see <http://www.gnu.org/licenses/>.
1311
1412classdef BpodStepperModule < handle & matlab .mixin .CustomDisplay
1513
1614 properties (SetAccess = protected )
1715 Port % ArCOM Serial port
16+ HardwareRevision % PCB revision of connected module
1817 FirmwareVersion % firmware version of connected module
19- HardwareVersion % PCB revision of connected module
2018 DriverVersion % which TMC driver is installed?
2119 end
2220
2321 properties (Dependent )
24- RMScurrent % RMS current (mA)
25- holdRMScurrent % hold RMS current (mA)
26- ChopperMode % 0 = PWM chopper ("spreadCycle")
27- % 1 = voltage chopper ("stealthChop")
28- % 2 = constant off time
29- Acceleration % acceleration (full steps / s^2)
30- MaxSpeed % peak velocity (full steps / s)
22+ PeakCurrent % peak current (mA)
23+ RMScurrent % RMS current (mA)
24+ holdRMScurrent % hold RMS current (mA)
25+ % ChopperMode
26+ % 0 = PWM chopper ("spreadCycle")
27+ % 1 = voltage chopper ("stealthChop")
28+ % 2 = constant off time
29+ ChopperMode
30+ Acceleration % acceleration (full steps / s^2)
31+ MaxSpeed % peak velocity (full steps / s)
3132 MicroPosition
32- Position % absolute position
33+ Position % absolute position
3334 EncoderPosition
3435 end
3536
7677
7778 % get non-dependent parameters from stepper module
7879 obj .Port .write(' GH' , ' uint8' );
79- obj.HardwareVersion = double(obj .Port .read(1 , ' uint8' )) / 10 ;
80+ obj.HardwareRevision = double(obj .Port .read(1 , ' uint8' )) / 10 ;
8081 obj .Port .write(' GT' , ' uint8' );
8182 switch obj .Port .read(1 , ' uint8' )
8283 case 17 % 0x11
83- obj.DriverVersion = 2130 ;
84+ obj.DriverVersion = ' TMC2130 ' ;
8485 case 48 % 0x30
85- obj.DriverVersion = 5160 ;
86+ obj.DriverVersion = ' TMC5160 ' ;
8687 otherwise
87- obj.DriverVersion = NaN ;
88+ obj.DriverVersion = ' unknown ' ;
8889 end
8990 obj .Port .write(' GA' , ' uint8' );
9091 obj.privAcceleration = obj .Port .read(1 , ' uint16' );
121122 obj .pauseStreaming(false );
122123 end
123124
125+ function out = get .PeakCurrent(obj )
126+ out = obj .RMScurrent * sqrt(2 );
127+ end
128+ function set .PeakCurrent(obj , newCurrent )
129+ obj.RMScurrent = newCurrent / sqrt(2 );
130+ end
131+
124132 function out = get .RMScurrent(obj )
125133 out = obj .privRMScurrent ;
126134 end
127135 function set .RMScurrent(obj , newCurrent )
128136 validateattributes(newCurrent ,{' numeric' },...
129- {' scalar' ,' integer ' ,' nonnegative ' })
137+ {' scalar' ,' nonnegative ' ,' real ' })
130138 obj .Port .write(' I' , ' uint8' , newCurrent , ' uint16' );
131139 obj .pauseStreaming(true );
132140 obj .Port .write(' GI' , ' uint8' );
133141 obj.privRMScurrent = obj .Port .read(1 , ' uint16' );
134142 obj .pauseStreaming(false );
135143 end
136-
144+
137145 function out = get .holdRMScurrent(obj )
138146 out = obj .privHoldRMScurrent ;
139147 end
140148 function set .holdRMScurrent(obj , newCurrent )
141149 validateattributes(newCurrent ,{' numeric' },...
142- {' scalar' ,' integer ' ,' nonnegative ' })
150+ {' scalar' ,' nonnegative ' ,' real ' })
143151 obj .Port .write(' i' , ' uint8' , newCurrent , ' uint16' );
144152 obj .pauseStreaming(true );
145153 obj .Port .write(' Gi' , ' uint8' );
172180 end
173181 function out = get .Position(obj )
174182 obj .pauseStreaming(true );
175- obj .Port .write(' GP ' , ' uint8' );
176- out = obj .Port .read(1 , ' int16 ' ) ;
183+ obj .Port .write(' Gp ' , ' uint8' );
184+ out = double( obj .Port .read(1 , ' int32 ' )) / 256 ;
177185 obj .pauseStreaming(false );
178186 end
179187 function set .Position(obj ,position )
180188 validateattributes(position ,{' numeric' },{' scalar' ,' integer' })
181- obj .Port .write(' P ' , ' int8' , position , ' int16 ' );
189+ obj .Port .write(' p ' , ' int8' , round( position * 256 ) , ' int32 ' );
182190 end
183191 function resetPosition(obj )
184192 % Reset value of absolute position to zero.
@@ -205,7 +213,7 @@ function step(obj, nSteps)
205213 end
206214 obj .Port .write(' S' , ' uint8' , nSteps , ' int16' );
207215 end
208-
216+
209217 function microStep(obj , nSteps )
210218 % Move stepper motor a set number of micro-steps. nSteps = positive
211219 % for clockwise steps, negative for counterclockwise
@@ -483,36 +491,71 @@ function pauseStreaming(obj, doPause)
483491 tmp = [typecast(tmp(3 : 4 ), ' uint16' ) tmp([2 1 ])];
484492 out = obj .verArr2Str(tmp );
485493 end
486-
494+
487495 function out = verArr2Str(~, in )
488496 out = sprintf(' %04d .%02d .%d ' , in(: ));
489497 end
490-
498+
491499 function out = verArr2Int(~, in )
492500 out = [uint8(in([3 2 ])) typecast(uint16(in(1 )), ' uint8' )];
493501 out = typecast(out , ' uint32' );
494502 end
495- end
503+
504+ function displayPropGroup(obj , groups , fmts )
505+ persistent nPad
506+ persistent chopperModes
507+ if isempty(nPad )
508+ nPad = max(cellfun(@numel ,[groups .PropertyList ])) + 1 ;
509+ chopperModes = {' PWM chopper' , ' voltage chopper' , ' constant off time chopper' };
510+ end
511+ for ii = 1 : numel(groups )
512+ padProps = pad(groups(ii ).PropertyList, nPad , ' left' );
513+ fprintf(' <strong>%s </strong>\n ' ,groups(ii ).Title)
514+ for jj = 1 : groups(ii ).NumProperties
515+ if strcmp(groups(ii ).PropertyList{jj }, ' ChopperMode' )
516+ fprintf([' %s : ' fmts{ii }{jj } ' (%s )\n ' ], ...
517+ padProps{jj }, obj.(groups(ii ).PropertyList{jj }), ...
518+ chopperModes{1 + obj.(groups(ii ).PropertyList{jj })})
519+ else
520+ fprintf([' %s : ' fmts{ii }{jj } ' \n ' ], ...
521+ padProps{jj }, obj.(groups(ii ).PropertyList{jj }))
522+ end
523+ end
524+ fprintf(' \n ' )
525+ end
526+ end
496527
497- methods (Access = protected )
498- function propgrp = getPropertyGroups(obj )
499- gTitle1 = ' <strong>Module Information</strong>' ;
500- propList1 = {' HardwareVersion' ,' DriverVersion' ,' FirmwareVersion' };
501- gTitle2 = ' <strong>Motor Configuration</strong>' ;
502- propList2 = {' RMScurrent' ,' holdRMScurrent' ,' ChopperMode' ,' MaxSpeed' ,' Acceleration' };
503- gTitle3 = ' <strong>Movement Parameters</strong>' ;
528+ function [propgrp , fmt ] = getPropGroups(obj )
529+ gTitle{1 } = ' Module Information' ;
530+ gTitle{2 } = ' Motor Configuration' ;
531+ gTitle{3 } = ' Movement Parameters' ;
532+
533+ pList{1 } = {' HardwareRevision' ,' DriverVersion' ,' FirmwareVersion' };
534+ pList{2 } = {' PeakCurrent' ,' RMScurrent' ,' holdRMScurrent' ,' ChopperMode' };
535+ pList{3 } = {' MaxSpeed' ,' Acceleration' ,' Position' };
536+
537+ fmt{1 } = {' %.1f ' , ' ''%s'' ' , ' ''%s'' ' };
538+ fmt{2 } = {' %d mA' , ' %d mA' , ' %d mA' , ' %d ' };
539+ fmt{3 } = {' %d steps/s' , ' %d steps/s²' , ' %.1f steps' };
540+
504541 if obj .privUseEncoder
505- propList3 = {' Position' ,' EncoderPosition' };
506- else
507- propList3 = {' Position' };
542+ pList{3 } = [pList{3 } {' EncoderPosition' }];
543+ fmt{3 } = [fmt{3 } {' %d ' }];
508544 end
509- propgrp(1 ) = matlab .mixin .util .PropertyGroup(propList1 ,gTitle1 );
510- propgrp(2 ) = matlab .mixin .util .PropertyGroup(propList2 ,gTitle2 );
511- propgrp(3 ) = matlab .mixin .util .PropertyGroup(propList3 ,gTitle3 );
512- end
513545
514- function s = getFooter(obj )
515- s = matlab .mixin .CustomDisplay .getDetailedFooter(obj );
546+ propgrp(1 ) = matlab .mixin .util .PropertyGroup(pList{1 },gTitle{1 });
547+ propgrp(2 ) = matlab .mixin .util .PropertyGroup(pList{2 },gTitle{2 });
548+ propgrp(3 ) = matlab .mixin .util .PropertyGroup(pList{3 },gTitle{3 });
549+ end
550+ end
551+
552+ methods (Access = protected )
553+ function displayScalarObject(obj )
554+ fprintf(' %s with properties:\n\n ' , ...
555+ matlab .mixin .CustomDisplay .getClassNameForHeader(obj ));
556+ [propgroup , fmt ] = getPropGroups(obj );
557+ displayPropGroup(obj ,propgroup ,fmt )
558+ disp(matlab .mixin .CustomDisplay .getDetailedFooter(obj ))
516559 end
517560 end
518561end
0 commit comments