Package: micropython-servo-pdm
Servo PDM ContinuousA library for controlling servos through the PWM interface of the Raspberry Pi Pico microcontroller in MicroPython.Library features:Rotate by specified angleSmooth change of the angle of rotationCancel hold angleAbility to use thesmooth-servolibrary to change the smooth start and stop algorithmAll pending work happens in the background, with two processing options:Using an asyncio task (recommended)Interrupt timerIf you don't need all the functionality listed above, then you should take a look at themicropython-servolibrary.
It is much smaller and better suited for simple tasks.The following materials were used in the development of the library:MaterialPDM servos with angle hold), author amperka.ruMaterialServo Motor with Raspberry Pi Pico using MicroPythonby microcontrollerslab.comMaterialHobby Servo Tutorialby MIKEGRUSIN and BYRON J. (sparkfun.com)CompatibilityMicroPython 1.19.1Raspberry Pi PicoOn the hardware above the library has been tested and works correctly.ATTENTIONYou use this module at your own risk.
I am new to MicroPython programming. So there may be nuances that I did not take into account.
If you notice an error or have suggestions for improvement, please write to Issues.InstallationInstall the library via pip (Thonny -> Manage Packages) by namemicropython-servo-pdmOr manual installation:Download library from GitHubtake themicropython_servo_pdmfolder from the archive.upload to the root of the microcontroller or to thelibfolder.If you want to play around with the logic of the library, then the 2nd installation option is preferable. :)InitializationInitializing the base libraryfrommachineimportPin,PWMfrommicropython_servo_pdmimportServoPDM# create a PWM servo controller (21 - pin Pico)servo_pwm=PWM(Pin(21))# Set the parameters of the servo pulses, more details in the "Documentation" sectionfreq=50min_us=500max_us=2500max_angle=180min_angle=0# create a servo objectservo=ServoPDM(pwm=servo_pwm,min_us=min_us,max_us=max_us,freq=freq,max_angle=max_angle,min_angle=min_angle)After that,basic methodsof controlling the servo will be available to you, which do not require pending tasks.To access additional methods that require deferred execution, you need to initialize one of the child classes.
Depending on which of the ways you prefer to handle pending tasks:Using the uasyncio libraryThis is the best option for most projects.frommachineimportPin,PWMfrommicropython_servo_pdmimportServoPDMRP2Async# create a PWM servo controller (21 - pin Pico)servo_pwm=PWM(Pin(21))# Set the parameters of the servo pulses, more details in the "Documentation" sectionfreq=50min_us=500max_us=2500max_angle=180min_angle=0# create a servo objectservo=ServoPDMRP2Async(pwm=servo_pwm,min_us=min_us,max_us=max_us,freq=freq,max_angle=max_angle,min_angle=min_angle)Using timer interruptsYou can read more about timershereFor Raspberry Pi PicohereBe careful, although this is the easiest option, it is not optimal.
Since the handling of servo events occurs in a timer interrupt, other interrupts will be delayed.frommachineimportPin,PWMfrommicropython_servo_pdmimportServoPDMRP2Irq# create a PWM servo controller (21 - pin Pico)servo_pwm=PWM(Pin(21))# Set the parameters of the servo pulses, more details in the "Documentation" sectionfreq=50min_us=500max_us=2500max_angle=180min_angle=0# create a servo objectservo=ServoPDMRP2Irq(pwm=servo_pwm,min_us=min_us,max_us=max_us,freq=freq,max_angle=max_angle,min_angle=min_angle)DocumentationA little about PDMPDM(pulse-duration modulation) is a process of power control by pulsing the power consumer on and off. By Wikipedia®
In our case, it is used to control the servo. By the time of the pulse, you can set the position of the servo shaft.ATTENTION:Unlike PWM, the control is not based on frequency, but on the duration of the pulse.
You can read more here (with pictures):wiki.amperka.ruFor the correct operation of the servo, we need to set the following parameters:freq- pulse frequency, for analog servos 50 Hz. For digital 300 Hz or more.min_us- minimum pulse time at which the servo goes to themin_anglepoint.max_us- maximum pulse time at which the servo goes to themax_anglepoint.min_angle- minimum servo rotation angle.max_angle- maximum servo rotation angle.
It should be noted that the parametersmin_angleandmax_angleset the working area of the servo.
Those. if the servo can rotate from 0 to 180 degrees, then it is not necessary to setmin_angle=0, max_angle=180,
it could be:min_angle=-90, max_angle=90,min_angle=180, max_angle=0or so on.Where can I get these parameters for a specific servo? It all depends on the manufacturer. But in most cases they are specified in the documentation.
But there may also be inaccuracies, for example, there is a driveMG90Sthe documentation states that the minimum pulse time is ~1ms, and the maximum is ~2ms.
But in practice it is 0.5ms and 2.5ms (actually 0.35ms and 2.65ms, but these are extreme points outside the operating range of 180 degrees).
So I recommend checking these parameters manually using theset_dutymethod.
How to do manual configuration is in the examples folder the filemanual_config.pyandencoder_config.py.List of parameters for servos:MG90S-min_us=500,max_us=2500,freq=50,min_angle=0,max_angle=180SG90-min_us=600,max_us=2500,freq=50,min_angle=0,max_angle=180MG995-min_us=500,max_us=2400,freq=50,min_angle=0,max_angle=180PLEASE:If you find parameters for a servo that are not listed, submit them to me viaissue.ServoPDM constructor parametersServoPDMRP2AsyncandServoPDMRP2Irqinherit it and have the same parametersParameterTypeDefaultDescriptionpwmPWMNonePWM controllermin_usint1000Minimum pulse timemax_usint9000Maximum pulse timemin_angleint0Minimum rotation anglemax_angleint180Maximum rotation anglefreqint50Pulse frequencyinvertboolFalseDirection inversionpwm-PWMcontroller object.min_us- Minimum pulse time (duty cycle)More.max_us- Maximum pulse time (duty cycle)Moremin_angle,max_angle- Conditional range of servo operation. You can set any values depending on your tasks and the capabilities of the servo.freq- Pulse frequency, for analog drives it is 50. Digital drives are usually 300 or more.invert- Invert the direction of the servo. IfTruethen the servo will rotate in the opposite direction.ServoPDM base class methodsset_duty(duty_us: int)- Sets an arbitrary value of the pulse duration in microseconds, from 0 to(1000 // freq) * 1000.
This method is intended for manual search of the minimum and maximum duty cycle values.Moreset_angle(angle: int)- Sets the angle of the servo, in the rangemin_angle < angle < max_angle(ormax_angle < angle < min_angleifmin_angle > max_angle).release()- Sets the pulse duration to 0, thus disabling position holding by the servo.deinit()- Disables PWM generation.ServoPDMRP2Async and ServoPDMRP2Irq class methodsWell, one method, to be precise :).move_to_angle(...)- Smoothly moves the servo to the specified angle.ParameterTypeDefaultDescriptionangleIntNoneEnd angle of rotationtime_msIntNoneMove timestart_smoothingtype(ServoSmoothBase)SmoothLinearEase class to be used for movementcallbackcallableNoneThe function that will be called after the end of the command.SlowdownsTo control slowdowns, you can use theServoSmoothBaseclasses and its descendants.
This library only hasSmoothLinearlinear deceleration, if you need more, install thesmooth-servolibrary.
An example of using built-in easing:frommachineimportPin,PWMfrommicropython_servo_pdmimportServoPDMRP2Async,SmoothLinear# create a PWM servo controller (21 - pin Pico)servo_pwm=PWM(Pin(21))# Set the parameters of the servo pulses, more details in the "Documentation" sectionfreq=50min_us=500max_us=2500max_angle=180min_angle=0# create a servo objectservo=ServoPDMRP2Async(pwm=servo_pwm,min_us=min_us,max_us=max_us,freq=freq,max_angle=max_angle,min_angle=min_angle)# Повернуть сервопривод до отметки в 50 градусов за 2 секунды используя линейное замедление. После вывести в консоль "callback cv"servo.move_to_angle(50,2000,SmoothLinear,callback=lambda:print("callback move_to_angle"))Details about the parameters and types of slowdowns can be found in thesmooth_servo documentation.ExamplesUsage examples can be found in theexamplesfolder.Bugs and feedbackIf you find bugs, createissueThe library is open for further development and yourpull requests!