2024年4月20日土曜日

RP2040でR-2R DACを試してみる

I2Sの勉強をしていたら、R-2RというDACのことを知った。
せっかくなので、試しに作って遊んでみる。

参考文献はこちら→https://www.mech.tohoku-gakuin.ac.jp/rde/contents/course/mechatronics/anadigi.html

上記サイトの上のほうの回路図にあるように、正確な抵抗のセットが2n本と、n個のDOがあれば、n bitのアナログ出力が作れるということ。
今回はDO4つ+R 3つ+2R 5つで、4bitを作ってみる。
Rの値は電源とマイコンの電流入出力能力を超えない範囲で選べばよいが、今回はわかりやすく1kΩと2kΩで作ってみた。

お行儀はよくないがGP18をLOWにしてGND代わりとしている。
GP21-24がDOで、A0で結果を読み取っている。

結果は以下のようになった。
ガタガタしているのは、抵抗のバラつき起因と思われる。
オーディオ用途で拘って作る人々は、チップ抵抗で16bit, 24bitを作って、抵抗器をやすりで削って微調整しているらしい。
一度トライしてみたい。

今回作ったものの精度はともかく、こんな簡単な回路でアナログ出力ができるというのは本当に面白い。


オマケで、結果の取得に使ったThonnyのコード。
汚いけどそのまま貼ります。
整数0~15を2bitの01の0埋め文字列に変換する部分、もっといいやり方がある気がするけど動けばいいやの精神。

import time

LED = machine.Pin(25, machine.Pin.OUT) # GP25をLEDとして出力端子に設定
GND = machine.Pin(18, machine.Pin.OUT)
GND.off()
bits = [
    machine.Pin(24, machine.Pin.OUT)
    ,machine.Pin(23, machine.Pin.OUT)
    ,machine.Pin(22, machine.Pin.OUT)
    ,machine.Pin(21, machine.Pin.OUT)
]
VIN = machine.ADC(0)
conv = 3.3/65535
conv = 1

print("start")
print("----")

def v(order):
    print(order, end="")
    print(": ", end="")
    for i in range(4):
        if order[i] is "0":
            bits[i].off()
        else:
            bits[i].on()
    time.sleep_ms(10)
    print(VIN.read_u16()*conv)

for i in range(2**4):
    t = ("000" + str(bin(i)).replace("0b", ""))[-4:]
    v(t)  

0 件のコメント:

コメントを投稿