CircuitPython Microcontroller Wiring
Wiring the MCP4728 to communicate with your microcontroller is straightforward thanks to the I2C interface. For these examples, we can use a multimeter to measure the voltages output on each of the DAC's channels. The instructions below reference an Adafruit Feather microcontroller, but the same applies to a Metro M0 or M4 or other CircuitPython compatible board.
- Feather 3.3V to MCP4728 VCC (red wire)
- Feather GND to MCP4728 GND (black wire)
- Feather SCL to MCP4728 SCL (yellow wire)
- Feather SDA to MCP4728 SDA (blue wire)
- Multimeter Positive Lead to MCP4728 VA, VB, VC, and VD in sequence
- Multimeter Negative Lead to GND
Python Computer Wiring
Since there are dozens of Linux computers/boards you can use, we will show wiring for Raspberry Pi. For other platforms, please visit the guide for CircuitPython on Linux to see whether your platform is supported.
Here's the Raspberry Pi wired with I2C:
- RPi 3.3V to MCP4728 VCC (red wire)
- RPi GND to MCP4728 GND (black wire)
- RPi SCL to MCP4728 SCL (yellow wire)
- RPi SDA to MCP4728 SDA (blue wire)
- Multimeter Positive Lead to MCP4728 VA, VB, VC, and VD in sequence
- Multimeter Negative Lead to GND
CircuitPython Installation of MCP4728 Library
You'll need to install the Adafruit CircuitPython MCP4728 library on your CircuitPython board.
First make sure you are running the latest version of Adafruit CircuitPython for your board.
Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle. Our CircuitPython starter guide has a great page on how to install the library bundle.
For non-express boards like the Trinket M0 or Gemma M0, you'll need to manually install the necessary libraries from the bundle:
- adafruit_mcp4728.mpy
- adafruit_bus_device
Before continuing make sure your board's lib folder or root filesystem has the adafruit_mcp4728.mpy file and adafruit_bus_device folder copied over.
Next connect to the board's serial REPL so you are at the CircuitPython >>> prompt.
Python Installation of MCP4728 Library
You'll need to install the Adafruit_Blinka library that provides the CircuitPython support in Python. This may also require enabling I2C on your platform and verifying you are running Python 3. Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready!
Once that's done, from your command line run the following command:
sudo pip3 install adafruit-circuitpython-mcp4728
If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!
To demonstrate the usage of the DAC, we'll initialize it and set the output values for each of the channels. Type the following code in the CircuitPython REPL to import the necessary modules and initialize the I2C connection with the DAC:
import board import busio import adafruit_mcp4728 i2c = busio.I2C(board.SCL, board.SDA) mcp4728 = adafruit_mcp4728.MCP4728(i2c)
If your board has a MCP4728A4 with an I2C address of 0x64, then you'll need to edit this line of code:
mcp4728 = adafruit_mcp4728.MCP4728(i2c)
To this:
mcp4728 = adafruit_mcp4728.MCP4728(i2c, 0x64)
Next, we'll set the values for each channel and then test the voltages with a multimeter
mcp4728.channel_a.value = 65535 mcp4728.channel_b.value = int(65535/2) mcp4728.channel_c.value = int(65535/4) mcp4728.channel_d.value = 0
You can now use a multimeter to check the voltages on each of the output pins, VA, VB, VC, and VD. The values will differ slightly for you but they should be close to:
- 3.3V on VA
- 1.65V on VB
- 0.825V on VC
- 0V on VD
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT import board import adafruit_mcp4728 MCP4728_DEFAULT_ADDRESS = 0x60 MCP4728A4_DEFAULT_ADDRESS = 0x64 i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller # use for MCP4728 variant mcp4728 = adafruit_mcp4728.MCP4728(i2c, adafruit_mcp4728.MCP4728_DEFAULT_ADDRESS) # use for MCP4728A4 variant # mcp4728 = adafruit_mcp4728.MCP4728(i2c, adafruit_mcp4728.MCP4728A4_DEFAULT_ADDRESS) mcp4728.channel_a.value = 65535 # Voltage = VDD mcp4728.channel_b.value = int(65535 / 2) # VDD/2 mcp4728.channel_c.value = int(65535 / 4) # VDD/4 mcp4728.channel_d.value = 0 # 0V
Vrefs and You
Reference Voltages (Vref for short) are an important topic to understand when working with DACs. The Vref determines the top of the voltage range that the DAC will output. This is because the DAC starts with the Vref as the output voltage and if the DAC settings specify a lower voltage, the internal circuitry will reduce the Vref voltage down to the specified amount.
If your Vref is 5V, you will be able to have the DAC output voltages from 0V up to 5V. Similarly if you are using a 3.3V source as your Vref, you will be able to scale the DAC's output voltages from 0V to 3.3V. If you need your DAC to output a voltage, your Vref will need to be the same or a higher voltage.
The MCP4728 can choose one of two sources for its Vref,. The first is the VCC pin which can take a supply voltage between 2.7V and 5.5V. This will match the output range of the DAC to the logic level of your microcontroller.
The second option is to use the 2.048V Vref in the MCP4728 itself. Normally this would mean the highest voltage you can output is 2.048V however when using the internal Vref, you can optionally apply a 2X gain to the Vref, doubling it and allowing your output voltages to range from 0V to 4.096V
The included Vref example code shows how the Vref and gain settings work. Typing the following into the CircuitPython REPL to follow along and setup the required library imports, and instantiate the mcp4728 library object.
Additionally we'll define a variable that represents the maximum value for a 12-bit DAC like this one. When the raw_value
of a channel of the mcp4728 is set to this, it will output the maximum possible voltage for that channel, as defined by the current Vref.
from time import sleep import board import busio import adafruit_mcp4728 i2c = busio.I2C(board.SCL, board.SDA) mcp4728 = adafruit_mcp4728.MCP4728(i2c) FULL_VREF_RAW_VALUE = 4095
Next we will set the raw value for channel a to half of this full value so that the output will be half of the Vref. We're wrapping the result of dividing the max value in an `int` call to make sure the resulting value is an integer type that the raw_value
property expects.
Once this is run, measure the voltage on the VA pin with your multimeter. Since the Vref is set to VDD, which is the logic level of the microcontroller, the Vref will be 3.3V. With setting the value to half of the maximum, the resulting voltage should be 3.3V/2 or approximately 1.65V
mcp4728.channel_a.raw_value = int(FULL_VREF_RAW_VALUE/2) mcp4728.channel_a.vref = adafruit_mcp4728.Vref.VDD
mcp4728.channel_b.raw_value = int(FULL_VREF_RAW_VALUE/2) # VDD/2 mcp4728.channel_b.vref = adafruit_mcp4728.Vref.INTERNAL mcp4728.channel_b.gain = 1
Next we'll set the Vref for channel B to use the DAC's internal Vref of 2.048V. Since we are using the internal Vref, we can set the gain on the internal Vref to 1X, so the final Vref voltage remains 2.048V.
We set the value of the channel to the same value as the previous example, however when you measure the voltage on channel B's output pin VB, you will see that because we're using a different lower Vref, the resulting voltage is approximately 1.024V, again half of the 2.048V Vref.
mcp4728.channel_c.raw_value = int(FULL_VREF_RAW_VALUE/2) # VDD/2 mcp4728.channel_c.vref = adafruit_mcp4728.Vref.INTERNAL mcp4728.channel_c.gain = 2
Finally for channel C, we again set the raw value to half of the maximum, so the resulting voltage should be half of the Vref voltage. We then set the Vref source to the internal 2.048V Vref, however this time we set the internal Vref's gain to 2X, making the final Vref voltage 4.096V. With the value for the channel set to half of the maximum, we get half of the Vref value, or in this case approximately 2.048V on pin VC
Without changing output value setting compared to the first channel, we were able to change the output voltage by changing the Vref.
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT from time import sleep import board import adafruit_mcp4728 i2c = board.I2C() # uses board.SCL and board.SDA # i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller mcp4728 = adafruit_mcp4728.MCP4728(i2c) FULL_VREF_RAW_VALUE = 4095 # pylint: disable=no-member mcp4728.channel_a.raw_value = int(FULL_VREF_RAW_VALUE / 2) # VDD/2 mcp4728.channel_a.vref = ( adafruit_mcp4728.Vref.VDD ) # sets the channel to scale between 0v and VDD mcp4728.channel_b.raw_value = int(FULL_VREF_RAW_VALUE / 2) # VDD/2 mcp4728.channel_b.vref = adafruit_mcp4728.Vref.INTERNAL mcp4728.channel_b.gain = 1 mcp4728.channel_c.raw_value = int(FULL_VREF_RAW_VALUE / 2) # VDD/2 mcp4728.channel_c.vref = adafruit_mcp4728.Vref.INTERNAL mcp4728.channel_c.gain = 2 mcp4728.save_settings() while True: sleep(1)
Page last edited January 22, 2025
Text editor powered by tinymce.