エレキ素人が何か考える（その８）：DAコンパーター

# DAコンパーターMCP4911を使う
秋月電子で入手した[DAコンパーターMCP4911](https://akizukidenshi.com/catalog/g/gI-11988/)をArduino Unoで使ってみる。ちなみに、このArduinoには、DAコンバーターが存在しない。

## データシート
データシートは、[ここ](https://akizukidenshi.com/download/ds/microchip/MCP4911.pdf)にある。ピン配置を抜粋すると下記のとおり。
![ピン配置.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/5e37bdca-1f20-193a-7249-75159a3357c3.png)
SPI対応しており、ArduinoのPin10をCS、Pin11をSDI、Pin13をSCKに接続する。また、VddおよびVrefを5V、VssおよびLDACをGNDに接続する（データシートを読み解くとLDACはGND接続でOK）。Voutが出力されるアナログ電圧となる。

ここでは、Voutの電圧を測定するとともに、VoutをArduinoのPin A0に接続し、DAコンバーターの結果をADコンバーターへFeedbackする。回路図的には下記のとおり。
![MCP4911_回路図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3943a3a0-0948-e283-0521-df293ac054b0.png)

## ソースコード
本家にある[ライブラリ](https://www.arduino.cc/reference/en/libraries/mcp_dac/)を利用し、サンプルコードであるMCP4911_testを改良したソースコードが下記である。

```c++
#include "MCP_DAC.h"  // MCP4911ライブラリ
#define CS 10         // ArduinoのCSピン
#define CH 0          // MCP4911チャネル

MCP4911 MCP;  // Hardware SPI
int res;      // 分解能

void setup() {
  Serial.begin(115200);
  Serial.println("DA conveter test");

  MCP.begin(CS); // chip select
  res = MCP.maxValue();
  Serial.print("MAXVALUE:\t");
  Serial.println(res);  // MCP4911では1023
  delay(100);  
}

void measure(int val) {
  MCP.analogWrite(val, CH);        // MCP4911へのwrite
  delay(100);
  Serial.print("Write Value: ");
  Serial.print(val);
  Serial.print("\t");
  Serial.print("Read Value: ");
  Serial.println(analogRead(A0));  // Arduino ADコンバーターからのread
}

void loop() {
  for (int value = 0; value <= res; value += 128) {  // 0から128おきにテスト
    measure(value);
    delay(200);
  }
  measure(res);  // 最大値1023のテスト
  delay(200);
}
```

## 実験
配線と電圧値の測定状況。
![IMG_6025.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/7e010742-53c7-cf8e-3bba-6140b2527270.jpeg)
電圧値の変化、0Vからおよそ5Vまでの変化が見られる。
![2022_03_12_17.05.45.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/490d18d8-f367-8b17-db4f-dbdbdb21deab.jpeg)

Arduinoのシリアルコンソールの状況。WriteとReadとの値に若干の差があるがまずまずか、、、。
```
DA conveter test
MAXVALUE:	1023
Write Value: 0	Read Value: 0
Write Value: 128	Read Value: 125
Write Value: 256	Read Value: 253
Write Value: 384	Read Value: 382
Write Value: 512	Read Value: 510
Write Value: 640	Read Value: 639
Write Value: 768	Read Value: 767
Write Value: 896	Read Value: 896
Write Value: 1023	Read Value: 1023
Write Value: 0	Read Value: 0
Write Value: 128	Read Value: 124
Write Value: 256	Read Value: 253
Write Value: 384	Read Value: 381
Write Value: 512	Read Value: 512
Write Value: 640	Read Value: 640
Write Value: 768	Read Value: 767
Write Value: 896	Read Value: 896
Write Value: 1023	Read Value: 1021
Write Value: 0	Read Value: 0
Write Value: 128	Read Value: 124
Write Value: 256	Read Value: 253
Write Value: 384	Read Value: 382
Write Value: 512	Read Value: 511
Write Value: 640	Read Value: 639
Write Value: 768	Read Value: 768
Write Value: 896	Read Value: 896
Write Value: 1023	Read Value: 1021
Write Value: 0	Read Value: 0
Write Value: 128	Read Value: 125
Write Value: 256	Read Value: 253
Write Value: 384	Read Value: 382
Write Value: 512	Read Value: 511
Write Value: 640	Read Value: 639
Write Value: 768	Read Value: 767
Write Value: 896	Read Value: 896
Write Value: 1023	Read Value: 1021
Write Value: 0	Read Value: 0
Write Value: 128	Read Value: 124
Write Value: 256	Read Value: 253
Write Value: 384	Read Value: 381
Write Value: 512	Read Value: 510
Write Value: 640	Read Value: 640
Write Value: 768	Read Value: 767
Write Value: 896	Read Value: 895
Write Value: 1023	Read Value: 1020
```

EOF