This is both a port of Adafruit's Arduino library for the PCA9685 (Adafruit Library) for the Raspberry Pi Pico board and an improvement on the PCA9685 Servo Controller library for Pi Pico (PCA9685 Servo Controller).
Please note it is not a Micropython library (as those have been released by Adafruit Circuitpython library), but a library meant to be used with Pi Pico C/C++ SDK.
Please find doxygen docs here Doxygen docs.
Copy the repository into your project. Include two files in your main cpp file:
#include <PCA9685_servo_driver.h>
#include <PCA9685_servo.h>
Add a subdirectory:
add_subdirectory(Adafruit-Servo-Driver-Library-Pi-Pico) # the argument represents a path to the library directory
Then include the library directory:
target_include_directories(${PROJECT_NAME}
PRIVATE Adafruit-Servo-Driver-Library-Pi-Pico # the argument represents a path to the library directory
)
Lastly, link the library:
target_link_libraries(${PROJECT_NAME}
Adafruit-Servo-Driver-Library-Pi-Pico # the argument represents the name of the library, as specified in the CMakeLists.txt in the library directory
)
- Create an object of PCA9685_servo_driver type to serve as your interface with the PCA9685 board.
PCA9685_servo_driver myController(i2c0);
- Create an object(s) (depending on the number of servos that are being driven) of PCA9685_servo type to keep track of the servo's parameters and movement.
std::vector<PCA9685_servo> myServo = {PCA9685_servo(&myController, 0, 100, 540)};
- Initialize the servo:
- set the angle range with
setRange()
, - set operation mode with
setMode()
, - set initial position with
setPosition()
, - set channel number on the board with
setAddress()
, - set duration of movement in constant time mode with
setTConstantDuration()
.
- set the angle range with
- In the main() loop, initialize the connection to the PCA9685 with
myController.begin();
.
Create a loop in which PCA9685_servo.loop() method will be called for each of the controlled servos. Into the loop() method pass an argument with time elapsed since last loop iteration (to keep track of when to move the servo).
while(1)
{
TEllapsed = TNow - TPrevious;
for(auto& servo : myServo) servo.loop(TEllapsed);
}
There are 3 modes:
MODE_FAST
- moves to the set position immediately, with maximum speed (part of the PCA9685_servo class as _TFastDuration),MODE_TCONSTANT
- the movement takes exactly _TConstantDuration microseconds, independent of the length of the movement,MODE_SCONSTANT
- the servo moves with a set angular velocity (set with setAngularVelocity()), which means the servo moves one degree after _SConstantPeriod microseconds.
Select a mode with setMode()
method.
In order to move the servo, it first needs to get its position changed with setPosition()
or setRelativePosition()
methods. The argument passed is the position to move to in degrees. It takes effect immediately.
In order to change the speed, use the setAngularVelocity()
method, providing velocity in deg/s. It changes the speed in both MODE_SCONSTANT and MODE_TCONSTANT modes.
In order to change the movement time, use changeSpeedConstT()
.
After setting the position, it is necessary to call the loop()
method repeatedly in order to execute the movement. It needs an argument that counts the time between the last call to the loop()
and now in microseconds.
Each servo keeps track of itself, it's possible to retrieve these states through e.g.:
getPosition()
retrieves current position in degrees,isMoving()
is the servo moving or not.
Each servo can call a function on start or end of movement through binding to function pointer. E.g.
void StopMoveHandler(uint16_t Address) { INTERNAL_LED(0); }
servo.onStopMove = StopMoveHandler;
In order to properly control the servo, its PWM pulse length count has to be determined. The usual range lies within (100-600), but please find the one matching your particular servo. The best way to do this is by manually changing the lower and upper range by a little bit until it matches the (-90, 90) degree range.
A simple example can be found in the examples
directory alongside a sample CMakeLists.txt file.
At the moment there are not any known problems or bugs, please feel free to report them.