Package: micropython-servo-pdm-360
This is an automatic translation, may be incorrect in some places.Servo PDM ContinuousA library for controlling continuous rotation servo drives via the PWM interface of the Raspberry Pi Pico microcontroller in MicroPython.Library features:Rotation with a given force and directionRotation within the specified timePossibility of soft start and stopAbility 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:MaterialPrinciple of operation of constant rotation servos, 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.ContentInstallationInitializationDocumentationExamplesBugs and feedbackInstallationInstall the library via pip (Thonny -> Manage Packages) by namemicropython-servo-pdm-360Or manual installation:Download library from GitHubtake themicropython_servo_pdm_360folder 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_pdm_360importServoPDM360# 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=400max_us=2550dead_zone_us=150# create a servo objectservo=ServoPDM360(pwm=servo_pwm,min_us=min_us,max_us=max_us,dead_zone_us=dead_zone_us,freq=freq)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_pdm_360importServoPDM360RP2Async# 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=1350max_us=8450dead_zone_us=300# create a servo objectservo=ServoPDM360RP2Async(pwm=servo_pwm,min_us=min_us,max_us=max_us,dead_zone_us=dead_zone_us,freq=freq)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_pdm_360importServoPDM360RP2Irq# 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=400max_us=2550dead_zone_us=150# create a servo objectservo=ServoPDM360RP2Irq(pwm=servo_pwm,min_us=min_us,max_us=max_us,dead_zone_us=dead_zone_us,freq=freq)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. According to the pulse time, you can set the force and direction of rotation of the servo.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 begins to rotate in one direction.max_us- maximum pulse time at which the servo stops rotating in the other direction.dead_zone_us- duration of the central zone in which the servo does not rotate. This is the transition zone between the two directions of rotation.Below I tried to graphically represent these parameters for the MG995_360 analog servo:As we can see in the figure, the servo begins to rotate at a pulse width of 400 µs, and stops rotating at 2600 µs.
Thus, we get the parametersmin_us=400andmax_us=2550(2600 - 50, since at 2600 the drive has already stopped). Now we need to find the duration of the central zone.
The figure shows that at a pulse length of 1450 µs, the servo stops rotating clockwise and stops.
Further, at a pulse length of 1600 μs, the rotation in the opposite direction begins. Thus the parameterdead_zone_us=150(1600-1450).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.
If not, we pick them up manually using theset_dutymethod and giving different values from 0 to 3000 µs, in 50 µs increments.
An example of such a configuration can be found in the examples folder filemanual_config.py.List of parameters for servos:MG995_360-min_us=400,max_us=2550,dead_zone_us=150,freq=50PLEASE:If you find parameters for a servo that are not listed, submit them to me viaissue.ServoPDM360 constructor parametersServoPDM360RP2AsyncandServoPDM360RP2Irqinherit it and have the same parametersParameterTypeDefaultDescriptionpwmPWMNonePWM controllermin_usint500Minimum impulse timemax_usint3000Maximum pulse timedead_zone_usint150Duration of the central zonefreqint50Pulse frequencyinvertboolfalseDirection inversionpwm-PWMcontroller object.min_us- Minimum pulse time (duty cycle)More.max_us- Maximum pulse time (duty cycle)Moredead_zone_us- Central zone durationMorefreq- Pulse frequency, for analog drives it is 50. Digital drives are usually 300 or more.invert- Invert direction (maybe needed for some drives, maybe not :) )ServoPDM360 base class methodsset_duty(duty: int)- Sets an arbitrary value of the duty cycle in the range from 0 to 65000.
This method is intended for manual search of the minimum and maximum duty cycle values.Moreturn_cv(force: int)- Starts rotation of the drive clockwise with the given acceleration.turn_ccv(force: int)- Starts the drive turning counterclockwise at the given acceleration.stop()- Stops the rotation of the drive.deinit()- Disables the PWM generator.ServoPDM360RP2Async and ServoPDM360RP2Irq class methodsturn_cv_ms(...)- Rotates the drive clockwise with various parameters.turn_ccv_ms(...)- Rotates the drive counterclockwise with various parameters.ParameterTypeDefaultDescriptiontime_msint0Rotation Time (0 - Infinite)forceintNoneEffort, if not specified, is taken fromstart_smoothingstart_smoothingServoSmoothBaseNoneStart deceleration, if the start is not specified, it will be instantaneousend_smoothingServoSmoothBaseNoneDecelerate stop, if not specified stop will be instantcallbackcallableNoneThe function that will be called after the end of the command. Iftime_ms== 0 then after overclockingsmooth- Smooth stop of the drive.ParameterTypeDefaultDescriptionend_smoothingServoSmoothBaseNoneStop slowdowncallbackcallableNoneThe 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_pdm_360importServoPDM360RP2Async,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=400max_us=2550dead_zone_us=150# create a servo objectservo=ServoPDM360RP2Async(pwm=servo_pwm,min_us=min_us,max_us=max_us,dead_zone_us=dead_zone_us,freq=freq)# Rotate the actuator clockwise for two seconds with a force of 50 and decelerate at the beginning. After output to the console "callback cv"servo.turn_cv_ms(2000,50,start_smoothing=SmoothLinear(50,1000),callback=lambda:print("callback cv"))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!