{"id":20989931,"url":"https://github.com/robtillaart/m62429","last_synced_at":"2025-05-14T18:32:21.536Z","repository":{"id":43723037,"uuid":"284715638","full_name":"RobTillaart/M62429","owner":"RobTillaart","description":"Arduino library for M62429 volume control IC","archived":false,"fork":false,"pushed_at":"2024-04-13T09:06:04.000Z","size":38,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-08-07T18:26:54.350Z","etag":null,"topics":["arduino","control","stereo","volume"],"latest_commit_sha":null,"homepage":"","language":"C++","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/RobTillaart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"RobTillaart","custom":"https://www.paypal.me/robtillaart"}},"created_at":"2020-08-03T14:02:31.000Z","updated_at":"2023-12-20T17:55:17.000Z","dependencies_parsed_at":"2024-04-13T10:23:37.051Z","dependency_job_id":"78d287a7-3f94-46fe-a187-e11831f42ddc","html_url":"https://github.com/RobTillaart/M62429","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FM62429","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FM62429/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FM62429/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FM62429/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobTillaart","download_url":"https://codeload.github.com/RobTillaart/M62429/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225305801,"owners_count":17453455,"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","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":["arduino","control","stereo","volume"],"created_at":"2024-11-19T06:26:44.964Z","updated_at":"2024-11-19T06:26:45.629Z","avatar_url":"https://github.com/RobTillaart.png","language":"C++","funding_links":["https://github.com/sponsors/RobTillaart","https://www.paypal.me/robtillaart"],"categories":[],"sub_categories":[],"readme":"\n[![Arduino CI](https://github.com/RobTillaart/M62429/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)\n[![Arduino-lint](https://github.com/RobTillaart/M62429/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/M62429/actions/workflows/arduino-lint.yml)\n[![JSON check](https://github.com/RobTillaart/M62429/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/M62429/actions/workflows/jsoncheck.yml)\n[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/M62429.svg)](https://github.com/RobTillaart/M62429/issues)\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/M62429/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/RobTillaart/M62429.svg?maxAge=3600)](https://github.com/RobTillaart/M62429/releases)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/M62429.svg)](https://registry.platformio.org/libraries/robtillaart/M62429)\n\n\n# M62429\n\nArduino library for M62429 volume control IC.\n\n\n## Description\n\n#### M62429\n\nThis library is used to set the attenuation (volume) of the \nM62429 IC a.k.a. FM62429.\n\nThe communication needs a minimum delay of 1.6 microseconds. \nThis is defined in the library in **M62429_CLOCK_DELAY** == 2\nFor AVR (UNO, slow device) it is defined as 0, as the digitalWrite\ntakes time enough.\n\nFor faster processors this define can be overruled runtime by setting it \nbefore including \"M62429.h\" or by defining it as command line parameter.\n\n\n#### M62429_RAW\n\nThe library also implements a M62429_RAW class which has a minimalistic interface.\n \n\n## Interface M62429\n\n```cpp\n#include \"M62429.h\"\n```\n\nThe interface is straightforward\n\n- **M62429()** Constructor\n- **void begin(uint8_t dataPin, uint8_t clockPin)** defines the clock and data pin.\nOne has to create one object per IC. \n- **int getVolume(uint8_t channel)** channel is 0, 1 or 2 (both). \nIn the latter case the volume of channel 0 is used as volume of both channels.\nSee remark future section.\n- **int setVolume(uint8_t channel, uint8_t volume)** \n  - channel = 0, 1, 2 = both\n  - volume = 0 .. 255\n  - Note: if system is muted, no changes are made.\n- **int incr(uint8_t channel = 2)** increment volume (both channels is default) until max (255) is reached.\nThis is another way to set volume that is better suited for a rotary \nencoder or a \\[+\\] button.\n  - Note: if system is muted, no changes are made.\n- **int decr(uint8_t channel = 2)** decrement volume (both channels is default) until 0 is reached. \n  - Note: if system is muted, no changes are made.\n- **int average()** averages the 2 channels to same = average level.  \nSort of set balance in the middle functionality.\n  - Note: if system is muted, no changes are made.\n- **void muteOn()** silences both channels but remembers the volume.\nGetVolume() will return the 'saved' volume value.\n- **void muteOff()** resets the volume per channel again.\n- **bool isMuted()** returns the muted state. \n\nNote: the volume goes from 0..255 while the actual steps go from 0..87.\nTherefore not every step in volume will make a \"real\" step (roughly 1 in 3).\nThis choice is made as the range 0..255 is more often used than the 0..87 range\nand therefore better fits other sensors and devices.\n\n\n#### Error codes\n\nThe functions **getVolume(), setVolume(), incr(), decr()** and **average()**\ncan return one of the  error codes.\n\n\n| value | name                 | notes     |\n|:-----:|:---------------------|:----------|\n|   0   | M62429_OK            | no error  |\n|  -1   | M62429_MUTED         | system is muted, use **muteOff()** |\n|  -10  | M62429_CHANNEL_ERROR | channel must be 0, 1 or 2          |\n\n\n## Operation\n\nSee examples\n\n\n\n## Interface M62429_RAW\n\nThe interface is minimalistic. \nNo parameter or other checks are made.\n\nUse **\\#include \"M62429.h\"**\n\n- **void begin(uint8_t dataPin, uint8_t clockPin)** defines the clock and data pin.\nOne has to create one object per IC. \n- **int getAttn(uint8_t channel)** channel is 0, 1 or 2 (both). \nIn the latter case the attenuation of channel 0 is used as attenuation of both channels.\n- **void setAttn(uint8_t channel, uint8_t attn)** \n  - channel = 0, 1, 2 = both\n  - attenuation = 0 .. 87\n\n\n## Future\n\n#### Must\n\n- improve documentation\n\n#### Should\n\n#### Could\n\n#### Mixer\n\n- Control multiple M62429 IC's \n- One shared dataPin and clockPin per IC. \n- use a PCF8574 / PCF8575 as selector \n- would allow for 16 stereo or 32 mono channels. \nRuntime configuration mono / stereo would be cool.\n\n```\n  PCF8574 or PCF8575 is used as device selector\n  AND port takes DATA and CLOCK to right M62429\n  identical schema for all 8/16 ports\n\n             PCF8575                 AND             M62429\n           +---------+              +---+          +---------+\n           |         |=======+======| \u0026 |==========| data    |\n           |         |   +===|======|   |          |         |\n   - I2C - |         |   |   |      +---+          |         |\n           |         |   |   |                     |         |\n           |         |   |   |      +---+          |         |\n           |         |   |   +======| \u0026 |==========| clock   |\n           |         |   |     +====|   |          |         |\n           |         |   |     |    +---+          |         |\n           +---------+   |     |                   +---------+\n                         |     |\n     DATA  ==============+     |\n     CLOCK ====================+\n```\n\n\n#### Volume pan model\n\n- model with one **volume(0..100%)** and one **balance(-100..100)** == **pan()**.  \n- Also a **left()** and **right()** incremental balance might be added.\n\nDoes this model work better than 2 separate volume channels?\n\n\n#### Other\n\n- change **getVolume(both)** to return max of the two channels?\n  would be better.\n- **min()** to reduce volume to minimum of both channels.\n- create **setAttn(channel, attn)** and **getAttn()** for low level control.\n  - needs cached attn values.\n\n\n#### Wont\n\n- **muteOff()** should increase gradually.  takes too much blocking time.\n- **Mute()** could be per channel, default = both / all.\nwould add a lot of extra testing. the user can implement a **setVolume(chan, 0)**\n- **mute50()** reduces levels with 50% (rounded down?).\n  user can implement this **setVolume(chan, getVolume(chan)/2);**\n\n\n## Support\n\nIf you appreciate my libraries, you can support the development and maintenance.\nImprove the quality of the libraries by providing issues and Pull Requests, or\ndonate through PayPal or GitHub sponsors.\n\nThank you,\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fm62429","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobtillaart%2Fm62429","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtillaart%2Fm62429/lists"}