« ◆光子とロドプシンによるレンジ圧縮シミュレーション | トップページ | ◇3Dプリンタ印刷後の後片づけ »

◇rasPiでDA変換(I2C制御)

 DAコンバータMCP4725(I2C制御)をrasPiに繋ぐ

DAコンバータMCP4725をrasPiのGPIOピンに接続します。

ここではブレッドボードを用いて配線しています。ケーブルはジャンパーワイヤーケーブル(メス-オス)を使用します。

+3.3とVCC(図では赤)、GNDとGND(図では白)、SDAとSDA(図では黄色)、SCLとSCL(図では水色)を接続します。
(GPIOの端子図は嵌め込みです)

出力はOUTとGND間で得られます。図では1/10の分圧のための抵抗が入っています。
実際には更に電圧切り替え時のノイズ防止用のコンデンサを適当に入れました)

 プログラムを書く

rasPiではGPIOを介しMCP4725にアクセスするプログラムをRythonで記述することができます。
以下はサイン波を出力するものです。このコードはchatGPTで生成しました。


# SignDA.py
import time
import math
import board
import busio
from adafruit_mcp4725 import MCP4725

def generate_sine_wave(
   dac: MCP4725,
   v_ref: float,
   v_min: float,
   v_max: float,
   v_offset: float,
   frequency: float,
   samples: int
) -> None:
   """MCP4725でサイン波を生成する関数"""
   while True:
      for i in range(samples):
         # サイン波の計算 (v_offset ± (v_max - v_min)/2)
         angle: float = 2 * math.pi * i / samples
         voltage: float = v_offset + (v_max - v_min) / 2 * math.sin(angle)

         # 電圧をDACの値に変換
         dac_value: int = int((voltage / v_ref) * 4095)  # 12ビット(0~4095)

         # MCP4725に出力
         print(f"dac.value = {dac_value}")
         dac.value = dac_value

         # 周波数に基づいてウェイトを挿入
         time.sleep(1.0 / (samples * frequency))

if __name__ == "__main__":
   # I2Cバスの初期化
   i2c: busio.I2C = busio.I2C(board.SCL, board.SDA)

   # MCP4725の初期化(I2Cアドレス0x60を指定)
   dac: MCP4725 = MCP4725(i2c, address=0x60)

   # サイン波のパラメータ
   v_min: float = 1.0    # 最小電圧 1V
   v_max: float = 3.0    # 最大電圧 3V
   v_offset: float = 1.5 # オフセット 2V
   frequency: float = 1 # 周波数 1Hz
   v_ref: float = 5.0    # DACのフルスケール電圧(通常5V)
   samples: int = 100    # サンプル数(1周期あたり)

   # サイン波を生成して出力
   generate_sine_wave(dac, v_ref, v_min, v_max, v_offset, frequency, samples)

ライブラリの導入も含む、プログラム起動手続きを載せます。
ライブラリの導入をifブロックに置いてありif falseをif trueとすると、ライブラリ導入を行います。
最初の1回だけtrueで実行してください。
Pythonはライブラリのバージョン依存が強く、アプリ毎に環境を作成しそこにライブラリを導入する方法がよく取られます。C++の様にstaticリンクを行う方がすなおで確実ですが、Pyhtonは混迷の道を突き進んでいます。
今回はシステムにライブラリを導入する形をとりました。その際pipコマンドに必要となるのが --break-system-packagesオプションです。


# A51_sinDA.sh
#!/bin/bash
# UTF-8 LF
THIS_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
cd ${THIS_DIR}
if [ $? -ne 0 ]; then echo "SOME ERROR OCCURED";exit; fi

#-- ここから環境設定 最初だけfalseをtrueにして流すこと
if false ; then 
pip install adafruit-circuitpython-mcp4725 --break-system-packages
pip install mypy --break-system-packages
cat < mypy.ini
[mypy]
disallow_untyped_defs = True
disallow_incomplete_defs = True
ignore_missing_imports = True
disable_error_code = no-redef
EOF
fi
#-- ここまで環境設定

echo mypy SignDA.py
mypy SignDA.py 2>&1 | grep -v 'None"'

python3 SignDA.py

# この行を消してはならない

実行し、出力をオシロで確認しました。

冒頭の写真は、サイン波の代わりに心電図(もどき)の波形を表示させたものです。
(計算部は昔「2001年宇宙の旅」のバイタル情報グラフをブログ上で動画表示するために作ったものです。pythonで試作後、javascript化が面倒で採用しませんでした)

|

« ◆光子とロドプシンによるレンジ圧縮シミュレーション | トップページ | ◇3Dプリンタ印刷後の後片づけ »