Source code for hardware.tlc59711_pwm_controller

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2020-2025 by Murray Altheim. All rights reserved. This file is part
# of the Robot Operating System project, released under the MIT License. Please
# see the LICENSE file included as part of this package.
#
# author:   Murray Altheim
# created:  2025-06-08
# modified: 2025-06-09
#

import time
from colorama import init, Fore, Style
init()

from core.logger import Logger, Level
from hardware.pwm_controller import PWMController
from hardware.tlc59711 import TLC59711
from hardware.controller_channel import ControllerChannel

# ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
[docs] class TLC59711PWMController(PWMController): ''' Implements the PWMController API using the Adafruit 12-channel 16-bit PWM controller board with the TLC59711 chip for motor control. ''' def __init__(self, pi, config: dict, pwm_controller: TLC59711, channel: ControllerChannel, level=Level.INFO): ''' Initialize the TLC59711PWMController with a specified channel and TLC59711 instance. Note that the PWM signal is inverted: 0% duty cycle is full speed, 100% is stopped. :param pi: pigpio pi instance :param pwm_controller: instance of TLC59711 PWM controller :param channel: motor control channel (0-11) :param level: logging level (default INFO) ''' self._log = Logger('tlc-pwm-ctrl', level=level) self._pi = pi self._config = config _cfg = config['kros'].get('hardware').get('motor_controller') self._verbose = _cfg.get('verbose', True) self._pwm_controller = pwm_controller self._channel = channel.channel self._pin_name = channel.pin self._stopped = 65535 # 100% duty (motor stopped) self._full_speed = 0 # 0% duty (full speed) self._log.info('TLC59711 PWM controller initialized on pin {} (channel {}).'.format(self._pin_name, self._channel))
[docs] def set_pwm(self, speed): ''' Set the motor speed by adjusting the PWM duty cycle. Note that direction is not indicated by a negative number but changing the value of the direction pin, therefore it's not handled here. :param speed: target speed as a percentage (0-100) ''' if not (0 <= speed <= 100): raise ValueError('speed must be between 0 and 100.') pwm_value = int(self._full_speed + (self._stopped - self._full_speed) * (speed / 100)) if self._verbose: self._log.info('set speed for channel {}:'.format(self._channel) + Fore.GREEN + ' {:>6.2f}% '.format(speed) + Fore.CYAN + Style.DIM + ' -> PWM value: {}'.format(pwm_value)) # update the TLC59711's pixel values (maps to RGB values) red_value = green_value = blue_value = pwm_value self._pwm_controller[self._channel] = (red_value, green_value, blue_value)
[docs] def stop_pwm(self): ''' Stop the PWM output by setting all RGB values to zero (off). ''' self._log.debug('stopping PWM for channel {}'.format(self._channel)) self._pwm_controller[self._channel] = (0, 0, 0)
[docs] def stop(self): ''' Stop the motor by turning off the PWM signal. ''' self.stop_pwm() self._log.info('Motor stopped on channel {}'.format(self._channel))
#EOF