Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe2824 committed Apr 1, 2024
0 parents commit 31f226d
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Release

on:
release:
types: [created]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.7"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
python setup.py sdist bdist_wheel
twine upload --repository pypi dist/*
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
__pycache__/
phdata.txt
ecdata.txt
*.egg-info
dist/
.DS_Store
.venv
.pypirc
181 changes: 181 additions & 0 deletions GP8XXX_IIC/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
from abc import ABC
from smbus2 import SMBus

# i2c address
GP8XXX_I2C_DEVICE_ADDR = 0x58


class GP8XXX(ABC):
# Select DAC output voltage of 0-5V
OUTPUT_RANGE_2_5V = 0
# Select DAC output voltage of 0-5V
OUTPUT_RANGE_5V = 1
# Select DAC output voltage of 0-10V
OUTPUT_RANGE_10V = 2
# Select DAC output voltage of 0-VCC
OUTPUT_RANGE_VCC = 3
RESOLUTION_12_BIT = 0x0FFF
RESOLUTION_15_BIT = 0x7FFF

def __init__(self):
pass

def begin(self):
pass

def set_dac_out_voltage(self, voltage, channel):
pass

class GP8XXX_IIC(GP8XXX):
"""
I2C class initialization
- param resolution: the resolution of the chip
- param bus: the i2c bus number
- param device_addr: the I2C device address
- param auto_range: automatically selects the correct output range
"""
GP8XXX_CONFIG_REG = 0x02

def __init__(self, resolution, bus=1, device_addr=GP8XXX_I2C_DEVICE_ADDR, auto_range=True):
self._resolution = resolution
self._bus = bus
self._device_addr = device_addr
self._auto_range = auto_range

self._i2c = SMBus(self._bus)

self._dac_voltage = None

def begin(self):
"""
Initialize the function returns true for success
"""
return not self._i2c.read_byte(self._device_addr) != 0

def set_dac_outrange(self, output_range: int = GP8XXX.OUTPUT_RANGE_10V):
"""
Set the DAC output range
- param output_range [int]: DAC output range
"""
if output_range == self.OUTPUT_RANGE_5V:
self._dac_voltage = 5000
self._i2c.write_byte_data(
self._device_addr, self.GP8XXX_CONFIG_REG >> 1, 0x00)
elif output_range == self.OUTPUT_RANGE_10V:
self._dac_voltage = 10000
self._i2c.write_byte_data(
self._device_addr, self.GP8XXX_CONFIG_REG >> 1, 0x11)

def set_dac_out_voltage(self, voltage: float, channel: int = 0):
"""
Set different channel output DAC values
- param voltage [int]: value corresponding to the output voltage value (e.g. 4.321V is 4321)
- param channel [int]: integer representing the output channel
- 0: Channel 0
- 1: Channel 1
- 2: All channels
"""
voltage = float(voltage)

if self._auto_range and 0 <= voltage <= 5000:
self.set_dac_outrange(self.OUTPUT_RANGE_5V)
elif self._auto_range and 5000 <= voltage <= 10000:
self.set_dac_outrange(self.OUTPUT_RANGE_10V)

output_value = (voltage / self._dac_voltage) * self._resolution

if self._resolution == self.RESOLUTION_12_BIT:
output_value = int(output_value) << 4
elif self._resolution == self.RESOLUTION_15_BIT:
output_value = int(output_value) << 1

if channel == 0:
self._i2c.write_word_data(
self._device_addr, self.GP8XXX_CONFIG_REG, output_value)
elif channel == 1:
self._i2c.write_word_data(
self._device_addr, self.GP8XXX_CONFIG_REG << 1, output_value)
elif channel == 2:
self._i2c.write_word_data(
self._device_addr, self.GP8XXX_CONFIG_REG, output_value)
self._i2c.write_word_data(
self._device_addr, self.GP8XXX_CONFIG_REG << 1, output_value)

def store(self):
"""
FIXME: Unfortunately, I can't get the chip to store the values
"""
raise NotImplementedError

class GP8503(GP8XXX_IIC):
"""
12bit DAC Dual Channel I2C to 0-2.5V/0-VCC
- param bus: the i2c bus number
"""

def __init__(self, bus=1):
super().__init__(bus=bus, resolution=self.RESOLUTION_12_BIT, auto_range=False)
self.voltage = 2500

class GP8211S(GP8XXX_IIC):
"""
15 bit DAC I2C to 0-5V/0-10V
- param bus: the i2c bus number
- param auto_range: automatically selects the correct output range
"""

def __init__(self, bus=1, auto_range=True):
super().__init__(bus=bus, resolution=self.RESOLUTION_15_BIT, auto_range=auto_range)

class GP8512(GP8XXX_IIC):
"""
15bit DAC I2C to 0-2.5V/0-VCC
- param bus: the i2c bus number
"""

def __init__(self, bus=1):
super().__init__(bus=bus, resolution=self.RESOLUTION_15_BIT, auto_range=False)
self.dac_voltage = 2500

class GP8413(GP8XXX_IIC):
"""
15bit DAC Dual Channel I2C to 0-10V
- param bus: the i2c bus number
- param i2c_addr: the I2C device address
"""

def __init__(self, bus=1, i2c_addr=0x58):
super().__init__(bus=bus, resolution=self.RESOLUTION_15_BIT,
device_addr=i2c_addr, auto_range=False)
self.set_dac_outrange(self.OUTPUT_RANGE_10V)

class GP8403(GP8XXX_IIC):
"""
12bit DAC Dual Channel I2C to 0-5V/0-10V
- param bus: the i2c bus number
- param i2c_addr: the I2C device address
- param auto_range: automatically selects the correct output range
"""

def __init__(self, bus=1, i2c_addr=0x58, auto_range=True):
super().__init__(bus=bus, resolution=self.RESOLUTION_12_BIT,
device_addr=i2c_addr, auto_range=auto_range)

class GP8302(GP8XXX_IIC):
"""
12bit DAC Dual Channel I2C to 0-5V/0-10V
- param bus: the i2c bus number
- param i2c_addr: the I2C device address
- param auto_range: automatically selects the correct output range
"""

def __init__(self, bus=1, i2c_addr=0x58, auto_range=True):
super().__init__(bus=bus, resolution=self.RESOLUTION_12_BIT,
device_addr=i2c_addr, auto_range=auto_range)

def set_dac_out_electric_current(self, current):
"""
Set different channel output DAC values
- param current [int]: value corresponding to the output current value (e.g. 1.321A is 1321)
"""
return self.set_dac_out_voltage(current)
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Joel Klein (joe2824)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# GP8XXX-IIC

The GP8XXX-IIC module provides an interface for controlling DAC (Digital to Analog Converter) devices over the I2C protocol. This module supports various DAC models with different resolutions and output voltage ranges.

## Features

- **I2C Communication**: Utilizes the smbus2 library for communicating with DAC devices over the I2C bus.
- **Output Ranges**: Supports different output voltage ranges including 0-5V, 0-10V.
- **Support Multiple DAC Models**:
- GP8503: 12-bit DAC Dual Channel I2C to 0-2.5V/0-VCC
- GP8211S: 15-bit DAC I2C to 0-5V/0-10V
- GP8512: 15-bit DAC I2C to 0-2.5V/0-VCC
- GP8413: 15-bit DAC Dual Channel I2C to 0-10V
- GP8403: 12-bit DAC Dual Channel I2C to 0-5V/0-10V
- GP8302: 12-bit DAC Dual Channel I2C to 0-5V/0-10V

## Installation
You can install the GP8XXX module from PyPI using pip:

```bash
pip install GP8XXX-IIC
```

## Example
```python
import time
from GP8XXX_IIC import GP8403

GP8403 = GP8403(i2c_addr=0x5F, auto_range=True)

while GP8403.begin():
print("init error")
time.sleep(1)

# Optional because GP8403 support auto_range
# GP8403.set_dac_outrange(GP8403.OUTPUT_RANGE_10V)

# Chanel 1: 6.721V ≙ 6721
GP8403.set_dac_out_voltage(voltage=6721, channel=0)

time.sleep(3)

# Chanel 2: 2.774V ≙ 2774
GP8403.set_dac_out_voltage(voltage=2774, channel=1)

time.sleep(3)

# Chanel 1 & 2: 1.253V ≙ 1253
GP8403.set_dac_out_voltage(voltage=1253, channel=2)
```

## Tested devices

| DAC Module | Tested |
|------------|--------|
|GP8503 ||
|GP8211S ||
|GP8512 ||
|GP8512 ||
|GP8413 ||
|GP8403 ||
|GP8302 ||
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[build-system]
requires = [
"setuptools>=42",
"wheel"

]
build-backend = "setuptools.build_meta"
30 changes: 30 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from setuptools import setup

with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()

setup(
name="GP8XXX_IIC",
keywords = 'Raspberry Pi, Raspi, GP8403, GP8503, GP8211S, GP8512, GP8413, GP8302, DAC',
version="0.0.1",
author="Joel Klein",
description="The GP8XXX Python module offers an intuitive interface for controlling DAC (Digital to Analog Converter) devices via the I2C protocol. With support for various DAC models.",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/joe2824/GP8XXX_IIC/",
project_urls={
"Bug Tracker": "https://github.com/joe2824/GP8XXX_IIC/issues",
"Github": "https://github.com/joe2824/GP8XXX_IIC/",
},
classifiers=[
'Development Status :: 5 - Production/Stable',
"Programming Language :: Python :: 3",
'License :: OSI Approved :: MIT License',
"Operating System :: POSIX :: Linux",
],
packages=['GP8XXX_IIC'],
python_requires=">=3",
install_requires=[
'smbus2'
]
)

0 comments on commit 31f226d

Please sign in to comment.