{"id":16360232,"url":"https://github.com/larsrollik/pypulsepal","last_synced_at":"2025-04-04T12:27:22.497Z","repository":{"id":41871804,"uuid":"472690823","full_name":"larsrollik/pypulsepal","owner":"larsrollik","description":"Python API to interact with PulsePal","archived":false,"fork":false,"pushed_at":"2023-01-17T07:09:54.000Z","size":74,"stargazers_count":1,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-10T23:17:38.508Z","etag":null,"topics":["api","arduino-due","hardware-api","pulse-generator","pulsepal","python","stimulation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/larsrollik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-03-22T09:15:04.000Z","updated_at":"2022-07-12T19:06:50.000Z","dependencies_parsed_at":"2023-02-10T08:15:59.197Z","dependency_job_id":null,"html_url":"https://github.com/larsrollik/pypulsepal","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":"larsrollik/templatepy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larsrollik%2Fpypulsepal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larsrollik%2Fpypulsepal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larsrollik%2Fpypulsepal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larsrollik%2Fpypulsepal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/larsrollik","download_url":"https://codeload.github.com/larsrollik/pypulsepal/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247177243,"owners_count":20896610,"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":["api","arduino-due","hardware-api","pulse-generator","pulsepal","python","stimulation"],"created_at":"2024-10-11T02:10:59.111Z","updated_at":"2025-04-04T12:27:22.467Z","avatar_url":"https://github.com/larsrollik.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6379627.svg)](https://doi.org/10.5281/zenodo.6379627)\n[![Website](https://img.shields.io/website?up_message=online\u0026url=https%3A%2F%2Fgithub.com/larsrollik/pypulsepal)](https://github.com/larsrollik/pypulsepal)\n[![PyPI](https://img.shields.io/pypi/v/pypulsepal.svg)](https://pypi.org/project/pypulsepal)\n[![Wheel](https://img.shields.io/pypi/wheel/pypulsepal.svg)](https://pypi.org/project/pypulsepal)\n[![Contributions](https://img.shields.io/badge/Contributions-Welcome-brightgreen.svg)](https://github.com/larsrollik/pypulsepal/blob/main/CONTRIBUTING.md)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/python/black)\n\n\n# PyPulsePal\nPython API for the PulsePal open-source pulse train generator\n---\nVersion: \"0.0.2.dev0\"\n\nThis package provides an API to the [PulsePal] hardware.\nThis API is a re-implementation of the original [PulsePal Python 3 API] that draws from the `pybpod-api` communication protoool.\n\n## Example usage\n\n#### script/function\n```python\nimport time\nfrom pypulsepal import PulsePal\n\nserial_port = \"/dev/ttyACM0\"  # for unix or \"COM\"-style port names for Windows\n\n# Create PulsePal object\npp = PulsePal(serial_port=serial_port)\n\n# Set parameters\n\n## Manually\npp.program_one_param(channel=2, param_name=\"phase1Duration\", param_value=.002)\n\n## Via convencience functions\npp.set_resting_voltage(channel=2, voltage=4.2)\n\n# Upload parameters\npp.upload_all()\n\n# Trigger selected channels\npp.trigger_selected_channels(channel_2=True, channel_4=True)\n\ntime.sleep(1)\n\n# Stop outputs\npp.stop_all_outputs()\n\ntime.sleep(1)\n\n# Save settings (also done automatically on disconnect)\npp.save_settings()\n\n\n```\n\n##### Channels can also be triggered all at once\n```python\nimport time\nfrom pypulsepal import PulsePal\n\nserial_port = \"/dev/ttyACM0\"  # for unix or \"COM\"-style port names for Windows\n\n# Create PulsePal object\npp = PulsePal(serial_port=serial_port)\n\n# Trigger all channels\npp.trigger_all_channels()\n\ntime.sleep(1)\n\n# Stop outputs\npp.stop_all_outputs()\n\n```\n\n#### as context manager\n```python\nimport time\nfrom pypulsepal import PulsePal\n\nwith PulsePal(serial_port=\"/dev/ttyACM0\") as pp:\n    # set params\n    pp.upload_all()\n\n    # do something\n    time.sleep(2)\n\n```\n\n#### Write `default` params to all channels\n\n```python\nfrom pypulsepal.write_tests import write_default_settings\n\nwrite_default_settings(serial_port=\"/dev/ttyACM0\")\n\n```\n\n#### Write (funky) `test` params to all channels\n\n```python\nfrom pypulsepal.write_tests import write_test_settings_for_manual_check\n\nwrite_test_settings_for_manual_check(serial_port=\"/dev/ttyACM0\")\n\n```\n\n\n## Installation\n#### pip\n```shell\npip install pypulsepal\n```\n#### git\n```shell\ngit clone https://github.com/larsrollik/pypulsepal.git\ncd pypulsepal/\npip install -e .\n```\n#### pip + git\n```shell\npip install git+https://github.com/larsrollik/pypulsepal.git\n```\n\n## Problems \u0026 issues\nPlease open [issues](https://github.com/larsrollik/pypulsepal/issues) or [pull-requests](https://github.com/larsrollik/pypulsepal/pulls) in this repository.\n\n## Citation\nPlease cite the original [PulsePal] and [PyBpod] code and publications that this package is based on.\n\nTo cite `PyPulsePal` with a reference to the current version (as publicly documented on Zenodo), please use:\n\u003e Rollik, Lars B. (2021). PyPulsePal: Python API for the PulsePal open-source pulse train generator. doi: [10.5281/zenodo.6379627](https://doi.org/10.5281/zenodo.6379627).\n\n**BibTeX**\n```BibTeX\n@misc{rollik2022pypulsepal,\n    author       = {Lars B. Rollik},\n    title        = {{PyPulsePal: Python API for the PulsePal open-source pulse train generator}},\n    year         = {2022},\n    month        = mar,\n    publisher    = {Zenodo},\n    url          = {https://doi.org/10.5281/zenodo.6379627},\n    doi          = {10.5281/zenodo.6379627},\n  }\n```\n\n## License \u0026 sources\nThis software is released under the **[GNU GPL v3.0](https://github.com/larsrollik/pypulsepal/blob/main/LICENSE)**.\n\nThis work is derived from the [Sanworks PulsePal Python API](https://github.com/sanworks/PulsePal/tree/develop) ([commit: 5bb189f](https://github.com/sanworks/PulsePal/commit/5bb189fec8d7435433b8c23f7bae520f92e271af)).\n\nThe architecture of the API is imported and inspired by the `pybpodapi.com.arcom` module from the [pybpod-api](https://github.com/pybpod/pybpod-api).\n\nFor changes from the original implementation, see the git history since [commit 972bc1e](https://github.com/larsrollik/pypulsepal/commit/972bc1ed3d07b6809e6cbcd05373be3b76ae5b5b).\n\n## Useful code references\n- [PyBpod com ArCOM]\n- [PyBpod com protocol]\n- [PyBpod message headers]\n- [PulsePal Python 3 API]\n- [PulsePal .ino file]\n- [PulsePal param definitions]\n\n\n## TODO\n- [ ] Simplify parameter dicts in `definitions`: into nested dict with first level for name, then standard sub-dict (default value, dtype, dtype legacy(model 1), scaling, )\n- [ ] Complete API functions with all PulsePal opcodes, e.g. for Arduino logic levels (see [PulsePal USB v2 opcode list])\n- [ ] Move PulsePal hardware settings to init and remove defaults for easier upgrade in future\n- [ ] API function to accept list of dicts (from json settings file)\n  - to make overwrites on channels to get from value-based logic to channel parameter sets\n  - add write function to save all settings to json for documentation\n\n[//]: # (links)\n[Pulsepal]: https://github.com/sanworks/PulsePal\n[PyBpod]: https://github.com/pybpod/pybpod\n[PyBpod com ArCOM]: https://github.com/pybpod/pybpod-api/blob/master/pybpodapi/com/arcom.py\n[PyBpod com protocol]: https://github.com/pybpod/pybpod-api/blob/master/pybpodapi/bpod/bpod_com_protocol.py\n[PyBpod message headers]: https://github.com/pybpod/pybpod-api/blob/master/pybpodapi/com/protocol/send_msg_headers.py\n[PulsePal Python 3 API]: https://github.com/sanworks/PulsePal/blob/develop/Python/Python3/PulsePal.py\n[PulsePal .ino file]: https://github.com/sanworks/PulsePal/blob/develop/Firmware/PulsePal_2_0_1/PulsePal_2_0_1.ino\n[PulsePal param definitions]: https://sites.google.com/site/pulsepalwiki/matlab-gnu-octave/functions/programpulsepalparam\n[PulsePal USB v2 opcode list]: https://sites.google.com/site/pulsepalwiki/usb-serial-interface/usb-interface-v2-x\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flarsrollik%2Fpypulsepal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flarsrollik%2Fpypulsepal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flarsrollik%2Fpypulsepal/lists"}