で、秋月に売ってるDAC MCP4922を使ってみました。ブレッドボードに刺さったまま2年くらい経ってる子。動かし方は電子部品使い方:マイコンのD/A変換さんを見ました。12Bitで、電源2.7V~5.5Vまでで動きます。
#なんか後でこの記事読んだけど全くさっきのサイトさんと一緒だったのでどうしよう感に溢れてる
一応データシートのp.18~19を見ると分かる通り、SPI通信で16bitのデータを送ることで制御します。16bitの中身は、
bit 15:DAC AかBを選ぶ。Aなら0、Bなら1
bit 14:Vrefの入力をバッファするか選ぶ。バッファするなら1、しないなら0(Vrefのインピーダンスがとても高い時に使う)。デフォルトだとUnbuffered(データシート4.1.2章より)。
bit 13:出力を2倍するかしないか。2倍するなら0、しないなら1。2倍すると単純にVout = 2 * (Vref * Data / 4096)となる。
bit 12:出力を出すかどうか?かな?0だと出力がハイインピーダンスになるみたい。
bit 11~0:出力する値のデータ(12bits)
らしいです。
MICROCHIP MCP4921/4922 Datasheet p.1より、VrefバッファとソフトウェアSHDNの位置 |
制御線のタイミングはp.19のFig.5-1を見てください。
MICROCHIP MCP4921/4922 Datasheet p.19より、制御タイミング |
Arduinoで動かすならこんな感じのクラスを作って(一応まとめてみた)
#include < SPI.h > class MCP4922 { private: const int SDI; const int CS ; const int LDAC; public: MCP4922 () : SDI(11), CS(10), LDAC(9) { } void initialize(){ pinMode(SCK, OUTPUT); pinMode(SDI, OUTPUT); pinMode(CS, OUTPUT); pinMode(LDAC, OUTPUT); digitalWrite(SCK, LOW); } void setDACvalue(unsigned int value){ SPI.begin(); digitalWrite(LDAC, HIGH); digitalWrite(CS, LOW); //データを送る SPI.transfer(0b01110000 | (0b00001111 & highByte(value))); //highByte()とlowByte()はArduinoで使える関数 //使えないときはhighByte(s):(s >> 8)、lowByte(s):s & 0xFFで。 SPI.transfer(lowByte(value)); digitalWrite(CS, HIGH); digitalWrite(LDAC, LOW); SPI.end(); } };
で、呼び方はこんな感じ
void setup() { } void loop(){ MCP4922 dac1; dac1.initialize(); for(unsigned int i = 0; i < 0x0FFF; i++){ dac1.setDACvalue(i); delay(5); } }
こうすると徐々に電圧が上がっていくのがわかる…それだけ
一応出力は15(Typ.)~24(Max.)mAまで出るっぽいけど、怖いんでバッファ付けたいとは思ってる。どうやらこのDACはそれなりに使われてるようで、こんなボードを作っている方も外国にいらっしゃるみたい。うーん、出力に非反転増幅で2倍してるけど、2倍だとVccが10V近く必要になる…Bi-FETオペアンプでボルテージフォロアにしてもいいけど、短絡とか発振とか考えるとなかなか怖い、お茶目に真空管でカソードフォロアはちょっとレベル高すぎた。見た感じZout=1/gmだけどそれってそこまで下がらないよね