Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PCA9685 I2C PWM Driver #35

Open
4 tasks
Tracked by #30
Mikefly123 opened this issue Oct 21, 2024 · 0 comments
Open
4 tasks
Tracked by #30

PCA9685 I2C PWM Driver #35

Mikefly123 opened this issue Oct 21, 2024 · 0 comments
Labels
new component Creating a new component for this task sensor Relating to a sensor implementation

Comments

@Mikefly123
Copy link
Member

Mikefly123 commented Oct 21, 2024

What Does This Component Do?

The PCA9685 is used to toggle power to the sensors on each face of the satellite. This gives us the ability to power cycle them (in case of needing to clear a latch or something) and also save power by powering down these faces when they are not in use.

  • Detect the I2C Device on the Bus
  • Set the duty cycle of each face to either maximum (4096) or off (0)
  • Log the on / off status of each Face power rail
  • Command SLEEP and WAKE

Like with the other power related stuff we mainly just want this component to interface with the sensor and toggle lines on and off. Logic for actually controlling when that happens will come in the form of a Power Manger Component.

Design Notes

Adafruit C++ Library
Adafruit Library Reference

Because of some rather annoying design decisions when moving from the PROVES Kit V1 to V1.5 the sensor data for the satellite faces is piped to the FC Board while the power control was handed over to the Battery Board. Also, the PCA is on an entirely separate board! And it turns out that it is rather power inefficient for a load switching application. So overall, quite a rough state of affairs.

In V2 of the PROVES Kit we'll probably either replace this with a GPIO expander or use it only to drive a bank of load switches rather than directly supplying power to the faces through it.

Example CircuitPython Implementation

import adafruit_pca9685  # LED Driver
...
class Satellite:
...
    # Turns all of the Faces On (Defined before init because this fuction is called by the init)
    def all_faces_on(self):
        # Faces MUST init in this order or the uController will brown out. Cause unknown
        if self.hardware["FLD"]:
            self.Face0.duty_cycle = 0xFFFF
            self.hardware["Face0"] = True
            self.Face1.duty_cycle = 0xFFFF
            self.hardware["Face1"] = True
            self.Face2.duty_cycle = 0xFFFF
            self.hardware["Face2"] = True
            self.Face3.duty_cycle = 0xFFFF
            self.hardware["Face3"] = True
            self.Face4.duty_cycle = 0xFFFF
            self.hardware["Face4"] = True
            self.cam.duty_cycle = 0xFFFF

    def all_faces_off(self):
        # De-Power Faces
        if self.hardware["FLD"]:
            self.Face0.duty_cycle = 0x0000
            time.sleep(0.1)
            self.hardware["Face0"] = False
            self.Face1.duty_cycle = 0x0000
            time.sleep(0.1)
            self.hardware["Face1"] = False
            self.Face2.duty_cycle = 0x0000
            time.sleep(0.1)
            self.hardware["Face2"] = False
            self.Face3.duty_cycle = 0x0000
            time.sleep(0.1)
            self.hardware["Face3"] = False
            self.Face4.duty_cycle = 0x0000
            time.sleep(0.1)
            self.hardware["Face4"] = False
            time.sleep(0.1)
            self.cam.duty_cycle = 0x0000
...
    def __init__(self):
        # Initialize LED Driver
        try:
            self.faces = adafruit_pca9685.PCA9685(self.i2c0, address=int(0x56))
            self.faces.frequency = 2000
            self.hardware["FLD"] = True
        except Exception as e:
            self.debug_print(
                "[ERROR][LED Driver]" + "".join(traceback.format_exception(e))
            )

        # Initialize all of the Faces and their sensors
        try:
            self.Face0 = self.faces.channels[0]
            self.Face1 = self.faces.channels[1]
            self.Face2 = self.faces.channels[2]
            self.Face3 = self.faces.channels[3]
            self.Face4 = self.faces.channels[4]
            self.cam = self.faces.channels[5]
            self.all_faces_on()
        except Exception as e:
            self.debug_print(
                "ERROR INITIALIZING FACES: " + "".join(traceback.format_exception(e))
            )
...
    # =======================================================#
    # Getting and Setting Power for Individual Faces        #
    # =======================================================#
    @property
    def Face0_state(self):
        return self.hardware["Face0"]

    @Face0_state.setter
    def Face0_state(self, value):
        if self.hardware["FLD"]:
            if value:
                try:
                    self.Face0 = 0xFFFF
                    self.hardware["Face0"] = True
                    self.debug_print("z Face Powered On")
                except Exception as e:
                    self.debug_print(
                        "[WARNING][Face0]" + "".join(traceback.format_exception(e))
                    )
                    self.hardware["Face0"] = False
            else:
                self.Face0 = 0x0000
                self.hardware["Face0"] = False
                self.debug_print("z+ Face Powered Off")
        else:
            self.debug_print("[WARNING] LED Driver not initialized")
...

Required Hardware

  • Battery Board V3 or higher
  • Mux Driver Board V1 (if using a Battery Board V3a or higher)
  • Z- Solar Panel Board (for interfacing with the Mux Driver Board V1)

Reference Schematic

Screenshot 2024-10-22 at 6 36 07 PM
@Mikefly123 Mikefly123 mentioned this issue Oct 21, 2024
12 tasks
@Mikefly123 Mikefly123 added sensor Relating to a sensor implementation new component Creating a new component for this task labels Oct 21, 2024
@Mikefly123 Mikefly123 added this to the fprime-proves-v1.0 milestone Oct 21, 2024
@Mikefly123 Mikefly123 added the draft Currently being drafted label Oct 21, 2024
@Mikefly123 Mikefly123 changed the title PCA9686 I2C PWM Driver PCA9685 I2C PWM Driver Oct 23, 2024
@Mikefly123 Mikefly123 removed the draft Currently being drafted label Oct 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new component Creating a new component for this task sensor Relating to a sensor implementation
Projects
None yet
Development

No branches or pull requests

1 participant