# Basicmicro Python Library
A modernized Python 3 library for controlling Basicmicro motor controllers using the Basicmicro packet serial mode.
## Features
- Full support for all Basicmicro packet serial commands
- Comprehensive type hints for better IDE integration
- Detailed logging for debugging
- Context manager support for safe resource handling
- Exception handling for robust error management
- Extensive documentation
- Modular file structure for better maintainability
## Installation
### From PyPI (recommended)
```bash
pip install basicmicro
```
### From Source
Clone the repository and install:
```bash
git clone https://github.com/basicmicro/basicmicro_python.git
cd basicmicro_python
pip install -e .
```
### Platform-Specific Instructions
#### Windows
On Windows, you'll need to identify the correct COM port for your controller:
1. Open Device Manager (right-click on Start Menu → Device Manager)
2. Expand "Ports (COM & LPT)"
3. Find your controller (e.g., "USB Serial Device") and note the COM port (e.g., COM3)
Example usage:
```python
controller = Basicmicro("COM3", 38400)
```
#### Linux
On Linux, the serial port is typically in the /dev directory:
```python
controller = Basicmicro("/dev/ttyACM0", 38400) # or /dev/ttyUSB0
```
You may need to add your user to the 'dialout' group for permission to access serial ports:
```bash
sudo usermod -a -G dialout $USER
```
Then log out and log back in for changes to take effect.
#### macOS
On macOS, the serial port will be in the /dev directory:
```python
controller = Basicmicro("/dev/tty.usbserial-XXXXXXXX", 38400)
```
The exact name will depend on your USB-serial adapter.
## Quick Start
```python
import logging
from basicmicro import Basicmicro
# Enable logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# Using context manager for automatic resource handling
with Basicmicro("/dev/ttyACM0", 38400) as controller: # Use "COM3" on Windows
address = 0x80 # Default address
# Simple motor control
controller.DutyM1(address, 16384) # Half speed forward for motor 1
controller.DutyM2(address, -8192) # Quarter speed backward for motor 2
# Read encoder values
enc1 = controller.ReadEncM1(address)
if enc1[0]: # Check if read was successful
print(f"Encoder 1 count: {enc1[1]}")
# Set velocity PID values
controller.SetM1VelocityPID(address, kp=1.0, ki=0.5, kd=0.25, qpps=44000)
```
## Usage Examples
### Basic Motor Control
```python
from basicmicro import Basicmicro
# Initialize and open connection
controller = Basicmicro("/dev/ttyACM0", 38400) # Use "COM3" on Windows
controller.Open()
address = 0x80 # Default controller address
# Control motors by duty cycle (-32767 to +32767)
controller.DutyM1(address, 16384) # 50% forward
controller.DutyM2(address, -8192) # 25% backward
# Control motors by speed (encoder counts per second)
controller.SpeedM1(address, 1000) # 1000 counts per second forward
controller.SpeedM2(address, -500) # 500 counts per second backward
# Control both motors simultaneously
controller.DutyM1M2(address, 8192, -8192) # Motor 1 forward, Motor 2 backward
# Always close connection when done
controller.close()
```
### Using Context Manager
```python
from basicmicro import Basicmicro
# The context manager automatically closes the connection when done
with Basicmicro("/dev/ttyACM0", 38400) as controller: # Use "COM3" on Windows
address = 0x80
# Read battery voltages
main_batt = controller.ReadMainBatteryVoltage(address)
logic_batt = controller.ReadLogicBatteryVoltage(address)
if main_batt[0] and logic_batt[0]:
print(f"Main battery: {main_batt[1]/10.0}V")
print(f"Logic battery: {logic_batt[1]/10.0}V")
# Read temperatures
temp = controller.ReadTemp(address)
if temp[0]:
print(f"Temperature: {temp[1]/10.0}°C")
```
### Reading Encoders and Speed
```python
from basicmicro import Basicmicro
import time
controller = Basicmicro("/dev/ttyACM0", 38400) # Use "COM3" on Windows
controller.Open()
address = 0x80
# Reset encoders to zero
controller.ResetEncoders(address)
# Set motor speed
controller.SpeedM1(address, 1000) # 1000 counts per second
# Monitor encoders and speed
try:
for _ in range(10):
enc = controller.ReadEncM1(address)
speed = controller.ReadSpeedM1(address)
if enc[0] and speed[0]:
print(f"Encoder: {enc[1]}, Speed: {speed[1]} counts/sec, Status: {enc[2]}")
time.sleep(0.5)
finally:
controller.DutyM1(address, 0) # Stop motor
controller.close()
```
### Setting PID Parameters
```python
from basicmicro import Basicmicro
controller = Basicmicro("/dev/ttyACM0", 38400) # Use "COM3" on Windows
controller.Open()
address = 0x80
# Set velocity PID parameters
kp = 1.0 # Proportional constant
ki = 0.5 # Integral constant
kd = 0.25 # Derivative constant
qpps = 44000 # Maximum speed in quadrature pulses per second
controller.SetM1VelocityPID(address, kp, ki, kd, qpps)
# Read back the PID settings to verify
result = controller.ReadM1VelocityPID(address)
if result[0]:
print(f"P: {result[1]}, I: {result[2]}, D: {result[3]}, QPPS: {result[4]}")
controller.close()
```
## Examples
For more detailed examples, check the `examples` directory:
1. Basic Movement: Demonstrates fundamental motor control
2. Acceleration & Position: Shows speed and position control with acceleration
3. PID Configuration: Examples of reading and setting PID parameters
4. Status & Diagnostics: Reading controller status and diagnostic information
5. Configuration Management: Managing controller settings
6. CAN Communication: Using the CAN bus interface
7. Mixed Mode & Differential Drive: Controlling differential drive robots
8. Advanced Scripting: Multi-threaded control and complex sequences
Run examples using:
```bash
python -m examples.01_basic_movement -p COM3 # On Windows
python -m examples.01_basic_movement -p /dev/ttyACM0 # On Linux
```
## Logging
The library uses Python's standard logging module. To enable logging:
```python
import logging
# Configure global logging level
logging.basicConfig(
level=logging.INFO, # Set to DEBUG for more detailed output
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# Enable DEBUG level for just the basicmicro module
logging.getLogger('basicmicro').setLevel(logging.DEBUG)
```
## Documentation
For detailed API documentation, see the [API Reference](./docs/api_reference.md).
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.# Test change
# Test docs
Raw data
{
"_id": null,
"home_page": "https://github.com/basicmicro/basicmicro_python",
"name": "basicmicro",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "robotics, motor control, basicmicro, roboclaw, serial",
"author": "Nathan Scherdin",
"author_email": "support@basicmicro.com",
"download_url": "https://files.pythonhosted.org/packages/72/b1/77981edeaa3f02c2f0fa81bdfca3480af95691f787cbe00da873407ec5bf/basicmicro-2.0.10.tar.gz",
"platform": null,
"description": "# Basicmicro Python Library\n\nA modernized Python 3 library for controlling Basicmicro motor controllers using the Basicmicro packet serial mode.\n\n## Features\n\n- Full support for all Basicmicro packet serial commands\n- Comprehensive type hints for better IDE integration\n- Detailed logging for debugging\n- Context manager support for safe resource handling\n- Exception handling for robust error management\n- Extensive documentation\n- Modular file structure for better maintainability\n\n## Installation\n\n### From PyPI (recommended)\n\n```bash\npip install basicmicro\n```\n\n### From Source\n\nClone the repository and install:\n\n```bash\ngit clone https://github.com/basicmicro/basicmicro_python.git\ncd basicmicro_python\npip install -e .\n```\n\n### Platform-Specific Instructions\n\n#### Windows\n\nOn Windows, you'll need to identify the correct COM port for your controller:\n\n1. Open Device Manager (right-click on Start Menu \u2192 Device Manager)\n2. Expand \"Ports (COM & LPT)\"\n3. Find your controller (e.g., \"USB Serial Device\") and note the COM port (e.g., COM3)\n\nExample usage:\n```python\ncontroller = Basicmicro(\"COM3\", 38400)\n```\n\n#### Linux\n\nOn Linux, the serial port is typically in the /dev directory:\n\n```python\ncontroller = Basicmicro(\"/dev/ttyACM0\", 38400) # or /dev/ttyUSB0\n```\n\nYou may need to add your user to the 'dialout' group for permission to access serial ports:\n```bash\nsudo usermod -a -G dialout $USER\n```\nThen log out and log back in for changes to take effect.\n\n#### macOS\n\nOn macOS, the serial port will be in the /dev directory:\n\n```python\ncontroller = Basicmicro(\"/dev/tty.usbserial-XXXXXXXX\", 38400)\n```\n\nThe exact name will depend on your USB-serial adapter.\n\n## Quick Start\n\n```python\nimport logging\nfrom basicmicro import Basicmicro\n\n# Enable logging\nlogging.basicConfig(\n level=logging.INFO,\n format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'\n)\n\n# Using context manager for automatic resource handling\nwith Basicmicro(\"/dev/ttyACM0\", 38400) as controller: # Use \"COM3\" on Windows\n address = 0x80 # Default address\n\n # Simple motor control\n controller.DutyM1(address, 16384) # Half speed forward for motor 1\n controller.DutyM2(address, -8192) # Quarter speed backward for motor 2\n\n # Read encoder values\n enc1 = controller.ReadEncM1(address)\n if enc1[0]: # Check if read was successful\n print(f\"Encoder 1 count: {enc1[1]}\")\n\n # Set velocity PID values\n controller.SetM1VelocityPID(address, kp=1.0, ki=0.5, kd=0.25, qpps=44000)\n```\n\n## Usage Examples\n\n### Basic Motor Control\n\n```python\nfrom basicmicro import Basicmicro\n\n# Initialize and open connection\ncontroller = Basicmicro(\"/dev/ttyACM0\", 38400) # Use \"COM3\" on Windows\ncontroller.Open()\n\naddress = 0x80 # Default controller address\n\n# Control motors by duty cycle (-32767 to +32767)\ncontroller.DutyM1(address, 16384) # 50% forward\ncontroller.DutyM2(address, -8192) # 25% backward\n\n# Control motors by speed (encoder counts per second)\ncontroller.SpeedM1(address, 1000) # 1000 counts per second forward\ncontroller.SpeedM2(address, -500) # 500 counts per second backward\n\n# Control both motors simultaneously\ncontroller.DutyM1M2(address, 8192, -8192) # Motor 1 forward, Motor 2 backward\n\n# Always close connection when done\ncontroller.close()\n```\n\n### Using Context Manager\n\n```python\nfrom basicmicro import Basicmicro\n\n# The context manager automatically closes the connection when done\nwith Basicmicro(\"/dev/ttyACM0\", 38400) as controller: # Use \"COM3\" on Windows\n address = 0x80\n \n # Read battery voltages\n main_batt = controller.ReadMainBatteryVoltage(address)\n logic_batt = controller.ReadLogicBatteryVoltage(address)\n \n if main_batt[0] and logic_batt[0]:\n print(f\"Main battery: {main_batt[1]/10.0}V\")\n print(f\"Logic battery: {logic_batt[1]/10.0}V\")\n \n # Read temperatures\n temp = controller.ReadTemp(address)\n if temp[0]:\n print(f\"Temperature: {temp[1]/10.0}\u00b0C\")\n```\n\n### Reading Encoders and Speed\n\n```python\nfrom basicmicro import Basicmicro\nimport time\n\ncontroller = Basicmicro(\"/dev/ttyACM0\", 38400) # Use \"COM3\" on Windows\ncontroller.Open()\naddress = 0x80\n\n# Reset encoders to zero\ncontroller.ResetEncoders(address)\n\n# Set motor speed\ncontroller.SpeedM1(address, 1000) # 1000 counts per second\n\n# Monitor encoders and speed\ntry:\n for _ in range(10):\n enc = controller.ReadEncM1(address)\n speed = controller.ReadSpeedM1(address)\n \n if enc[0] and speed[0]:\n print(f\"Encoder: {enc[1]}, Speed: {speed[1]} counts/sec, Status: {enc[2]}\")\n \n time.sleep(0.5)\nfinally:\n controller.DutyM1(address, 0) # Stop motor\n controller.close()\n```\n\n### Setting PID Parameters\n\n```python\nfrom basicmicro import Basicmicro\n\ncontroller = Basicmicro(\"/dev/ttyACM0\", 38400) # Use \"COM3\" on Windows\ncontroller.Open()\naddress = 0x80\n\n# Set velocity PID parameters\nkp = 1.0 # Proportional constant\nki = 0.5 # Integral constant\nkd = 0.25 # Derivative constant\nqpps = 44000 # Maximum speed in quadrature pulses per second\n\ncontroller.SetM1VelocityPID(address, kp, ki, kd, qpps)\n\n# Read back the PID settings to verify\nresult = controller.ReadM1VelocityPID(address)\nif result[0]:\n print(f\"P: {result[1]}, I: {result[2]}, D: {result[3]}, QPPS: {result[4]}\")\n\ncontroller.close()\n```\n\n## Examples\n\nFor more detailed examples, check the `examples` directory:\n\n1. Basic Movement: Demonstrates fundamental motor control\n2. Acceleration & Position: Shows speed and position control with acceleration\n3. PID Configuration: Examples of reading and setting PID parameters\n4. Status & Diagnostics: Reading controller status and diagnostic information\n5. Configuration Management: Managing controller settings\n6. CAN Communication: Using the CAN bus interface\n7. Mixed Mode & Differential Drive: Controlling differential drive robots\n8. Advanced Scripting: Multi-threaded control and complex sequences\n\nRun examples using:\n```bash\npython -m examples.01_basic_movement -p COM3 # On Windows\npython -m examples.01_basic_movement -p /dev/ttyACM0 # On Linux\n```\n\n## Logging\n\nThe library uses Python's standard logging module. To enable logging:\n\n```python\nimport logging\n\n# Configure global logging level\nlogging.basicConfig(\n level=logging.INFO, # Set to DEBUG for more detailed output\n format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'\n)\n\n# Enable DEBUG level for just the basicmicro module\nlogging.getLogger('basicmicro').setLevel(logging.DEBUG)\n```\n\n## Documentation\n\nFor detailed API documentation, see the [API Reference](./docs/api_reference.md).\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.# Test change\n# Test docs\n",
"bugtrack_url": null,
"license": null,
"summary": "A modernized Python 3 library for controlling Basicmicro motor controllers",
"version": "2.0.10",
"project_urls": {
"Homepage": "https://github.com/basicmicro/basicmicro_python"
},
"split_keywords": [
"robotics",
" motor control",
" basicmicro",
" roboclaw",
" serial"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "763d2a3b699026a07194e5e8dea7743e168538dcef3d5aa43c0e7bc2d8f7dea4",
"md5": "082fa8a9672e428a20eb5a717e73edb9",
"sha256": "d97e3d579aea4f4623e12a88209f79e3f1ce2eb8fa3983caa23852bec17de3ef"
},
"downloads": -1,
"filename": "basicmicro-2.0.10-py3-none-any.whl",
"has_sig": false,
"md5_digest": "082fa8a9672e428a20eb5a717e73edb9",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 31145,
"upload_time": "2025-07-18T00:45:58",
"upload_time_iso_8601": "2025-07-18T00:45:58.307519Z",
"url": "https://files.pythonhosted.org/packages/76/3d/2a3b699026a07194e5e8dea7743e168538dcef3d5aa43c0e7bc2d8f7dea4/basicmicro-2.0.10-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "72b177981edeaa3f02c2f0fa81bdfca3480af95691f787cbe00da873407ec5bf",
"md5": "a7eff7343d4dd1d4d3d8c50a5f0de72b",
"sha256": "ecb7373151d2d1c349df2f419a9b4aacd28144eff65b1e4629f2ff1dacd8fbc8"
},
"downloads": -1,
"filename": "basicmicro-2.0.10.tar.gz",
"has_sig": false,
"md5_digest": "a7eff7343d4dd1d4d3d8c50a5f0de72b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 33139,
"upload_time": "2025-07-18T00:46:00",
"upload_time_iso_8601": "2025-07-18T00:46:00.535682Z",
"url": "https://files.pythonhosted.org/packages/72/b1/77981edeaa3f02c2f0fa81bdfca3480af95691f787cbe00da873407ec5bf/basicmicro-2.0.10.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-18 00:46:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "basicmicro",
"github_project": "basicmicro_python",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "basicmicro"
}