{"id":16000625,"url":"https://github.com/ttitanua/micropython_servo_pdm","last_synced_at":"2025-07-29T03:40:54.879Z","repository":{"id":65971684,"uuid":"603700080","full_name":"TTitanUA/micropython_servo_pdm","owner":"TTitanUA","description":"A library for controlling servos through the PWM interface of the Raspberry Pi Pico microcontroller in MicroPython.","archived":false,"fork":false,"pushed_at":"2023-02-19T13:09:32.000Z","size":20,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-17T03:25:35.652Z","etag":null,"topics":["mg90s","mg995","micropython","raspbery-pi-pico","servo","sg90"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TTitanUA.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-19T10:15:52.000Z","updated_at":"2024-11-27T11:16:29.000Z","dependencies_parsed_at":null,"dependency_job_id":"88e07778-0bba-4dd8-8427-0348a9d479db","html_url":"https://github.com/TTitanUA/micropython_servo_pdm","commit_stats":{"total_commits":3,"total_committers":2,"mean_commits":1.5,"dds":"0.33333333333333337","last_synced_commit":"7533541f73b0968d43cd672c37eda86c8421a4b8"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/TTitanUA/micropython_servo_pdm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TTitanUA%2Fmicropython_servo_pdm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TTitanUA%2Fmicropython_servo_pdm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TTitanUA%2Fmicropython_servo_pdm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TTitanUA%2Fmicropython_servo_pdm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TTitanUA","download_url":"https://codeload.github.com/TTitanUA/micropython_servo_pdm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TTitanUA%2Fmicropython_servo_pdm/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267624657,"owners_count":24117476,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mg90s","mg995","micropython","raspbery-pi-pico","servo","sg90"],"created_at":"2024-10-08T09:05:13.312Z","updated_at":"2025-07-29T03:40:54.826Z","avatar_url":"https://github.com/TTitanUA.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![pypi version shield](https://img.shields.io/pypi/v/micropython-servo-pdm)](https://pypi.org/project/micropython-servo-pdm/) \n[![pypi downloads per month shield](https://img.shields.io/pypi/dm/micropython-servo-pdm?color=brightgreen)](https://pypi.org/project/micropython-servo-pdm/)\n# Servo PDM Continuous\nA library for controlling servos through the PWM interface of the Raspberry Pi Pico microcontroller in MicroPython.\n\nLibrary features:\n- Rotate by specified angle\n- Smooth change of the angle of rotation\n- Cancel hold angle\n- Ability to use the [smooth-servo](https://pypi.org/project/smooth-servo/) library to change the smooth start and stop algorithm\n- All pending work happens in the background, with two processing options:\n     - Using an asyncio task (recommended)\n     - Interrupt timer\n\nIf you don't need all the functionality listed above, then you should take a look at the [micropython-servo](https://pypi.org/project/micropython-servo/) library.\nIt is much smaller and better suited for simple tasks.\n\nThe following materials were used in the development of the library:\n- Material [PDM servos with angle hold](http://wiki.amperka.ru/articles:servo-pdm-standard)), author amperka.ru\n- Material [Servo Motor with Raspberry Pi Pico using MicroPython](https://microcontrollerslab.com/servo-motor-raspberry-pi-pico-micropython/) by microcontrollerslab.com\n- Material [Hobby Servo Tutorial](https://learn.sparkfun.com/tutorials/hobby-servo-tutorial?_ga=2.2724022.723022425.1676642363-1173110823.1674579241) by MIKEGRUSIN and BYRON J. (sparkfun.com)\n\n### Compatibility\n- MicroPython 1.19.1\n- Raspberry Pi Pico\n\nOn the hardware above the library has been tested and works correctly.\n\n### ATTENTION\nYou use this module at your own risk.\nI am new to MicroPython programming. So there may be nuances that I did not take into account.\nIf you notice an error or have suggestions for improvement, please write to Issues.\n\n\u003ca name=\"install\"\u003e\u003c/a\u003e\n## Installation\n- Install the library via pip (Thonny -\u003e Manage Packages) by name **micropython-servo-pdm**\n- Or manual installation:\n   - [Download library from GitHub](https://github.com/TTitanUA/micropython_servo_pdm)\n   - take the **micropython_servo_pdm** folder from the archive.\n   - upload to the root of the microcontroller or to the **lib** folder.\n\nIf you want to play around with the logic of the library, then the 2nd installation option is preferable. :)\n\n\u003ca name=\"init\"\u003e\u003c/a\u003e\n## Initialization\n### Initializing the base library\n```python\nfrom machine import Pin, PWM\nfrom micropython_servo_pdm import ServoPDM\n\n# create a PWM servo controller (21 - pin Pico)\nservo_pwm = PWM(Pin(21))\n\n# Set the parameters of the servo pulses, more details in the \"Documentation\" section\nfreq = 50\nmin_us = 500\nmax_us = 2500\nmax_angle = 180\nmin_angle = 0\n\n# create a servo object\nservo = ServoPDM(pwm=servo_pwm, min_us=min_us, max_us=max_us, freq=freq, max_angle=max_angle, min_angle=min_angle)\n```\nAfter that, [basic methods](https://github.com/TTitanUA/micropython_servo_pdm#doc_base) of controlling the servo will be available to you, which do not require pending tasks.\n\nTo access additional methods that require deferred execution, you need to initialize one of the child classes.\nDepending on which of the ways you prefer to handle pending tasks:\n\n#### Using the uasyncio library\nThis is the best option for most projects.\n```python\nfrom machine import Pin, PWM\nfrom micropython_servo_pdm import ServoPDMRP2Async\n\n# create a PWM servo controller (21 - pin Pico)\nservo_pwm = PWM(Pin(21))\n\n# Set the parameters of the servo pulses, more details in the \"Documentation\" section\nfreq = 50\nmin_us = 500\nmax_us = 2500\nmax_angle = 180\nmin_angle = 0\n\n# create a servo object\nservo = ServoPDMRP2Async(pwm=servo_pwm, min_us=min_us, max_us=max_us, freq=freq, max_angle=max_angle, min_angle=min_angle)\n```\n\n#### Using timer interrupts\nYou can read more about timers [here](https://docs.micropython.org/en/latest/library/machine.Timer.html)\nFor Raspberry Pi Pico [here](https://docs.micropython.org/en/latest/rp2/quickref.html#timers)\nBe careful, although this is the easiest option, it is not optimal.\nSince the handling of servo events occurs in a timer interrupt, other interrupts will be delayed.\n```python\nfrom machine import Pin, PWM\nfrom micropython_servo_pdm import ServoPDMRP2Irq\n\n# create a PWM servo controller (21 - pin Pico)\nservo_pwm = PWM(Pin(21))\n\n# Set the parameters of the servo pulses, more details in the \"Documentation\" section\nfreq = 50\nmin_us = 500\nmax_us = 2500\nmax_angle = 180\nmin_angle = 0\n\n# create a servo object\nservo = ServoPDMRP2Irq(pwm=servo_pwm, min_us=min_us, max_us=max_us, freq=freq, max_angle=max_angle, min_angle=min_angle)\n```\n\n\u003ca id=\"doc\"\u003e\u003c/a\u003e\n## Documentation\n\u003ca id=\"doc_pdm\"\u003e\u003c/a\u003e\n### A little about PDM\nPDM(pulse-duration modulation) is a process of power control by pulsing the power consumer on and off. By Wikipedia®\nIn our case, it is used to control the servo. By the time of the pulse, you can set the position of the servo shaft.\n**ATTENTION:** Unlike PWM, the control is not based on frequency, but on the duration of the pulse.\nYou can read more here (with pictures): [wiki.amperka.ru](http://wiki.amperka.ru/articles:servo-pdm-standard#%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81_%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F)\n\nFor the correct operation of the servo, we need to set the following parameters:\n- **freq** - pulse frequency, for analog servos 50 Hz. For digital 300 Hz or more.\n- **min_us** - minimum pulse time at which the servo goes to the `min_angle` point.\n- **max_us** - maximum pulse time at which the servo goes to the `max_angle` point.\n- **min_angle** - minimum servo rotation angle.\n- **max_angle** - maximum servo rotation angle.\nIt should be noted that the parameters `min_angle` and `max_angle` set the working area of the servo.\nThose. if the servo can rotate from 0 to 180 degrees, then it is not necessary to set `min_angle=0, max_angle=180`,\nit could be: `min_angle=-90, max_angle=90`, `min_angle=180, max_angle=0` or so on.\n\n\nWhere 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.\nBut there may also be inaccuracies, for example, there is a drive [MG90S](https://pdf1.alldatasheet.com/datasheet-pdf/view/1132104/ETC2/MG90S.html)\nthe documentation states that the minimum pulse time is ~1ms, and the maximum is ~2ms.\nBut 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).\nSo I recommend checking these parameters manually using the `set_duty` method.\nHow to do manual configuration is in the examples folder the file [manual_config.py](https://github.com/TTitanUA/micropython_servo_pdm/tree/main/examples/manual_config.py) and [encoder_config.py](https://github.com/TTitanUA/micropython_servo_pdm/tree/main/examples/encoder_config.py).\n\nList of parameters for servos:\n- **MG90S** - `min_us=500`, `max_us=2500`, `freq=50`, `min_angle=0`, `max_angle=180`\n- **SG90** - `min_us=600`, `max_us=2500`, `freq=50`, `min_angle=0`, `max_angle=180`\n- **MG995** - `min_us=500`, `max_us=2400`, `freq=50`, `min_angle=0`, `max_angle=180`\n\n**PLEASE:** If you find parameters for a servo that are not listed, submit them to me via [issue](https://github.com/TTitanUA/micropython_servo_pdm/issues).\n\n### ServoPDM constructor parameters\n**ServoPDMRP2Async** and **ServoPDMRP2Irq** inherit it and have the same parameters\n\n| Parameter | Type | Default | Description            |\n|-----------|------|---------|------------------------|\n| pwm       | PWM  | None    | PWM controller         |\n| min_us    | int  | 1000    | Minimum pulse time     |\n| max_us    | int  | 9000    | Maximum pulse time     |\n| min_angle | int  | 0       | Minimum rotation angle |\n| max_angle | int  | 180     | Maximum rotation angle |\n| freq      | int  | 50      | Pulse frequency        |\n| invert    | bool | False   | Direction inversion    |\n\n- `pwm` - [PWM](https://docs.micropython.org/en/latest/library/machine.PWM.html) controller object.\n- `min_us` - Minimum pulse time (duty cycle) [More](https://github.com/TTitanUA/micropython_servo_pdm#doc_pdm).\n- `max_us` - Maximum pulse time (duty cycle) [More](https://github.com/TTitanUA/micropython_servo_pdm#doc_pdm)\n- `min_angle`, `max_angle` - Conditional range of servo operation. You can set any values depending on your tasks and the capabilities of the servo.\n- `freq` - Pulse frequency, for analog drives it is 50. Digital drives are usually 300 or more.\n- `invert` - Invert the direction of the servo. If `True` then the servo will rotate in the opposite direction.\n\n\u003ca id=\"doc_base\"\u003e\u003c/a\u003e\n### ServoPDM base class methods\n- `set_duty(duty_us: int)` - Sets an arbitrary value of the pulse duration in microseconds, from 0 to `(1000 // freq) * 1000`.\nThis method is intended for manual search of the minimum and maximum duty cycle values. [More](https://github.com/TTitanUA/micropython_servo_pdm#doc_pdm)\n- `set_angle(angle: int)` - Sets the angle of the servo, in the range `min_angle \u003c angle \u003c max_angle` (or `max_angle \u003c angle \u003c min_angle` if `min_angle \u003e max_angle`).\n- `release()` - Sets the pulse duration to 0, thus disabling position holding by the servo.\n- `deinit()` - Disables PWM generation.\n\n### ServoPDMRP2Async and ServoPDMRP2Irq class methods\nWell, one method, to be precise :).\n- `move_to_angle(...)` - Smoothly moves the servo to the specified angle.\n\n| Parameter       | Type                  | Default      | Description                                                    |\n|-----------------|-----------------------|--------------|----------------------------------------------------------------|\n| angle           | Int                   | None         | End angle of rotation                                          |\n| time_ms         | Int                   | None         | Move time                                                      |\n| start_smoothing | type(ServoSmoothBase) | SmoothLinear | Ease class to be used for movement                             |\n| callback        | callable              | None         | The function that will be called after the end of the command. |\n\n\n### Slowdowns\nTo control slowdowns, you can use the `ServoSmoothBase` classes and its descendants.\nThis library only has `SmoothLinear` linear deceleration, if you need more, install the [smooth-servo](https://pypi.org/project/smooth-servo/) library.\nAn example of using built-in easing:\n```python\nfrom machine import Pin, PWM\nfrom micropython_servo_pdm import ServoPDMRP2Async, SmoothLinear\n\n# create a PWM servo controller (21 - pin Pico)\nservo_pwm = PWM(Pin(21))\n\n# Set the parameters of the servo pulses, more details in the \"Documentation\" section\nfreq = 50\nmin_us = 500\nmax_us = 2500\nmax_angle = 180\nmin_angle = 0\n\n# create a servo object\nservo = ServoPDMRP2Async(pwm=servo_pwm, min_us=min_us, max_us=max_us, freq=freq, max_angle=max_angle, min_angle=min_angle)\n\n# Повернуть сервопривод до отметки в 50 градусов за 2 секунды используя линейное замедление. После вывести в консоль \"callback cv\"\nservo.move_to_angle(50, 2000, SmoothLinear, callback=lambda: print(\"callback move_to_angle\"))\n```\nDetails about the parameters and types of slowdowns can be found in the [smooth_servo documentation](https://github.com/TTitanUA/smooth_servo#doc).\n\n\n## Examples\nUsage examples can be found in the [examples](https://github.com/TTitanUA/micropython_servo_pdm/tree/main/examples)  folder.\n\n\n\u003ca id=\"feedback\"\u003e\u003c/a\u003e\n## Bugs and feedback\nIf you find bugs, create [issue](https://github.com/TTitanUA/micropython_servo_pdm/issues)\nThe library is open for further development and your [pull requests](https://github.com/TTitanUA/micropython_servo_pdm/pulls)!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fttitanua%2Fmicropython_servo_pdm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fttitanua%2Fmicropython_servo_pdm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fttitanua%2Fmicropython_servo_pdm/lists"}