Skip to content

Commit 490fe0b

Browse files
authored
Merge pull request #122 from Chr157i4n/dev
version 0.7.8
2 parents 533dbbd + 3621a03 commit 490fe0b

21 files changed

+216
-133
lines changed

.vscode/settings.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,14 @@
55
"--disable=W0012",
66
"--extension-pkg-whitelist=RPi",
77
],
8-
"files.trimTrailingWhitespace": true
8+
"files.trimTrailingWhitespace": true,
9+
"python.testing.unittestArgs": [
10+
"-v",
11+
"-s",
12+
"./tests",
13+
"-p",
14+
"test_*.py"
15+
],
16+
"python.testing.pytestEnabled": false,
17+
"python.testing.unittestEnabled": true
918
}

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## version 0.7.8
4+
5+
- fixed RPi4 using wrong gpio lib
6+
- changed init/deinit of classes
7+
38
## version 0.7.7
49

510
- fixed wrong reg adress of IOIN for TMC220X

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = PyTmcStepper
3-
version = 0.7.7
3+
version = 0.7.8
44
author = Christian Köhlke
55
author_email = christian@koehlke.de
66
description = This is a Python libary to drive a stepper motor with a Trinamic stepper driver and a single board computer like a Raspberry Pi

src/tmc_driver/_tmc_gpio_board.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ def gpio_remove_event_detect(self, pin:int):
117117
class BaseRPiGPIOWrapper(BaseGPIOWrapper):
118118
"""RPI.GPIO base wrapper"""
119119

120-
_gpios_pwm = [None] * 200
120+
def __init__(self):
121+
"""constructor"""
122+
self._gpios_pwm = [None] * 200
121123

122124
def init(self, gpio_mode=None):
123125
"""initialize GPIO library"""
@@ -185,6 +187,7 @@ class MockGPIOWrapper(BaseRPiGPIOWrapper):
185187

186188
def __init__(self):
187189
"""constructor, imports Mock.GPIO"""
190+
super().__init__()
188191
self.GPIO = import_module('Mock.GPIO')
189192
dependencies_logger.log("using Mock.GPIO for GPIO mocking", Loglevel.INFO)
190193

@@ -193,6 +196,7 @@ class RPiGPIOWrapper(BaseRPiGPIOWrapper):
193196

194197
def __init__(self):
195198
"""constructor, imports RPi.GPIO"""
199+
super().__init__()
196200
self.GPIO = import_module('RPi.GPIO')
197201
dependencies_logger.log("using RPi.GPIO for GPIO control", Loglevel.INFO)
198202

@@ -201,6 +205,7 @@ class JetsonGPIOWrapper(BaseRPiGPIOWrapper):
201205

202206
def __init__(self):
203207
"""constructor, imports Jetson.GPIO"""
208+
super().__init__()
204209
self.GPIO = import_module('Jetson.GPIO')
205210
dependencies_logger.log("using Jetson.GPIO for GPIO control", Loglevel.INFO)
206211

@@ -209,17 +214,17 @@ class OPiGPIOWrapper(BaseRPiGPIOWrapper):
209214

210215
def __init__(self):
211216
"""constructor, imports OPi.GPIO"""
217+
super().__init__()
212218
self.GPIO = import_module('OPi.GPIO')
213219
dependencies_logger.log("using OPi.GPIO for GPIO control", Loglevel.INFO)
214220

215221
class GpiozeroWrapper(BaseGPIOWrapper):
216222
"""gpiozero GPIO wrapper"""
217223

218-
_gpios = [None] * 200
219-
_gpios_pwm = [None] * 200
220-
221224
def __init__(self):
222225
"""constructor, imports gpiozero"""
226+
self._gpios = [None] * 200
227+
self._gpios_pwm = [None] * 200
223228
self.gpiozero = import_module('gpiozero')
224229
dependencies_logger.log("using gpiozero for GPIO control", Loglevel.INFO)
225230

@@ -234,16 +239,20 @@ def deinit(self):
234239
def gpio_setup(self, pin:int, mode:GpioMode, initial:Gpio=Gpio.LOW, pull_up_down:GpioPUD=GpioPUD.PUD_OFF):
235240
"""setup GPIO pin"""
236241
if mode == GpioMode.OUT:
237-
self._gpios[pin] = self.gpiozero.DigitalOutputDevice(pin, initial_value =bool(initial))
242+
if self._gpios[pin] is None or self._gpios[pin].closed:
243+
self._gpios[pin] = self.gpiozero.DigitalOutputDevice(pin, initial_value =bool(initial))
238244
else:
239-
self._gpios[pin] = self.gpiozero.DigitalInputDevice(pin)
245+
if self._gpios[pin] is None or self._gpios[pin].closed:
246+
self._gpios[pin] = self.gpiozero.DigitalInputDevice(pin)
240247

241248
def gpio_cleanup(self, pin:int):
242249
"""cleanup GPIO pin"""
243250
if self._gpios[pin] is not None:
244251
self._gpios[pin].close()
252+
self._gpios[pin] = None
245253
if self._gpios_pwm[pin] is not None:
246254
self._gpios_pwm[pin].close()
255+
self._gpios_pwm[pin] = None
247256

248257
def gpio_input(self, pin:int) -> int:
249258
"""read GPIO pin"""
@@ -314,7 +323,9 @@ def gpio_setup(self, pin:int, mode:GpioMode, initial:Gpio=Gpio.LOW, pull_up_down
314323

315324
def gpio_cleanup(self, pin:int):
316325
"""cleanup GPIO pin"""
317-
self._gpios[pin].close()
326+
if self._gpios[pin] is not None:
327+
self._gpios[pin].close()
328+
self._gpios[pin] = None
318329

319330
def gpio_input(self, pin:int) -> int:
320331
"""read GPIO pin"""
@@ -327,7 +338,7 @@ def gpio_output(self, pin:int, value):
327338

328339
board_mapping = {
329340
"raspberry pi 5": (GpiozeroWrapper, Board.RASPBERRY_PI5, "gpiozero", "https://gpiozero.readthedocs.io/en/stable/installing.html"),
330-
"raspberry": (GpiozeroWrapper, Board.RASPBERRY_PI, "RPi.GPIO", "https://sourceforge.net/p/raspberry-gpio-python/wiki/install"),
341+
"raspberry": (RPiGPIOWrapper, Board.RASPBERRY_PI, "RPi.GPIO", "https://sourceforge.net/p/raspberry-gpio-python/wiki/install"),
331342
"jetson": (JetsonGPIOWrapper, Board.NVIDIA_JETSON, "jetson-gpio", "https://github.com/NVIDIA/jetson-gpio"),
332343
"luckfox": (peripheryWrapper, Board.LUCKFOX_PICO, "periphery", "https://github.com/vsergeev/python-periphery"),
333344
"orange": (OPiGPIOWrapper, Board.ORANGE_PI, "OPi.GPIO", "https://github.com/rm-hull/OPi.GPIO")
@@ -365,16 +376,15 @@ def handle_import_error(err, board_name, module_name, install_link):
365376
Loglevel.ERROR)
366377
raise err
367378

368-
def initialize_gpio():
379+
def initialize_gpio(force_lib:Board = None) -> tuple[BaseGPIOWrapper, Board]:
369380
"""initialize GPIO"""
370381
model = get_board_model_name()
371382
dependencies_logger.log(f"Board model: {model}", Loglevel.INFO)
372383
if model == "mock":
373384
return MockGPIOWrapper(), Board.UNKNOWN
374385

375-
376386
for key, (wrapper_class, board_enum, module_name, install_link) in board_mapping.items():
377-
if key in model:
387+
if (key in model and force_lib is None) or (force_lib == module_name):
378388
try:
379389
return wrapper_class(), board_enum
380390
except ModuleNotFoundError as err:

src/tmc_driver/_tmc_logger.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ class TmcLogger:
2727
log messages from the Tmc2209 lib
2828
"""
2929

30-
_loglevel: Loglevel = Loglevel.INFO
31-
32-
3330
@property
3431
def loglevel(self):
3532
"""get the loglevel"""
@@ -55,6 +52,8 @@ def __init__(self,
5552
handlers (list): list of logging handlers, see logging.handlers (default: None)
5653
formatter (logging.Formatter): formatter for the log messages (default: None)
5754
"""
55+
self._loglevel: Loglevel = Loglevel.INFO
56+
5857
if logprefix is None:
5958
logprefix = "TMC2209"
6059

@@ -80,6 +79,16 @@ def __init__(self,
8079
self.logger.propagate = True
8180

8281

82+
def __del__(self):
83+
"""destructor"""
84+
self.deinit()
85+
86+
87+
def deinit(self):
88+
"""destructor"""
89+
self.remove_all_handlers()
90+
91+
8392
def set_logprefix(self, logprefix: str):
8493
"""set the logprefix.
8594

src/tmc_driver/_tmc_stallguard.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,25 @@ class StallGuard():
2929
This class is used to control the stallguard feature of the TMC stepper driver.
3030
The drivers class needs to inherit from this class to use the stallguard feature (mixin).
3131
"""
32-
tmc_com:TmcCom = None
3332

34-
_pin_stallguard:int = None
35-
_sg_callback:types.FunctionType = None
33+
def __init__(self):
34+
"""initialize StallGuard instance variables"""
35+
self._pin_stallguard:int = None
36+
self._sg_callback:types.FunctionType = None
3637

3738

39+
def __del__(self):
40+
self.deinit()
41+
42+
43+
def deinit(self):
44+
"""destructor"""
45+
if self._deinit_finished is False:
46+
if self._pin_stallguard is not None:
47+
tmc_gpio.gpio_remove_event_detect(self._pin_stallguard)
48+
tmc_gpio.gpio_cleanup(self._pin_stallguard)
49+
self._pin_stallguard = None
50+
3851

3952
def set_stallguard_callback(self, pin_stallguard, threshold, callback,
4053
min_speed = 100):

src/tmc_driver/_tmc_stepperdriver.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,6 @@ class TmcStepperDriver:
3030
2. move the motor via STEP/DIR pins
3131
"""
3232

33-
BOARD:Board = BOARD
34-
tmc_mc:TmcMotionControl = None
35-
tmc_ec:TmcEnableControl = None
36-
tmc_logger:TmcLogger = None
37-
38-
39-
_deinit_finished:bool = False
40-
41-
4233

4334
# Constructor/Destructor
4435
# ----------------------------
@@ -69,6 +60,13 @@ def __init__(self,
6960
Defaults to None (messages are logged in the format
7061
'%(asctime)s - %(name)s - %(levelname)s - %(message)s').
7162
"""
63+
self.BOARD:Board = BOARD
64+
self.tmc_mc:TmcMotionControl = None
65+
self.tmc_ec:TmcEnableControl = None
66+
self.tmc_logger:TmcLogger = None
67+
68+
self._deinit_finished:bool = False
69+
7270
if logprefix is None:
7371
logprefix = "StepperDriver"
7472
self.tmc_logger = TmcLogger(loglevel, logprefix, log_handlers, log_formatter)
@@ -94,6 +92,11 @@ def __init__(self,
9492

9593

9694
def __del__(self):
95+
self.deinit()
96+
97+
98+
99+
def deinit(self):
97100
"""destructor"""
98101
if self._deinit_finished is False:
99102
self.tmc_logger.log("Deinit", Loglevel.INFO)
@@ -105,11 +108,11 @@ def __del__(self):
105108
else:
106109
self.tmc_logger.log("Deinit already finished", Loglevel.INFO)
107110
if self.tmc_ec is not None:
108-
del self.tmc_ec
111+
self.tmc_ec.deinit()
109112
if self.tmc_mc is not None:
110-
del self.tmc_mc
113+
self.tmc_mc.deinit()
111114
if self.tmc_logger is not None:
112-
del self.tmc_logger
115+
self.tmc_logger.deinit()
113116

114117

115118
# TmcEnableControl Wrapper

src/tmc_driver/com/_tmc_com.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,6 @@ def compute_crc8_atm(datagram, initial_value=0):
3636
class TmcCom:
3737
"""TmcCom
3838
"""
39-
_tmc_logger:TmcLogger = None
40-
_tmc_registers = None
41-
42-
mtr_id:int = 0
43-
r_frame:List[int]
44-
w_frame:List[int]
45-
communication_pause:int = 0
46-
error_handler_running:bool = False
47-
4839
@property
4940
def tmc_logger(self):
5041
"""get the tmc_logger"""
@@ -69,7 +60,7 @@ def tmc_registers(self, tmc_registers):
6960

7061
def __init__(self,
7162
mtr_id:int = 0,
72-
tmc_logger = None
63+
tmc_logger:TmcLogger = None
7364
):
7465
"""constructor
7566
@@ -79,6 +70,13 @@ def __init__(self,
7970
"""
8071
self._tmc_logger = tmc_logger
8172
self.mtr_id = mtr_id
73+
self._tmc_registers = None
74+
75+
self.mtr_id:int = 0
76+
# self.r_frame:List[int]
77+
# self.w_frame:List[int]
78+
self.communication_pause:int = 0
79+
self.error_handler_running:bool = False
8280

8381

8482
# def init(self):

src/tmc_driver/com/_tmc_com_spi.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,13 @@ class TmcComSpi(TmcCom):
3737
like the current or the microsteppingmode
3838
"""
3939

40-
spi = spidev.SpiDev()
41-
_spi_bus: int
42-
_spi_dev: int
43-
_spi_speed: int
40+
4441

4542

4643

4744
def __init__(self,
48-
spi_bus,
49-
spi_dev,
45+
spi_bus:int,
46+
spi_dev:int,
5047
spi_speed:int = 8000000,
5148
mtr_id:int = 0,
5249
tmc_logger = None
@@ -59,6 +56,8 @@ def __init__(self,
5956
"""
6057
super().__init__(mtr_id, tmc_logger)
6158

59+
self.spi = spidev.SpiDev()
60+
6261
self._spi_bus = spi_bus
6362
self._spi_dev = spi_dev
6463
self._spi_speed = spi_speed
@@ -85,6 +84,10 @@ def init(self):
8584

8685

8786
def __del__(self):
87+
self.deinit()
88+
89+
90+
def deinit(self):
8891
"""destructor"""
8992

9093

src/tmc_driver/com/_tmc_com_uart.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ class TmcComUart(TmcCom):
2121
like the current or the microsteppingmode
2222
"""
2323

24-
ser:serial.Serial = serial.Serial()
25-
26-
2724
def __init__(self,
2825
serialport:str ,
2926
baudrate:int = 115200,
@@ -40,6 +37,8 @@ def __init__(self,
4037
"""
4138
super().__init__(mtr_id, tmc_logger)
4239

40+
self.ser = serial.Serial()
41+
4342
if serialport is None:
4443
return
4544

@@ -86,6 +85,10 @@ def init(self):
8685

8786

8887
def __del__(self):
88+
self.deinit()
89+
90+
91+
def deinit(self):
8992
"""destructor"""
9093
if self.ser is not None and isinstance(self.ser, serial.Serial):
9194
self.ser.close()

0 commit comments

Comments
 (0)