The ServoHat is a shield for Raspberry Pi that is based on the PCA9685 controller. The PCA9685 module is a 16 channel controller that allows you to drive 16 PWM outputs via I2C communication. It allows among other things to free inputs and outputs of your microcontroller and drive up to 16 LEDs or servomotors (or any other module taking a PWM signal as input) using two pins (SCL and SDA) while keeping the pins of your microcontroller for other modules like sensors.

Material
- Computer
- Rapsberry Pi 3B+
- ServoHAT
Principle of operation
The module is based on the PCA9685 controller which allows to drive PWM outputs using I2C communication and an integrated clock. This module has 6 bridges allowing to select the address of the board and to place on the same bus up to 62 controllers for a total of 992 servomotors (available addresses 0x40 to 0x7F). It allows to drive PWM outputs with an adjustable frequency and with a 12 bits resolution.
Scheme
The ServoHAT is placed directly on the connector of the Raspberry Pi. It is preferable to use spacers to fix the shield to the microcontroller and not to damage the pins of the connector. The ServoHAT uses the I2C bus of the RaspberryPi, i.e. the GPIO2 and 3 pins (SDA and SCL, respectively).

Code
The ServoHAT is used in the same way as the PCA9685 module with the adafruit_servokit library.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Libraries
import time #https://docs.python.org/fr/3/library/time.html
from adafruit_servokit import ServoKit #https://circuitpython.readthedocs.io/projects/servokit/en/latest/
#Objects
pca = ServoKit(channels=16)
# function init
def init():
for i in range(nbPCAServo):
pca.servo[i].set_pulse_width_range(MIN_IMP[i] , MAX_IMP[i])
# function main
def main():
pcaScenario()
# function pcaScenario
def pcaScenario():
"""Scenario to test servo"""
for i in range(nbPCAServo):
for j in range(MIN_ANG[i],MAX_ANG[i],1):
print("Send angle {} to Servo {}".format(j,i))
pca.servo[i].angle = j
time.sleep(0.01)
for j in range(MAX_ANG[i],MIN_ANG[i],-1):
print("Send angle {} to Servo {}".format(j,i))
pca.servo[i].angle = j
time.sleep(0.01)
pca.servo[i].angle=None #disable channel
time.sleep(0.5)
if __name__ == '__main__':
init()
main()
Applications
- Controlling the Quadrina6 robot
Sources
- http://adafruit.github.io/Adafruit-PWM-Servo-Driver-Library/html/class_adafruit___p_w_m_servo_driver.html#aa892432ed08e4b3892c8eb0478168dd8
- https://robojax.com/learn/arduino/robojax-PCA6985.pdf
- https://www.nxp.com/products/power-management/lighting-driver-and-controller-ics/ic-led-controllers/16-channel-12-bit-pwm-fm-plus-ic-bus-led-controller:PCA9685
- https://docs.python.org/fr/3/library/time.html
- https://circuitpython.readthedocs.io/projects/servokit/en/latest/