(SKU:DFR0552)12-Bit I2C DAC Module

来自DFRobot Product Wiki
跳转至: 导航搜索

目录

概述

DFRobot Gravity 12-Bit I2C DAC是一款I2C接口集成有EEPROM小巧易用的数模DA转换模块,能将数字量准确地转换成对应的直流电压信号(非PWM),满足各类小型创意项目或自动控制系统的需要。该模块兼容arduino、树莓派等各种3.3V或5V主控板,虽然这类主控板要实现模拟量输出可使用PWM模拟,但这种模拟的纹波很大,而且精度不高。如要得到稳定准确的直流电压信号,必须要用DAC。此外,DAC可用于一些有趣的应用,如用作为信号发生器产生正弦波、三角波甚至是任意波形。

本模块采用12位DAC芯片MCP4725,无需外部提供参考电压(供电电压VCC与参考电压一致),支持3.3~5V宽电压供电,板载I2C地址选择开关(两个I2C地址0x60或0x61可选),最大支持2个DA模块的级联。芯片内置EEPROM,可将需要输出的DAC值写入EEPROM中,断电保存,下次重新上电时模块立刻根据存储在EEPROM的DAC值输出相应的模拟电压信号。

特性

  • 12-bit高精度数模转换
  • 内置EEPROM,断电保存DAC数据
  • Gravity I2C接口,即插即用,预留XH2.54 4P接口供扩展
  • 宽电压输入,兼容3.3V/5V控制器
  • 模块尺寸小巧,方便安装


应用场景

  • 传感器校准
  • 运动控制系统
  • 函数信号发生器


技术规格

  • 输入电压(VCC):3.3V~5.0V
  • 输出电压:0~VCC
  • 分辨率:12-bit
  • 工作电流:< 0.2mA
  • 通信接口:Gravity I2C (逻辑电平0-3.3V)
  • 产品尺寸:27mm*22mm


接口说明

12位DAC模块 引脚说明
引脚说明
标号 名称 功能描述
+ VCC 电源正极(3.3~5.0V)
- GND 电源负极
C SCL I2C时钟线
D SDA I2C数据线
ADDR I2C地址 I2C地址选择开关,拨动选择I2C地址(0x60或0x61)
VOUT VOUT DAC模拟电压输出(0~VCC)


Arduino使用教程

准备

  • 硬件
    • Arduino UNO控制板(或类似控制板) x 1
    • 12-Bit I2C DA数模转换模块 x 1
    • Gravity 4P传感器连接线(或若干杜邦线) x 1
    • 数字万用表(可选) x 1

连线图

DFR0552 connection.png

校准与可调模拟电压输出

虽然DAC的电压输出精度受多种因素影响,使实际输出电压与用户所指定电压值产生误差,但MCP4725的DAC参考电压Vref与供电电压VCC相同,供电电压的不准(实际电压并非准确的5.000V或3.300V)往往使输出误差较大。这里提供一种简易的校准方法,消除由于参考电压不准造成的误差。若不进行校准,也可根据所使用的控制器电平将下方代码中的REF_VOLTAGE设为5000(如Arduino等5V控制器)或3300(如树莓派、FireBeetle等3.3V控制器)。

用户需要自备一块高精度(3位或以上)数字万用表来完成该校准,具体步骤如下:

  1. 将模块与Arduino按照上面的连线图相连,将模块上的ADDR拨至0x60设定I2C地址。若拨至0x61,需要相应地修改下面代码中函数DAC.init()的第一个参数。
  2. 安装Arduino MCP4725库。如何安装库?
  3. 打开Arduino IDE,将下面的代码上传到Arduino UNO
  4. 使用万用表测量VOUT输出电压并将电压值写入REF_VOLTAGE。如:测得VOUT=4950mV,将“#define REF_VOLTAGE 5000”改为“#define REF_VOLTAGE 4950”。校准完成。
  • 在变量OUTPUT_VOLTAGE输入不超过REF_VOLTAGE的指定电压值(单位:mV),即可输出误差较小的模拟输出电压。在使用下面的样例代码前,可先把校准数值写入REF_VOLTAGE,以获得更准确的输出电压。
/*
 * file OutputVoltage.ino
 *
 * @ https://github.com/DFRobot/DFRobot_MCP4725
 *
 * connect MCP4725 I2C interface with your board (please reference board compatibility)
 *
 * Output a constant voltage value and print through the serial port.
 *
 * Copyright   [DFRobot](http://www.dfrobot.com), 2016
 * Copyright   GNU Lesser General Public License
 *
 * version  V1.0
 * date  2018-1-15
 */
#include "DFRobot_MCP4725.h"
#include "Wire.h"
#define  REF_VOLTAGE    5000

DFRobot_MCP4725 DAC;

uint16_t OUTPUT_VOLTAGE = 5000;        // Input DAC output voltage (0~REF_VOLTAGE,unit: mV)

void setup(void) {
  
  Serial.begin(115200);
  /* MCP4725A0_address is 0x60 or 0x61  
   * MCP4725A0_IIC_Address0 -->0x60
   * MCP4725A0_IIC_Address1 -->0x61
   */
  DAC.init(MCP4725A0_IIC_Address0, REF_VOLTAGE);

}

void loop(void) {

  Serial.print("DFRobot_MCP4725 output: ");
  Serial.print(OUTPUT_VOLTAGE); 
  Serial.println(" mV");
  
  DAC.outputVoltage(OUTPUT_VOLTAGE);

  delay(500);
}

将DAC值存入EEPROM

  • 将模块上的ADDR拨至0x60设定I2C地址。若拨至0x61,需要相应地修改下面代码中函数DAC.init()的第一个参数。
  • 打开Arduino IDE,将下面的代码上传到Arduino UNO,使用数字万用表测量VOUT输出电压。
  • 用户可修改变量OUTPUT_VOLTAGE的值改变模拟电压的输出值。REF_VOLTAGE可采用在校准一节中所使用的值,若未进行校准,可根据所使用的控制器电平将其设为5000(如Arduino等5V控制器)或3300(如树莓派、FireBeetle等3.3V控制器)。
/*
 * file OutputVoltageEEPROM.ino
 *
 * @ https://github.com/DFRobot/DFRobot_MCP4725
 *
 * connect MCP4725 I2C interface with your board (please reference board compatibility)
 *
 * Output a constant voltage value and write to the internal EEPROM.
 *
 * Copyright   [DFRobot](http://www.dfrobot.com), 2016
 * Copyright   GNU Lesser General Public License
 *
 * version  V1.0
 * date  2018-1-15
 */
#include "DFRobot_MCP4725.h"
#include "Wire.h"
#define  REF_VOLTAGE    5000

DFRobot_MCP4725 DAC;

uint16_t OUTPUT_VOLTAGE = 1000;        // Input DAC output voltage (0~REF_VOLTAGE,unit: mV)

void setup(void) {
  
  Serial.begin(115200);
  /* MCP4725A0_address is 0x60 or 0x61  
   * MCP4725A0_IIC_Address0 -->0x60
   * MCP4725A0_IIC_Address1 -->0x61
   */
  DAC.init(MCP4725A0_IIC_Address0, REF_VOLTAGE);

}

void loop(void) {

  Serial.print("DFRobot_MCP4725 write to EEPROM and output: ");
  Serial.print(OUTPUT_VOLTAGE); 
  Serial.println(" mV");
  
  DAC.outputVoltageEEPROM(OUTPUT_VOLTAGE);

  delay(200);
}

结果

  • 使用万用表可测得模块的VOUT产生1V电压信号。断开模块与Arduino的所有连接,利用模块上的焊盘,将VCC与GND分别与Arduino上的5V和GND相连,使模块重新上电,在VOUT上仍能测出1V电压。函数DAC.outputVoltageEEPROM()在输出一个指定的模拟电压信号的同时将该DAC值存储在EEPROM中,模块在重新上电的时候调用EEPROM中的DAC值,在VOUT恢复上次断电时的模拟输出电压。


正弦波模拟电压输出

  • 将模块上的ADDR拨至0x60设定I2C地址。若拨至0x61,需要相应地修改下面代码中函数DAC.init()的第一个参数。
  • 打开Arduino IDE,将下面的代码上传到Arduino UNO,使用示波器观察VOUT输出电压波形。
  • 用户可修改函数DAC.outputSin()中的参数改变输出正弦波的幅度,频率和直流偏置
/*
 * file OutputVoltage.ino
 *
 * @ https://github.com/DFRobot/DFRobot_MCP4725
 *
 * connect MCP4725 I2C interface with your board (please reference board compatibility)
 *
 * Output a constant voltage value and print through the serial port.
 *
 * Copyright   [DFRobot](http://www.dfrobot.com), 2016
 * Copyright   GNU Lesser General Public License
 *
 * version  V1.0
 * date  2018-1-25
 */
#include "DFRobot_MCP4725.h"
#include "Wire.h"
#define  REF_VOLTAGE    5000

DFRobot_MCP4725 DAC;

void setup(void) {
  Serial.begin(115200);
  /* MCP4725A0_address is 0x60 or 0x61  
   * MCP4725A0_IIC_Address0 -->0x60
   * MCP4725A0_IIC_Address1 -->0x61
   */
  DAC.init(MCP4725A0_IIC_Address0, REF_VOLTAGE);
}

void loop(void) {
  /*Output a magnitude of 2500mv, the frequency of 10HZ, DC offset 2500mv sine wave*/
  DAC.outputSin(2500,10,2500);
}

结果

  • 可观察到一个幅值为2.5V(峰峰值约为5V),频率为10Hz,带有2.5V直流偏置的完整正弦波
Sin 10Hz ZoomOut.png
void outputSin(uint16_t amp, uint16_t freq, uint16_t offset)
  • 函数说明:产生一个Vo=Voffset+Vp*sin(2*pi*f*t)的正弦波信号。当Vo>REF_VOLTAGE时,取值REF_VOLTAGE;当Vo<0时,取值0。
    • amp:单位(mV),设定正弦波幅度Vp。取值范围0-REF_VOLTAGE,取值大于REF_VOLTAGE时取REF_VOLTAGE,取0时为直流信号。
    • freq:单位(Hz),设定正弦波频率f。取值范围0~100,取值大于100时取100,取0时为直流信号。
    • offset:单位(mV),设定正弦波直流偏置Voffset。取值范围0-REF_VOLTAGE,取值大于REF_VOLTAGE时取REF_VOLTAGE。
DFR0552 Sin description.png

三角波模拟电压输出

  • 将模块上的ADDR拨至0x60设定I2C地址。若拨至0x61,需要相应地修改下面代码中函数DAC.init()的第一个参数。
  • 打开Arduino IDE,将下面的代码上传到Arduino UNO,使用示波器观察VOUT输出电压波形。
  • 用户可修改函数DAC.outputTriangle()中的参数改变输出三角波的幅度,频率,直流偏置和占空比
/*
 * file OutputVoltage.ino
 *
 * @ https://github.com/DFRobot/DFRobot_MCP4725
 *
 * connect MCP4725 I2C interface with your board (please reference board compatibility)
 *
 * Output a constant voltage value and print through the serial port.
 *
 * Copyright   [DFRobot](http://www.dfrobot.com), 2016
 * Copyright   GNU Lesser General Public License
 *
 * version  V1.0
 * date  2018-1-25
 */
#include "DFRobot_MCP4725.h"
#include "Wire.h"
#define  REF_VOLTAGE    5000

DFRobot_MCP4725 DAC;

void setup(void) {
  Serial.begin(115200);
  /* MCP4725A0_address is 0x60 or 0x61  
   * MCP4725A0_IIC_Address0 -->0x60
   * MCP4725A0_IIC_Address1 -->0x61
   */
  DAC.init(MCP4725A0_IIC_Address0, REF_VOLTAGE);
}

void loop(void) {
  /*Output amplitude 5000mv, frequency 10HZ, 
   *the rise of the entire cycle accounted for 50% of the DC offset 0mv triangular wave.
   */
  DAC.outputTriangle(5000,10,0,50);
}

结果

  • 可观察到一个幅值为5V(峰峰值约为5V),频率为10Hz,无直流偏置,占空比为50%的完整三角波
Triangle 10Hz ZoomOut.png
void outputTriangle(uint16_t amp, uint16_t freq, uint16_t offset, uint8_t dutyCycle)
  • 函数说明:产生一个三角(锯齿)波信号Vo。当Vo>REF_VOLTAGE时,取值REF_VOLTAGE;当Vo<0时,取值0。
    • amp:单位(mV),设定三角(锯齿)波幅度。取值范围0-REF_VOLTAGE,取值大于REF_VOLTAGE时取REF_VOLTAGE。
    • freq:单位(Hz),设定三角(锯齿)波频率。取值范围0~100。取值大于100时取100,取0时输出恒定0V。
    • offset:单位(mV),设定三角(锯齿)波直流偏置。取值范围0-REF_VOLTAGE,取值大于REF_VOLTAGE时取REF_VOLTAGE。
    • dutyCycle:单位(%),设定三角(锯齿)波占空比。取值范围0~100,取值大于100时取100,取0或100时成为锯齿波。
DFR0552 Triangle description.png


  • 在上述基础上其它参数不变,仅将占空比改为0,即“DAC.outputTriangle(5000,10,0,0)”可产生一个幅度为5V频率为10Hz的锯齿波
Sawtooth 10Hz ZoomIn.png


树莓派教程

本教程将演示如何在树莓派主控板上使用这款DA模块输出准确直流电压信号,EEPROM的使用和产生正弦波与三角波。

准备

  • 硬件
    • 树莓派3代B型(或类似)主控板 x 1
    • 12-Bit I2C DA数模转换模块 x 1
    • Gravity 4P传感器连接线(或若干杜邦线) x 1
    • 数字万用表(可选) x 1

接线图

DFR0552 connection (RP3).png

安装驱动

1.启动树莓派的I2C接口。如已开启,可跳过该步骤。
打开终端(Terminal),键入如下指令,并回车:

pi@raspberrypi:~ $ sudo raspi-config

然后用上下键选择“ 5 Interfacing Options ”, 按回车进入,选择 “ P5 I2C ”, 按回车确认“ YES ”即可。重启树莓派主控板。

2.安装Python依赖库与git,树莓派需要联网。如已安装,可跳过该步骤。
在终端中,依次键入如下指令,并回车:

pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get install build-essential python-dev python-smbus git

3.下载驱动库,并运行。 在终端中,依次键入如下指令,并回车:

pi@raspberrypi:~ $ git clone https://github.com/DFRobot/DFRobot_MCP4725.git
pi@raspberrypi:~ $ cd ~/DFRobot_MCP4725/RaspberryPi/python
pi@raspberrypi:~/DFRobot_MCP4725/RaspbeeryPi/python $ sudo python DFRobot_MCP4725.py

校准与可调模拟电压输出

用户需要自备一块高精度(3位或以上)数字万用表来完成校准,具体步骤如下:

  • 将模块与树莓派按照上面的连线图相连,将模块上的ADDR拨至0x60设定I2C地址。若拨至0x61,需要相应地将代码中mcp4725.setAddr_MCP4725()的参数改为MCP4725A0_IIC_Address1。
  • 打开python样例程序OutputVoltage.py,将REF_VOLTAGE和OUTPUT_VOLTAGE的值均改为5000(若模块使用3.3V,则均改为3300)并保存。
  • 在终端中,依次键入如下指令并回车,运行样例代码:
pi@raspberrypi:~/DFRobot_MCP4725/RaspbeeryPi/python $ cd OutputVoltage
pi@raspberrypi:~/DFRobot_MCP4725/RaspbeeryPi/python/OutputVoltage $ sudo python OutputVoltage.py
  • 使用万用表测量VOUT输出电压并将电压值写入REF_VOLTAGE。如:测得VOUT=4950mV,将“REF_VOLTAGE 5000”改为“REF_VOLTAGE 4950”。校准完成。
  • 在变量OUTPUT_VOLTAGE输入不超过REF_VOLTAGE的指定电压值(单位:mV),即可输出误差较小的模拟输出电压。在使用后面的样例代码前,可先把校准数值写入REF_VOLTAGE,以获得更准确的输出电压。


  • 可以通过下面两种方法打开并修改Python程序:

1.在图形化环境中使用IDLE集成开发环境修改Python程序。点击树莓派主界面上方菜单栏的“File Manager”,然后在地址栏输入“/home/pi/DFRobot_MCP4725/RaspberryPi/Python/OutputVoltage”,右击目录中的Python源码“OutputVoltage.py”,在弹出菜单中选择“Python 3 (IDLE)”,在弹出的窗口中即可编辑Python程序。完成编辑后使用快捷键“Ctrl+S”保存关闭窗口即可。

DFR0552 树莓派打开python程序.png


DFR0552 树莓派使用idle编辑python程序.png


2.在Terminal环境中使用nano编辑器修改Python程序。在Terminal中输入如下指令:

pi@raspberrypi:~/DFRobot_MCP4725/RaspbeeryPi/python/OutputVoltage $ nano OutputVoltage.py

输入指令后,即使用树莓派自带的nano编辑器打开了一个Python程序。完成代码修改后使用快捷键“Ctrl+O”保存,按回车确认,然后使用快捷键“Ctrl+X”关闭nano编辑器即可。

DFR0552 树莓派使用nano编辑python程序.png


将DAC值存入EEPROM

  • 将模块与树莓派按照上面的连线图相连,将模块上的ADDR拨至0x60设定I2C地址。若拨至0x61,需要相应地将修改代码中mcp4725.setAddr_MCP4725()的参数改为MCP4725A0_IIC_Address1。
  • 用户可修改Python例程OutputVoltageEEPROM.py中变量OUTPUT_VOLTAGE的值,以改变模拟电压的输出值。REF_VOLTAGE可采用在校准一节中所使用的值,若未进行校准,根据VCC供电的额定值输入5000(5V)或3300(3.3V)。
  • 在终端中,依次键入如下指令并回车,运行样例代码:
pi@raspberrypi:~ $ cd ~/DFRobot_MCP4725/RaspberryPi/Python/OutputVoltageEEPROM
pi@raspberrypi:~/DFRobot_MCP4725/RaspbeeryPi/python/OutputVoltageEEPROM $ sudo python OutputVoltageEEPROM.py

结果

  • 使用万用表可测得模块的VOUT产生1V电压信号。拔出模块与树莓派的所有连接,然后再重新连接相应的供电5V和GND,使模块重新上电(但不通过I2C通信),在VOUT上仍能测出1V电压。函数mcp4725.outputVoltageEEPROM()在输出一个指定的模拟电压信号的同时将该DAC值存储在EEPROM中,模块在重新上电的时候调用EEPROM中的DAC值,在VOUT恢复上次断电时的模拟输出电压。


正弦波模拟电压输出

  • 将模块与树莓派按照上面的连线图相连,将模块上的ADDR拨至0x60设定I2C地址。若拨至0x61,需要相应地将修改代码中mcp4725.setAddr_MCP4725()的参数改为MCP4725A0_IIC_Address1。
  • REF_VOLTAGE可采用在校准一节中所使用的值,若未进行校准,根据VCC供电的额定值输入5000(5V)或3300(3.3V)。
  • 在终端中,依次键入如下指令并回车,运行样例代码:
pi@raspberrypi:~ $ cd ~/DFRobot_MCP4725/RaspberryPi/Python/OutputSin
pi@raspberrypi:~/DFRobot_MCP4725/RaspbeeryPi/python/OutputSin $ sudo python OutputSin.py
  • 使用示波器观察VOUT输出电压波形。
  • 用户可修改函数mcp4725.outputSin()中的参数改变输出正弦波的幅度,频率和直流偏置

结果

  • 可观察到一个幅值为2.5V(峰峰值约为5V),频率为10Hz,带有2.5V直流偏置的完整正弦波
Sin 10Hz ZoomOut.png
 outputSin(amp,freq,offset)
  • 函数说明:产生一个Vo=Voffset+Vp*sin(2*pi*f*t)的正弦波信号。当Vo>REF_VOLTAGE时,取值REF_VOLTAGE;当Vo<0时,取值0。
    • amp:单位(mV),设定正弦波幅度Vp。取值范围0-REF_VOLTAGE,取值大于REF_VOLTAGE时取REF_VOLTAGE,取0时为直流信号。
    • freq:单位(Hz),设定正弦波频率f。取值范围0~40,取值大于40时取40,取0时为直流信号。
    • offset:单位(mV),设定正弦波直流偏置Voffset。取值范围0-REF_VOLTAGE,取值大于REF_VOLTAGE时取REF_VOLTAGE。
DFR0552 Sin description.png

三角波模拟电压输出

  • 将模块与树莓派按照上面的连线图相连,将模块上的ADDR拨至0x60设定I2C地址。若拨至0x61,需要相应地将修改代码中mcp4725.setAddr_MCP4725()的参数改为MCP4725A0_IIC_Address1。
  • REF_VOLTAGE可采用在校准一节中所使用的值,若未进行校准,根据VCC供电的额定值输入5000(5V)或3300(3.3V)。
  • 在终端中,依次键入如下指令并回车,运行样例代码:
pi@raspberrypi:~ $ cd ~/DFRobot_MCP4725/RaspberryPi/Python/OutputTriangle
pi@raspberrypi:~/DFRobot_MCP4725/RaspbeeryPi/python/OutputTriangle $ sudo python OutputTriangle.py
  • 使用示波器观察VOUT输出电压波形。
  • 用户可修改函数mcp4725.outputTriangle()中的参数改变输出正弦波的幅度,频率,直流偏置和占空比

结果

  • 可观察到一个幅值为5V(峰峰值约为5V),频率为10Hz,无直流偏置,占空比为50%的完整三角波
Triangle 10Hz ZoomOut.png
 outputTriangle(amp,freq,offset,dutyCycle)
  • 函数说明:产生一个三角(锯齿)波信号Vo。当Vo>REF_VOLTAGE时,取值REF_VOLTAGE;当Vo<0时,取值0。
    • amp:单位(mV),设定三角(锯齿)波幅度。取值范围0-REF_VOLTAGE,取值大于REF_VOLTAGE时取REF_VOLTAGE。
    • freq:单位(Hz),设定三角(锯齿)波频率。取值范围0~40。取值大于40时取40,取0时输出恒定0V。
    • offset:单位(mV),设定三角(锯齿)波直流偏置。取值范围0-REF_VOLTAGE,取值大于REF_VOLTAGE时取REF_VOLTAGE。
    • dutyCycle:单位(%),设定三角(锯齿)波占空比。取值范围0~100,取值大于100时取100,取0或100时成为锯齿波。
DFR0552 Triangle description.png


  • 在上述基础上其它参数不变,仅将占空比改为0,即“DAC.outputTriangle(5000,10,0,0)”可产生一个幅度为5V频率为10Hz的锯齿波
Sawtooth 10Hz ZoomIn.png


常见问题

Q1. 为什么所提供的MCP4725库正弦波与三角波最高仅能输出100Hz(Arduino),40Hz(树莓派),频率可以更高吗?

A. MCP4725采用I2C与主控通信,使用Arduino等传统主控板时,最高只能使用快速模式Fast(400kbps)。实际测试中(Arduino),给DA模块赋值到电压出来一次的时间差不多要180us,加上正弦或者三角波运算后所消耗的时间,仅能勉强达到一百多Hz。MCP4725的I2C虽然支持高速High-speed(3.4Mbps),但大部分主控板不支持高速模式I2C,因此受限于通信接口,输出频率难以进一步提升。

更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖。

更多

个人工具
名字空间

变换
操作
导航
工具箱