# theacodes / Winterbloom_VoltageIO

A CircuitPython helper library for dealing with voltage values in DACs and ADCs
Python
Latest commit 41c4cf1 Oct 28, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
tests Oct 28, 2019
.flake8 Oct 16, 2019
.gitignore Oct 16, 2019
CODE_OF_CONDUCT.md Oct 16, 2019
noxfile.py Oct 16, 2019
winterbloom_voltageio.py Oct 28, 2019

# Winterbloom VoltageIO

This is a CircuitPython helper library for setting a digital-to-analog Converter (DAC) to a direct voltage value. That is, instead of setting a 16-bit integer value you can set the DAC to a floating-point voltage value. It also provides similar helpers for reading voltage values from analog-to-digital converters (ADCs).

For example you can replace this code:

```import board
from analogio import AnalogOut

analog_out = AnalogOut(board.A0)

# 0-3.3v range, so this should be ~0.25 volts.
analog_out.value = round(65535 * 0.25 / 3.3)```

with this code:

```import board
from winterbloom_voltageio import VoltageOut

voltage_out = VoltageOut.from_pin(board.A0)

# 3.3v range.
voltage_out.linear_calibration(3.3)

# And 0.25v out.
voltage_out.voltage = 0.25```

While this is a useful convenience for when you want to skip doing the math to set the DAC to a specific voltage, it's also incredibly useful for working around any non-linearity in your DAC. Real-world DACs have some degree of imperfection. You can measure the DAC's output voltage at various output values and then use `VoltageIO.direct_calibration` to get more accurate voltage output:

```voltage_out.direct_calibration({
# Voltage: DAC value
0: 0,
0.825: 16000,
1.65: 32723,
2.475: 49230,
3.3, 65535,
})```

This library is also extremely useful if your DAC's output is scaled. For example, if you have an op amp after your DAC that's scaling its output to 0v-10v. You can use `VoltageIO` to set the output based on the final, scaled voltage:

```# While the DAC itself only ouputs up to 3.3v,
# it's scaled up to 10v by an op amp.
voltage_out.linear_calibration(10)

# 5.5v output.
voltage_out.voltage = 5.5```

Very similarly and for similar reasons, you can use `VoltageIn` to read voltage values from ADCs. For example, you might replace this code:

```import board

# 3.3v range
voltage = analog_in.value * 3.3 / 65536

print(voltage)```

with:

```import board
from winterbloom_voltageio import VoltageIn

voltage_in = VoltageIn.from_pin(board.A0)

# 3.3v range.
voltage_in.linear_calibration(3.3)

print(voltage_in)```

Just like with `VoltageOut`, you can directly specify the calibration values. This allows you to counteract any non-linearity:

```voltage_in.direct_calibration({
0: 0,
16000: 0.825,
32723: 1.65,
49230: 2.475,
65535: 3.3,
})```

And again, just like with `VoltageOut`, this class is useful for dealing with cases where your input voltage is scaled up or down for your ADC.

## Installation

Install this library by copying winterbloom_voltageio.py to your device's `lib` folder.