-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchopper_tune.cfg
415 lines (392 loc) · 22.9 KB
/
chopper_tune.cfg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
[gcode_macro CHOPPER_TUNE]
description: Vibrations tests to calculate lowest magnitude drivers registers v1.2 ; https://github.com/MRX8024/chopper-resonance-tuner
variable_debug: False ; Enable debug output
variable_inset: 10 ; Offset from axis limits (mm), to determine work area limits
variable_current_change_step: 25 ; Set run_current change step
variable_measure_time: 1250 ; Set measure time (msec)
variable_required_rpm: [37.5, 150, 1.5] ; Set range, step of motor rpm in find vibr mode
variable_delay: 500 ; Set delay between measurements (msec) in find vibr mode
variable_fclk: 12
gcode:
{% set current_min = params.CURRENT_MIN_MA|default('default')|string|lower %}
{% set current_max = params.CURRENT_MAX_MA|default('default')|string|lower %}
{% set tbl_min = params.TBL_MIN|default(0)|int %}
{% set tbl_max = params.TBL_MAX|default(3)|int %}
{% set toff_min = params.TOFF_MIN|default(1)|int %}
{% set toff_max = params.TOFF_MAX|default(8)|int %}
{% set hstrt_hend_max = params.HSTRT_HEND_MAX|default(16)|int %}
{% set hstrt_min = params.HSTRT_MIN|default(0)|int %}
{% set hstrt_max = params.HSTRT_MAX|default(7)|int %}
{% set hend_min = params.HEND_MIN|default(2)|int %}
{% set hend_max = params.HEND_MAX|default(15)|int %}
{% set tpfd_min = params.TPFD_MIN|default(-1)|int %}
{% set tpfd_max = params.TPFD_MAX|default(-1)|int %}
{% set min_speed = params.MIN_SPEED|default('default')|string|lower %}
{% set max_speed = params.MAX_SPEED|default('default')|string|lower %}
{% set speed_change_step = params.SPEED_CHANGE_STEP|default('default')|string|lower %}
{% set iterations = params.ITERATIONS|default(1)|int %}
{% set travel_distance = params.TRAVEL_DISTANCE|default('default')|string|lower %}
{% set accel_chip = params.ACCELEROMETER|default('default')|string|lower %}
{% set find_vibr = params.FIND_VIBRATIONS|default('False')|string|lower %}
{% set axis = params.AXIS|default('X')|string|lower %}
{% set run_plotter = params.RUN_PLOTTER|default('True')|string|lower %}
_detect_driver stepper={axis}
_chop_workflow axis={axis} {rawparams}
[gcode_shell_command chop_tune]
command: ~/chopper-resonance-tuner/chopper_plot.sh
timeout: 9999.0
verbose: True
[gcode_macro _detect_driver]
description: Find which driver is used in configuration
variable_drivers: '2130', '2208', '2209', '2660', '2240', '5160' ; Drivers supported by Klipper
variable_driver: 0
variable_resistor: 0
gcode:
{% set stepper = 'stepper_' + params.STEPPER|string|lower %} ; Import default stepper for search its driver
{% for driver in drivers %}
{% if 'run_current' in printer.configfile.config['tmc' + driver + ' ' + stepper] %}
{action_respond_info('Selected tmc%s for %s' % (driver, stepper))}
SET_GCODE_VARIABLE MACRO=_detect_driver VARIABLE=driver VALUE={driver}
{% if driver != '2240' %}
{% set resistor = printer.configfile.settings['tmc' + driver + ' ' + stepper].sense_resistor %}
{% else %}
{% set resistor = printer.configfile.settings['tmc' + driver + ' ' + stepper].rref %}
{% endif %}
SET_GCODE_VARIABLE MACRO=_detect_driver VARIABLE=resistor VALUE={resistor}
{% endif %}
{% endfor %}
[gcode_macro _chop_apply_regs]
variable_registers: 'tbl', 'toff', 'hend', 'hstrt', 'tpfd', 'curr'
variable_amount: 0
variable_tbl: -1
variable_toff: -1
variable_hend: -1
variable_hstrt: -1
variable_tpfd: -1
variable_curr: -1
gcode:
{% if printer['gcode_macro _chop_apply_regs'][params.FIELD]|int != params.VALUE|int %}
{% for stepper in params.STEPPERS.split('-') %}
{% if printer['gcode_macro CHOPPER_TUNE'].debug %}
M118 Setting {params.FIELD|string|lower} from {
printer['gcode_macro _chop_apply_regs'][params.FIELD]|int} to {params.VALUE|int} on {stepper}
{% endif %}
{% if params.FIELD|lower != 'curr' %}
SET_TMC_FIELD STEPPER={stepper} FIELD={params.FIELD} VALUE={params.VALUE|int}
{% else %}
SET_TMC_CURRENT STEPPER={stepper} CURRENT={params.VALUE|int / 1000}
{% endif %}
{% for count in range(1, amount + 1) %}
{% if printer['gcode_macro CHOPPER_TUNE'].debug %}
M118 Setting {params.FIELD|string|lower} from {
printer['gcode_macro _chop_apply_regs'][params.FIELD]|int} to {
params.VALUE|int} on {stepper|string + count|string}
{% endif %}
{% if params.FIELD|lower != 'curr' %}
SET_TMC_FIELD STEPPER={stepper|string + count|string} FIELD={params.FIELD} VALUE={params.VALUE|int}
{% else %}
SET_TMC_CURRENT STEPPER={stepper} CURRENT={params.VALUE|int / 1000}
{% endif %}
{% endfor %}
{% endfor %}
SET_GCODE_VARIABLE MACRO=_chop_apply_regs VARIABLE={params.FIELD|string|lower} VALUE={params.VALUE|int}
{% endif %}
[gcode_macro _chop_workflow]
description: Calculate process of CHOPPER_TUNE macro
gcode:
{% set axis = params.AXIS|default('X')|string|lower %}
{% set driver = printer['gcode_macro _detect_driver'].driver|string|lower %} ; Import default driver from _detect_driver
{% set sense_resistor = printer['gcode_macro _detect_driver'].resistor %} ; Import sense_resistor from _detect_driver
{% set current_min = params.CURRENT_MIN_MA|default('default')|string|lower %} ; Import rawparams from CHOPPER_TUNE params
{% set current_max = params.CURRENT_MAX_MA|default('default')|string|lower %}
{% set current_change_step = printer['gcode_macro CHOPPER_TUNE'].current_change_step %}
{% set tbl_min = params.TBL_MIN|default(0)|int %}
{% set tbl_max = params.TBL_MAX|default(3)|int %}
{% set toff_min = params.TOFF_MIN|default(1)|int %}
{% set toff_max = params.TOFF_MAX|default(8)|int %}
{% set hstrt_hend_max = params.HSTRT_HEND_MAX|default(16)|int %}
{% set hstrt_min = params.HSTRT_MIN|default(0)|int %}
{% set hstrt_max = params.HSTRT_MAX|default(7)|int %}
{% set hend_min = params.HEND_MIN|default(2)|int %}
{% set hend_max = params.HEND_MAX|default(15)|int %}
{% set tpfd_min = params.TPFD_MIN|default(-1)|int %}
{% set tpfd_max = params.TPFD_MAX|default(-1)|int %}
{% set min_speed = params.MIN_SPEED|default('default')|string|lower %}
{% set max_speed = params.MAX_SPEED|default('default')|string|lower %}
{% set speed_change_step = params.SPEED_CHANGE_STEP|default('default')|string|lower %}
{% set required_rpm = printer['gcode_macro CHOPPER_TUNE'].required_rpm %}
{% set iterations = params.ITERATIONS|default(1)|int %}
{% set travel_distance = params.TRAVEL_DISTANCE|default('default')|string|lower %}
{% set accel_chip = params.ACCELEROMETER|default('default')|string|lower %}
{% set find_vibr = params.FIND_VIBRATIONS|default('False')|string|lower %}
{% set run_plotter = params.RUN_PLOTTER|default('True')|string|lower %}
{% set inset = printer['gcode_macro CHOPPER_TUNE'].inset %}
{% set config = printer.configfile.config %}
{% set settings = printer.configfile.settings %}
{% set measure_time = printer['gcode_macro CHOPPER_TUNE'].measure_time / 1000|float %}
{% set delay = printer['gcode_macro CHOPPER_TUNE'].delay|int %}
{% set fclk = printer['gcode_macro CHOPPER_TUNE'].fclk|int %}
{% set kinematics = config.printer.kinematics|string %}
; Select main and secondary axis / stepper, their requirements
{% if axis in ['x', 'y', 'z'] %}
{% if kinematics == 'corexy' %}
{% if axis in ['x', 'y'] %}
{% if axis == 'x' %}
{% set axes = ['x', 'y'] %}
{% elif axis == 'y' %}
{% set axes = ['y', 'x'] %}
{% endif %}
{% set steppers = ['stepper_x', 'stepper_y'] %}
{% elif axis == 'z' %}
{% set axes = ['z', 'x'] %}
{% set steppers = ['stepper_z'] %}
{% endif %}
{% elif kinematics == 'cartesian' %}
{% if axis == 'x' %}
{% set axes = ['x', 'y'] %}
{% set steppers = ['stepper_x'] %}
{% elif axis == 'y' %}
{% set axes = ['y', 'x'] %}
{% set steppers = ['stepper_y'] %}
{% elif axis == 'z' %}
{% set axes = ['z', 'x'] %}
{% set steppers = ['stepper_z'] %}
{% endif %}
{% else %}
{action_raise_error('WARNING!!! Script does not support your kinematics')}
{% endif %}
{% if axes[0] == 'z' %}
{% set minAX = (settings['stepper_' + axes[0]].position_min|float, 0)|max + inset %}
{% set acceleration = settings.printer.max_z_accel|int %}
{% set trv_speed = config.printer.max_z_velocity|int / 2 * 60 %} ; Idle movements speed
{% else %}
{% set minAX = settings['stepper_' + axes[0]].position_min|float + inset %}
{% set acceleration = config.printer.max_accel|int %}
{% set trv_speed = config.printer.max_velocity|int / 2 * 60 %} ; Idle movements speed
{% endif %}
{% set maxAX = settings['stepper_' + axes[0]].position_max|float - inset %}
{% set midAX = settings['stepper_' + axes[0]].position_min|float +
((settings['stepper_' + axes[0]].position_max|float -
settings['stepper_' + axes[0]].position_min|float) / 2) %}
{% set midBAX = settings['stepper_' + axes[1]].position_min|float +
((settings['stepper_' + axes[1]].position_max|float -
settings['stepper_' + axes[1]].position_min|float) / 2) %}
{% else %}
{action_raise_error('WARNING!!! Incorrect direction')}
{% endif %}
; Error TPFD on unsupported drivers and values
{% if tpfd_min != -1 or tpfd_max != -1 %}
{% if driver == '5160' or driver == '2240' %}
{% if tpfd_min < 0 or tpfd_max < 0 %}
{action_raise_error('WARNING!!! Incorrect TPFD values')}
{% endif %}
{% else %}
{action_raise_error('WARNING!!! TMC%s not support register TPFD' % (driver))}
{% endif %}
{% endif %}
; Reseting variables with registers and steppers
{% for register in printer['gcode_macro _chop_apply_regs'].registers %}
SET_GCODE_VARIABLE MACRO=_chop_apply_regs VARIABLE={register|string|lower} VALUE=-1
{% endfor %}
; Select count of one axis steppers
{% for mot in range(8) %}
{% if ('stepper_' + axes[0] + mot|string) in config %}
SET_GCODE_VARIABLE MACRO=_chop_apply_regs VARIABLE=amount VALUE={mot}
{% if ('stepper_' + axes[0] + (mot + 1)|string) not in config %}
{action_respond_info('Selected %dwd configuration' % (mot + 1))}
{% endif %}
{% elif mot == 1 %}
{action_respond_info('Selected 1wd configuration')}
{% endif %}
{% endfor %}
; Select accelerometer
{% if accel_chip == 'default' %}
{% if 'accel_chip' in config.resonance_tester %}
{% set accel_chip = config.resonance_tester.accel_chip %}
{% else %}
{% set accel_chip = 'adxl345' %} ; Default accelerometer
{% endif %}
{% endif %}
{action_respond_info('Selected %s for accelerometer' % (accel_chip))}
; Select run_current
{% if current_min == 'default' %}
{% set current_min = (config['tmc' + driver + ' ' + steppers[0]].run_current|float * 1000)|int %}
{% if printer['gcode_macro CHOPPER_TUNE'].debug %}
{action_respond_info('Set default run_current: %d mA to run_current_min' % (current_min))}
{% endif %}
{% else %}
{% set current_min = current_min|int %}
{% endif %}
{% if current_max == 'default' %}
{% set current_max = (config['tmc' + driver + ' ' + steppers[0]].run_current|float * 1000)|int%}
{% if printer['gcode_macro CHOPPER_TUNE'].debug %}
{action_respond_info('Set default run_current: %d mA to run_current_max' % (current_max))}
{% endif %}
{% else %}
{% set current_max = current_max|int %}
{% endif %}
; In vibration measurement mode, search and takes registers from printer.cfg, set speed range
{% if find_vibr == 'true' or find_vibr == '1' %}
{% set current_max = current_min %}
{% set tbl_min = settings['tmc' + driver + ' ' + steppers[0]].driver_tbl|int %}
{% set tbl_max = tbl_min %}
{% set toff_min = settings['tmc' + driver + ' ' + steppers[0]].driver_toff|int %}
{% set toff_max = toff_min %}
{% set hstrt_min = settings['tmc' + driver + ' ' + steppers[0]].driver_hstrt|int %}
{% set hstrt_max = hstrt_min %}
{% set hend_min = settings['tmc' + driver + ' ' + steppers[0]].driver_hend|int %}
{% set hend_max = hend_min %}
{% set rotation_dist = config[steppers[0]].rotation_distance|float %}
{% set gear_ratio = (config[steppers[0]].gear_ratio|default('1:1')).split(':') %}
{% set full_steps_per_rotation = config[steppers[0]].full_steps_per_rotation|default(200)|int %}
{% if min_speed == 'default' %}
{% set min_speed = (required_rpm[0] / 60 * full_steps_per_rotation /
200 / (gear_ratio[0]|int / gear_ratio[1]|int) * rotation_dist)|float %}
{% else %}
{% set min_speed = min_speed|float %}
{% endif %}
{% if max_speed == 'default' %}
{% set max_required_mms = (required_rpm[1] / 60 * full_steps_per_rotation /
200 / (gear_ratio[0]|int / gear_ratio[1]|int) * rotation_dist)|int %}
{% set max_speed = (((-acceleration * measure_time + ((acceleration * measure_time) ** 2 +
4 * acceleration * (maxAX - minAX)) ** 0.5) / 2), max_required_mms)|min|float %}
{% else %}
{% set max_speed = max_speed|float %}
{% endif %}
{% if speed_change_step == 'default' %}
{% set speed_change_step = required_rpm[2] / 60 * full_steps_per_rotation /
200 / (gear_ratio[0]|int / gear_ratio[1]|int) * rotation_dist %}
{% else %}
{% set speed_change_step = speed_change_step|float %}
{% endif %}
{% else %}
; Protect not defined speed & converting str -> float
{% if min_speed == 'default' or max_speed == 'default' %}
{action_raise_error('WARNING!!! Resonance speed must be defined')}
{% endif %}
{% set min_speed, max_speed = min_speed|float, max_speed|float %}
{% set speed_change_step = 1 %}
{% endif %}
; Check speed limit
{% if max_speed > trv_speed / 30 %}
{action_raise_error('WARNING!!! Required speed (%d mm/s) on axis (%s)'
' is faster than kinematics allow, please lower speed or increase'
' speed limit in printer.cfg' % (max_speed, axes[0]))}
{% endif %}
; Calculate min required toolhead travel distance from speed, acceleration and time
{% set accel_decel_distance = max_speed ** 2 / acceleration %}
{% set auto_travel_distance = accel_decel_distance + (max_speed * measure_time) %}
{% if printer['gcode_macro CHOPPER_TUNE'].debug %}
{action_respond_info('Acceleration & deceleration zone = %f mm' % (accel_decel_distance))}
{action_respond_info('Auto calculated min required travel distance = %f mm' % (auto_travel_distance))}
{% endif %}
; Protect exceeding axis limits & calculate travel distance
{% if travel_distance == 'default' %}
{% if minAX + auto_travel_distance > maxAX %}
{action_raise_error('WARNING!!! Required travel distance on axis (%s)'
' (%.2f mm) is longer than kinematics allows, please lower'
' speed or increase acceleration' % (axes[0], auto_travel_distance))}
{% endif %}
{% set travel_distance = auto_travel_distance %}
{% else %}
{% set travel_distance = travel_distance|int %}
{% if minAX + travel_distance > maxAX %}
{% set travel_distance = maxAX - minAX %}
{% if travel_distance < auto_travel_distance %}
{action_raise_error('WARNING!!! Travel distance on axis (%s) is less than'
' it should be, please increase acceleration or lower speed' % (axes[0]))}
{% else %}
{action_respond_info('WARNING!!! Travel distance on axis (%s)'
' is longer than kinematics allows, lowering...' % (axes[0]))}
{% endif %}
{% else %}
{% if travel_distance < auto_travel_distance %}
{% set travel_distance = auto_travel_distance %}
{% if minAX + auto_travel_distance > maxAX %}
{action_raise_error('WARNING!!! Travel distance on axis (%s) is less'
' than required (%.2f mm), and longer than kinematics allows, please lower'
' speed or increase acceleration' % (axes[0], auto_travel_distance))}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
; Info message
{% if find_vibr == 'true' or find_vibr == '1' %}
{action_respond_info('Final max travel distance = %.2f mm, position min = %.2f, traveling: %.2f --> %.2f' %
(travel_distance, minAX, minAX, travel_distance + minAX))}
{action_respond_info('Start find vibration mode, speed: %.2f --> %.2f mm/s with %.2f step current=%d TBL=%d TOFF=%d'
' HSTRT=%d HEND=%d' % (min_speed, max_speed, speed_change_step, current_min, tbl_min, toff_min, hstrt_min, hend_min))}
{% else %}
{action_respond_info('Final travel distance = %.2f mm, position min = %.2f, traveling: %.2f --> %.2f' %
(travel_distance, minAX, minAX, travel_distance + minAX))}
{action_respond_info('Start of register enumeration mode, speed: %.2f --> %.2f mm/s current: %d'
' --> %d mA iterations=%d TBL: %d --> %d TOFF: %d --> %d HSTRT: %d --> %d HEND: %d --> %d TPFD:'
' %d --> %d' % (min_speed, max_speed, current_min, current_max, iterations, tbl_min, tbl_max,
toff_min, toff_max, hstrt_min, hstrt_max, hend_min, hend_max, tpfd_min, tpfd_max))}
{% endif %}
; Check for axis homing
{% if not 'xyz' in printer.toolhead.homed_axes %}
G28 X Y Z
{% endif %}
SET_VELOCITY_LIMIT ACCEL={acceleration}
SET_VELOCITY_LIMIT ACCEL_TO_DECEL={acceleration}
G0 {axes[0]}{minAX} {axes[1]}{midBAX} F{trv_speed} ; Move to the initial position
RUN_SHELL_COMMAND CMD=chop_tune PARAMS='cleaner' ; Clean csv files
ACCELEROMETER_MEASURE CHIP={accel_chip} NAME=stand_still
G4 P5000
ACCELEROMETER_MEASURE CHIP={accel_chip} NAME=stand_still
{% for current in range(current_min, current_max + 1, current_change_step) %} ; Set steps of run_current
_chop_apply_regs steppers={steppers|join('-')} field=curr value={current}
{% for tbl in range(tbl_min, tbl_max + 1) %} ; Set tbl values
_chop_apply_regs steppers={steppers|join('-')} field=tbl value={tbl}
{% for toff in range(toff_min, toff_max + 1) %} ; Set toff values
_chop_apply_regs steppers={steppers|join('-')} field=toff value={toff}
{% for hstrt_value in range(hstrt_min, hstrt_max + 1) %}
{% for hend_value in range(hend_min, hend_max + 1) %}
{% if hend_value + hstrt_value <= hstrt_hend_max %} ; Set hend, and hstrt values
_chop_apply_regs steppers={steppers|join('-')} field=hend value={hend_value}
_chop_apply_regs steppers={steppers|join('-')} field=hstrt value={hstrt_value}
{% for tpfd in range(tpfd_min, tpfd_max + 1) %} ; Set tpfd values
{% if tpfd_min != -1 and tpfd_max != -1 %}
_chop_apply_regs steppers={steppers|join('-')} field=tpfd value={tpfd}
{% endif %}
DUMP_TMC STEPPER={steppers[0]} REGISTER=chopconf ; Dump TMC settings
{% set freq = 1/(2*(12+32*toff)*1/(1000000*fclk)+2*1/(1000000*fclk)*16*(1.5**tbl)) %}
{% for speed in range((min_speed * 100)|int, (max_speed * 100)|int + 1, (speed_change_step * 100)|int) %}
{% set speed = speed / 100 %}
{% for i in range(iterations) %}
{% if find_vibr == 'true' or find_vibr == '1' %}
{% set travel_distance = (travel_distance / max_speed) * speed %}
G4 P{delay}
M118 Speed {speed|round(2)} mm/s on {travel_distance|round(2)} mm
{% endif %}
{% set name = '__%d_%d_%d_%d_%d_%d_%d_%d_%d__' %
(current, tbl, toff, hstrt_value, hend_value, tpfd, speed*100, freq, i+1) %}
ACCELEROMETER_MEASURE CHIP={accel_chip} NAME={name} ; Start accelerometer data collection
G0 {axes[0]}{minAX + travel_distance} F{speed*60} ; Movement
ACCELEROMETER_MEASURE CHIP={accel_chip} NAME={name} ; Stop accelerometer data collection
G0 {axes[0]}{minAX} F{trv_speed} ; Move to the initial position
M400
{% endfor %}
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
{% if tpfd_min == -1 or tpfd_max == -1 %}
{% set tpfd_min, tpfd_max = 0, 0 %}
{% endif %}
G4 P500
G0 {axis}{midAX} F{trv_speed}
{% if run_plotter == 'true' or run_plotter == '1' %}
M118 Magnitude graphs generation...
M118 This may take a while, please wait
; export data to processing
RUN_SHELL_COMMAND CMD=chop_tune PARAMS='{'iterations=%d driver=%s sense_resistor=%f'%(iterations, driver, sense_resistor)}'
{% endif %}
; output data info
M118 For run parser manually type - RUN_SHELL_COMMAND CMD=chop_tune PARAMS='{'iterations=%d driver=%s sense_resistor=%f'%
(iterations, driver, sense_resistor)}'