【Arduino】DACモジュール(MCP4725)を使う

it

デジタルアナログ出力モジュールMCP4725を使いました。
マイコンからI2C経由で命令を送ることで、アナログ信号を出力することができます。
DACモジュールの使い方とDACボードの比較、マイコンから出力できるDACとの性能比較をします。

DACモジュール(MCP4725)

簡単紹介

電源電圧までの任意のアナログ電圧を出力する。
MCP4725基板を2枚使いました。
当ページではそれぞれを以下の紹介の呼称にします。

◆MCP4725-Red

◆MCP4725-Blue

MCP4725(MCP4725A0)ではI2Cアドレスを60(h)または61(h)のどちらかを選択できます。
この2枚の基板はI2Cアドレスの設定の方法が違います。
それぞれの設定方法についてはこちら

◆関連記事

ピン配置

◆MCP4725-Red

◆MCP4725-Blue

外観

◆MCP4725-Red

◆MCP4725-Blue

使ってみた

◆開発環境

Arduino環境で開発しました。
制御するマイコンボードはRaspberry Pi Picoを使用しました。
ボードライブラリにはAdafruitの「Adafruit MCP4725 by Adafruit」を使用しました。
簡単な命令セットで扱いやすいです。

◆アナログ出力とPWM出力

DACによるアナログ出力とPWM出力の違いで、LEDの光り方の変化を見ました。
アナログ出力はLEDのVFになるまで発光せず、電圧が上昇してからゆっくり点灯ゆっくり消灯しました。
PWMはDutyの低いうちからゆっくり点灯します。
LEDの輝度調整はPWMの方が制御が簡単ですが、遅い周期のPWMは点滅のちらつきが気になることがあります。

◆アナログ出力

出力できる電圧範囲は0Vから電源電圧までです。
電源電圧を最小の2.7Vと最大の5.5Vまで入力し、三角波を出力しました。
出力電圧はオシロスコープ(HDS272)で読み取ります。

オシロスコープの1ch(黄)の三角波はDAC出力を読み取った波形です。
2ch(青)はDACモジュールの電源電圧です。
最大値は電源電圧まで変化しています。

こちらはサンプルスケッチにあった正弦波を出力した結果です。
綺麗な波形を読み取ることができました。

◆I2C通信

モジュールはI2Cで接続します。
通信を使うことで設定速度への影響を調査しました。
ベンチマークにADCを内蔵しているXIAO SAMD21の設定速度と比較しました。

約60倍XIAO SAMD21の方が早い結果でした。

MCP4725XIAO SAMD21
1秒間に実行できるADC設定(回)7,299469,266


まとめ

簡単にアナログ波形の出力ができました。

今回2種類のボードを試しましたが、精度や分解能に差異はありません。
I2Cアドレスの設定方法が異なり、半田作業で固定して使うかピン配置で変更するの違いです。

気になる点としては通信(I2C)を使うため繰り返しの設定が遅く、DACをマイコンに搭載しているSAMD21やESP32-WROOMと比べると頻繁なアナログ出力の変更には不利です。

準備

◆開発環境

Arduino環境でRaspberryPi Picoを使用します。
Arduino環境の準備はこちらの記事で紹介しています。

◆ボードライブラリ

Raspberry Pi Picoを使用します。
Arduino IDEのボードマネージャからRP2040用のライブラリのインストールとボードの選択をします。
ボードライブラリには「Raspberry Pi Pico/RP2040 by Earle F. Philhower, III」を使用します。
Generic RP2040またはRaspberry Pi Picoを使用します。

追加のボードマネージャのURLhttps://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
検索RP2040
ボードライブラリRaspberry Pi RP2040 Boards(x.x.x)※
選択するボードRaspberry Pi RP2040 Boards(x.x.x) > Raspberry Pi Pico
※動作確認はバージョン 4.1.1です

◆モジュールライブラリ

モジュールライブラリには「Adafruit MCP4725 by Adafruit」を使用します。

ライブラリ名検索動作確認時バージョン
Adafruit MCP4725 by Adafruitmcp47252.0.2

準備

◆I2Cアドレスの変更(MCP4725-Red)

I2Cアドレスは60(h)または61(h)を選択できます。
アドレスは基板上の「ADDR」のパターンショートすることで変更できます。
デフォルトは画像左側の60(h)で、パターンは左と中央がショートした状態です。

◆I2Cアドレスの変更(MCP4725-Blue)

I2Cアドレスは60(h)または61(h)を選択できます。
アドレスは基板上のA0が未接続で60(h)、電源をショートさせると61(h)に変更できます。

スケッチサンプル

三角波アナログ出力

説明

三角波を出力します。
最大出力電圧は3.3Vを入力し、MCP4725の分解能12bit(4095)分を1bitずつ加算し、最大値になったら1bitずつ減算します。

出力した波形はオシロスコープで読み取ります。

配線

配線はDACモジュールに3.3Vを印加しています。
DACの出力設定では3.3Vまで出力します。

DACから5Vを出力する場合は、DACモジュールのVCCの電源供給元にVBUSまたはVSYSを接続します。

スケッチ

#include <Wire.h>
#include <Adafruit_MCP4725.h>

#define MCP4725_SDA   (0)
#define MCP4725_SCL   (1)

Adafruit_MCP4725 dac;

void setup(void)
{
  Wire.setSDA(MCP4725_SDA);
  Wire.setSCL(MCP4725_SCL);
  Wire.begin();

  dac.begin(0x60);  

  while(1)
  {
    for (int16_t i = 0; i < 4095; i ++)
    {
      dac.setVoltage(i, false);
    }
    for (int16_t i = 0; i < 4095; i ++)
    {
      dac.setVoltage((4095 - i), false);
    }
  }
}

void loop(void)
{
}

結果

VCCに3.3Vを印加した場合と、5.0Vを印加した場合の結果です。
電源電圧により扱いたい電圧のレンジを設定できました。
どちらもリニアに変化しています。

三角波アナログ出力

説明

ADCの設定速度を測ります。

ベンチマークとしてADC機能のあるXIAO SAMD21を使います。
XIAO SAMD21を2つ使い、1つはMCP4725, 1つはDACを制御します。
それぞれ0 ~ 3.3V、3.3V ~ 0Vに設定するスケッチを書き込みます。

それぞれのアナログ出力をオシロスコープ(HDS272)でモニタし、設定速度を計測します。

XIAO SAMD21のADCは10bit(0 ~ 1023), MCP4725のADCは12bit(0 ~ 4095)です。
3.3Vまでの設定回数を同じにするため、MCP4725は0 ~ 1023までのインクリメントに4倍して設定しています。

メモ:直接ADCを使えるマイコンにはEspressifのESP32-WROOMもあります。
ESP32-WROOMのADCは8bit(0 ~ 255)分解能で、2ch使えます。

配線

スケッチ

#include <Wire.h>
#include <Adafruit_MCP4725.h>

#define MCP4725_SDA   (D0)
#define MCP4725_SCL   (D1)

Adafruit_MCP4725 dac;

void setup(void)
{
  dac.begin(0x60);  
}

void loop(void)
{
  while(1)
  {
    for (int16_t i = 0; i < 1024; i ++)
    {
      dac.setVoltage(i << 2, false);
    }
    for (int16_t i = 0; i < 1024; i ++)
    {
      dac.setVoltage((4092 - (i << 2)), false);
    }
  }
}
#define DAC_PIN     (0)

void setup()
{
}

void loop()
{
  while(1)
  {
    for(int i = 0; i < 1024; i ++)
    {
      analogWrite(DAC_PIN, i);
    }

    for(int i = 0; i < 1024; i ++)
    {
      analogWrite(DAC_PIN, 1023 - i);
    }
  }
}

結果

XIAO SAMD21のADCとMCP4725のADCの設定速度を比べました。
三角波の波形は2046回の設定で1周期です。

MCP4725XIAO SAMD21
三角波1周期の時間(ms)2804.36
1回のADC実行時間(us)※11372.13
1秒間に実行できるADC設定(回)7,299469,266

※1 : 三角波1周期の時間 ÷ 2046

応答速度はXIAO SAMD21 ADCが圧倒的に速い結果でした。
分解能が細かいMCP4725には設定値を4倍に計算する含まれていますが、結果に影響はないものと考えています。

MCP4725-RedとMCP4725-Blue

説明

MCP4725-RedとMCP4725-Blueのアナログ出力を比べます。

どちらも同じ値を設定し同じ変化をさせます。
オシロスコープで出力電圧をモニタし重ねて表示します。

MCP4725-BlueはI2Cアドレスを61(h)にするためにA0端子に3.3Vを印加しています。

配線

スケッチ

#include <Wire.h>
#include <Adafruit_MCP4725.h>

#define MCP4725_SDA   (0)
#define MCP4725_SCL   (1)

Adafruit_MCP4725 dac_r;
Adafruit_MCP4725 dac_b;

void setup(void)
{
  Wire.setSDA(MCP4725_SDA);
  Wire.setSCL(MCP4725_SCL);
  Wire.begin();

  dac_r.begin(0x60);  
  dac_b.begin(0x61);

  while(1)
  {
    for (int16_t i = 0; i < 4095; i ++)
    {
      dac_r.setVoltage(i, false);
      dac_b.setVoltage(i, false);
    }
    for (int16_t i = 0; i < 4095; i ++)
    {
      dac_r.setVoltage((4095 - i), false);
      dac_b.setVoltage((4095 - i), false);
    }
  }
}

void loop(void)
{
}

結果

黄がMCP4725-Red、青がMPC4725-Blueのアナログ出力波形です。
完全に重なっているため青がほとんど見えません。
性能差は無いようです。

アナログ出力とPWM出力

説明

ADCの出力とPWMの出力でLEDの点灯の違いを確認します。

ADCは0 ~ 3.3Vまでを直線的に変化させます。
PWMもDuty 0 ~ 100%を直線的に変化させます。

ADCは分解能12bit(0 ~ 4095)の変化をする繰り返し文により設定しています。
PWMは同じ繰り返し文を使用しますが、分解能8bit(0 ~ 255)で回数が合わないため、4bit右シフトによりスケール調整してます。

配線

スケッチ

#include <Wire.h>
#include <Adafruit_MCP4725.h>

#define PWM_PIN       (15)
#define MCP4725_SDA   (0)
#define MCP4725_SCL   (1)

Adafruit_MCP4725 dac;

void setup(void)
{
  Wire.setSDA(MCP4725_SDA);
  Wire.setSCL(MCP4725_SCL);
  Wire.begin();

  dac.begin(0x60);  

  while(1)
  {
    for (int16_t i = 0; i < 4095; i ++)
    {
      dac.setVoltage(i, false);
      analogWrite(PWM_PIN, (i >> 4));
    }
    for (int16_t i = 0; i < 4095; i ++)
    {
      dac.setVoltage((4095 - i), false);
      analogWrite(PWM_PIN, ((4095 - i) >> 4));
    }
  }
}

void loop(void)
{
}

結果

黄がADCによるアナログ電圧、青がPWM制御です。
LEDがゆっくり点灯ゆっくり消灯しました。
黄の消灯時間が長いのは、LEDのVF未達時間があり発光できないため。
青は通電中は3.3Vで通電時間の長短でなのでなめらかな輝度変化に見えます。

オシロスコープは黄LEDは黄波形、青LEDは青波形です。
黄は電圧が直線的に変化しています。
青はPWMによりLow時間とHigh時間の変化を示したかったのですが、波形がつぶれてしまいました。

コメント

タイトルとURLをコピーしました