{"id":19839445,"url":"https://github.com/scientifichackers/dialmap","last_synced_at":"2025-09-04T12:47:17.611Z","repository":{"id":133162454,"uuid":"146780018","full_name":"scientifichackers/dialmap","owner":"scientifichackers","description":"Software controlled dials done right.","archived":false,"fork":false,"pushed_at":"2018-09-13T13:31:47.000Z","size":27,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-28T22:20:42.855Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scientifichackers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2018-08-30T16:58:55.000Z","updated_at":"2021-02-22T12:08:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"cfa311bf-2305-4eaf-a2f6-f4e628c4ed94","html_url":"https://github.com/scientifichackers/dialmap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/scientifichackers/dialmap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientifichackers%2Fdialmap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientifichackers%2Fdialmap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientifichackers%2Fdialmap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientifichackers%2Fdialmap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scientifichackers","download_url":"https://codeload.github.com/scientifichackers/dialmap/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientifichackers%2Fdialmap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273611798,"owners_count":25136977,"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-09-04T02:00:08.968Z","response_time":61,"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":[],"created_at":"2024-11-12T12:22:28.166Z","updated_at":"2025-09-04T12:47:17.524Z","avatar_url":"https://github.com/scientifichackers.png","language":"Python","funding_links":["https://www.buymeacoffee.com/u75YezVri"],"categories":[],"sub_categories":[],"readme":"# Dial Map\n*Software controlled dials done right.*\n\nEver had to deal with potentiometers, and their horrible jitter? \nThen this library is just for you.\n\n- Automatically normalizes the ADC's raw values.\n- 100% Dependency free, MicroPython compatible.\n- Fast, because of the magical pre-computation it does. (Takes more memory though)\n  \n  *I'm talking `µs` level response times.*\n\n## Install\n\nIt's a sub-100 line python script so, just copy-paste [dialmap.py](dialmap.py) and import it. \n\n### The Problem\n\nPotentiometers always have some degree of jitter.\n \nIt doesn't matter much in the Analog world,\nbut when you want to use them for Digital (especially Software applications), \nthis is a *huge* headache.\n\n**Let's take an example**\n\nWe have an ADC that gives us the reading of potentiometer as an integer between `0` and `1000`, \nand we want to map these values to a range between `1` and `5`. \n\nHere is a visual representation:\n\n```text\n                    +------+-------+-------+-------+-------+\nInterpreted Value:  |  1   |   2   |   3   |   4   |   5   |     \n                    +------+-------+-------+-------+-------+\nRaw Value:          0     200     400     600     800     1000\n                         ↑↑↑↑↑\n```\n\n\n*It's guaranteed that the potentiometer will have some amount of jitter, even when it's absolutely stationary.*\n\nLet's assume that the values are swinging around the `200` mark. (represented very creatively by the arrows)\n\nYou can immediately notice the problem here. \n\nEven the slightest amount of jitter will cause random switching between `1` and `2`, \ncausing unwanted behavior in our software.\n\n**I mean Just imagine your IOT Fan controlled by this knob!**\n\n### The culprit\n\nHowever big or small the jitter, the fact that we have the concept of \"breakpoints\" is damaging.\n\n### The Solution\n\n\nThe solution, is to program \"Dead Zones\" into our mapping.\n\nWhen-ever the raw value reaches the \"Dead Zone\", our Software will stop responding.\n\nHere is a visual representation:\n\n```text\n                    +-------+---+-------+---+-------+---+-------+---+-------+\nInterpreted Value:  |   1   |XXX|   2   |XXX|   3   |XXX|   4   |XXX|   5   |     \n                    +-------+---+-------+---+-------+---+-------+---+-------+\nRaw Value:          0      195 205     396 405     595 605     795 805     1000\n                          ↑↑↑↑↑                          \n```\n\nNow even if there is jitter at the `200` mark, \nthe interpreted value will remain stable at `1` as long as there is a jitter of `±5`.\n\n\n##### Example\n \n```python\nfrom dialmap import DialMap\n\nmy_dial_map = DialMap(output_pts=range(5), deadzone=5)\n```\n\n- `deadzone` is in percentage. \n    Such that, `0` results in no deadzones, and a value of `100` results in no active zones (empty mapping).\n\n- The `DialMap` has adaptive normalization. \n    Which means it will observe the range of ADC's raw values, and normalize them automatically. \n    Which means, you don't need to provide the range of ADC's raw values.\n  \nHere is how you use this mapping:\n\n```python\nmy_dial_map[150]\n```\n\nAnd that's it!\n\n---\n\nYou can inspect the mapping like this:\n\n```python\n\u003e\u003e my_dial_map.mapping.keys()\ndict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99])\n\n\u003e\u003e\u003e my_dial_map.mapping.values()\ndict_values([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4])\n```\n\n- `keys()` represent the normalized values.\n- `values()` represent the `output_pts` you asked for.\n\n---\n\n`DialMap.__getitem__()` simply normalizes the input, and passes it through this mapping.\n\nIf a Dead Zone is encountered, (for e.g. `16` is a Dead Point above) then the last translated value is returned.\n\n---\n\n```\nfrom dialmap import MultiDialMap\nd = MultiDialMap([[1, 10, 100], [2, 16, 150], [5, 20, 200], [10, 40, 300]], deadzone=0)\n```\n\n\n\u003ca href=\"https://www.buymeacoffee.com/u75YezVri\" target=\"_blank\"\u003e\u003cimg src=\"https://www.buymeacoffee.com/assets/img/custom_images/black_img.png\" alt=\"Buy Me A Coffee\" style=\"height: auto !important;width: auto !important;\" \u003e\u003c/a\u003e\n\n[🐍🏕️](http://www.pycampers.com/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscientifichackers%2Fdialmap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscientifichackers%2Fdialmap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscientifichackers%2Fdialmap/lists"}