Raspberry Pi 3にAD変換器「ADS7828」とDA変換器「DAC7573」を接続します。プログラム言語はPython3でライブラリ「pigpio」を使用します。Raspberry Pi 3の設定については「pigpioによるI2CとSPIインタフェースの実装」を参考にしてください。

AD変換器「ADS7828」とDA変換器「DAC7573」の接続

AD変換器「ADS7828」とDA変換器「DAC7573」は、Raspberry Pi 3とI2Cインタフェースにより接続します。

AD変換器「ADS7828」

ADS7828は、アナログ信号をデジタル信号に変換し、12ビットのデジタル変換し8チャンネル入力を持ちます。

DA変換器「DAC7573」

DAC7573は、12ビットのデジタル信号をアナログ信号に変換し、4チャンネルのアナログ出力を持ちます。

コマンド「i2cdetect」によりRaspberry Pi 3との接続を確認します。I2Cインタフェースのアドレスは次のようになっています。

  • AD変換器「ADS7828」のアドレス – 0x48
  • DA変換器「DAC7573」のアドレス – 0x4c

AD変換器「ADS7828」のPythonスクリプト

Python3でライブラリ「pigpio」を使用して、AD変換器「ADS7828」のPythonスクリプト「mADS7828.py」を作成します。ADS7828のデータシートを示します。

デジタル変換された電圧を読み込むコマンドは、次の仕様に基づいています。「PD1, PD0」は「11」に設定しています。「SD」については、Differential Inputs「0」あるいはSingle-Ended Inputs「1」を使用します。

電圧を読み込むコマンド

デジタル変換された電圧データの受信手順は、次のようになっています。Write-Addressing後に、上記で作成したコマンドバイトを出力します。デジタル変換された電圧は、Read-Addressingの後に入力される2バイトのデータを使用します。

電圧データの受信手順

Differential InputsとSingle-Ended Inputsとで、「C2 – C0: Channel Selections」の割り当てが次のように変わります。

Channel Selection

Pythonスクリプト「mADS7828.py」を次に示します。19行目から25行目でコマンドを作成し、変数「reg_data」に保存します。28行目でコマンドを出力します。30行目で電圧値を入力し「data」に保存します。

# -*- coding: utf-8 -*- 

import pigpio
import time

ADS_ADDRESS = 0x48

class ADS7828(object):
    """コンストラクタ"""

    def __init__(self, pidata, address, internal, differential):
        self.pi = pidata
        self.internal = internal
        self.differential = differential
        self._device = pidata.i2c_open(1, address)

    def read_adc(self, channel):
        reg_data = 0
        if not self.differential:
            reg_data |= 0x80
        if self.internal:
            reg_data |= 0x0C
        else:
            reg_data |= 0x04
        reg_data |= (channel << 4)
        regtemp = reg_data
        reg_data = [reg_data]
        self.pi.i2c_write_device(self._device, reg_data)
        reg_data = regtemp
        wc, data = self.pi.i2c_read_i2c_block_data(self._device, reg_data, 2)
        if self.internal:
            return (int.from_bytes(data, 'big', signed=True) )* CONSTANT25
        else:
            return (int.from_bytes(data, 'big', signed=True) )* CONSTANT50

    def cancel(self):
        """
        Cancels the sensor and releases resources.
        """
        if self._device is not None:
            self.pi.i2c_close(self._device)
            self._device = None

if __name__ == "__main__":
    CHANNEL = 0
    pi = pigpio.pi()
    if not pi.connected:
        exit(0)

    adc = ADS7828(pi,  ADS_ADDRESS, True, True)

    while True:
        wvoltage = adc.read_adc(CHANNEL)
        print("voltage:{:.2f}v".format(wvoltage))
        time.sleep(0.5)

DA変換器「DAC7573」のPythonスクリプト

Python3でライブラリ「pigpio」を使用して、DA変換器「DAC7573」のPythonスクリプト「mDAC7573.py」を作成します。DAC7573のデータシートを示します。

デジタル値の電圧を書き込むコマンドは、次の仕様に基づいています。Extended address 「A1,A2」は「00」に設定しました。Load「L1,L2」は「01」(Update selected DAC with I2C data)に設定しました。「PD0」は「0」(Normal operation)設定しました。

電圧を書き込むコマンド

デジタル値の電圧を書き込む手順は、次のようになっています。書き込む手順は「DAC7573 as a Slave Receiver – Standard and Fast Mode」を使用しています。「SLAVE ADDRESS」後に上記で作成したコマンドを設定し、次のバイトに出力したい電圧値を設定します。

電圧を書き込む手順

書き込んだデジタル値の電圧を読み込むコマンドは、次の仕様に基づいています。この電圧の読み込みは、電圧値がうまく出力されないため、動作確認のために行います。

書き込んだデジタル値の電圧を読み込むコマンド

設定したデジタル値の電圧を読み込む手順は、次のようになっています。

設定したデジタル値の電圧を読み込む手順

作成したPythonスクリプト「mDAC7573.py」を次に示します。22行目でコマンドを作成し、変数「reg_data」に保存します。24行目でコマンドを出力します。26行目で電圧値を入力し「data」に保存します。

# -*- coding: utf-8 -*- 
import pigpio
import time

class DAC7573(object):
    DEFAULT_ADDRESS = 0x4c
    CONSTANT = 5.0 / (2 ** 12)

    """コンストラクタ"""

    def __init__(self, pidata):
        self.pi = pidata
        self._device = pidata.i2c_open(1, DAC7573.DEFAULT_ADDRESS)

    def set_voltage(self, ch, voltage):
        value = int(voltage / DAC7573.CONSTANT)
        # Clamp value to an unsigned 12-bit value.
        if value > 4095:
            value = 4095
        if value < 0:
            value = 0
        reg_data = [0x10 | (ch << 1), (value >> 4) & 0xFF, (value << 4) & 0xFF]

        self.pi.i2c_write_device(self._device, reg_data)
        reg_data = 0x10 |  (ch << 1)
        wc, data = self.pi.i2c_read_i2c_block_data(self._device, reg_data, 2)

    def cancel(self):
        if self._device is not None:
            self.pi.i2c_close(self._device)
            self._device = None

if __name__ == "__main__":
    pi = pigpio.pi()
    if not pi.connected:
        exit(0)

    logger = 0
    dac = DAC7573(pi)

    while True:
        dac.set_voltage(0,5)
        time.sleep(2.0)