0
0

More than 1 year has passed since last update.

FT232HとMCP3004/MCP3008でPCにアナログ入力

Last updated at Posted at 2022-10-31

Windows PCにPython、FT232H、MCP3004の組み合わせでアナログ信号処理

GPIOボードFT232HとACコンバータMCP3004の組み合わせ。
BLINKA使用

※ラズパイの記事や、古い作法しか見つけられなかったため、メモとして残す。
※書いてる人は普段は電気/電子回路やらない人です。

FT232Hについて

秋月:https://akizukidenshi.com/catalog/g/gM-08942/
本家:https://learn.adafruit.com/adafruit-ft232h-breakout
USB接続でGPIO入出力ポートを設けるモジュール。
単純なデジタル信号だけでなく、I2CとSPI、2種のシリアルフォーマットも利用できる。

FT232HとCircuitPython、BLINKAのインストールについては本記事では省略
↓ adafruitの「setup」に倣った。
https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/setup

MCP3004 について

秋月:https://akizukidenshi.com/catalog/g/gI-11987/
製品説明書:https://akizukidenshi.com/download/ds/microchip/mcp3008.pdf
10bit X 4チャンネル、SPIシリアル出力のADコンバーター。
姉弟製品に2チャンネルのMCP3002や8チャンネルのMCP3008がある。
※シリアル出力ということは信号線が1本ということ、「10bitだから10ポート」ではない。

  • 5V 電源での最大サンプルレート 200 ksps / 3Vでは100ksps程度。
  • 最大クロックは1~3MHzあたり(?)
  • サンプリングが実用的クロックは(使用環境次第で)10kHz程度まで下がる(説明書のp22)
  • ※高レートほど消費電力が増えるような?

FT232Hへの接続

とにかく7~14番はすべて繋いでしまえ! (※厳密には12番はアナログ入力のグランドですが、ここではアナログ信号の電源もFT232Hからとってる前提。)
・電源V_DDはFT232Hの5V、(3.3Vでも可のはず)
・参照電圧V_REFは電源と同じ、
・クロックは当然接続必須だろう。
・チップセレクトはどういうものかよくわからないがCircuitPython側で必須っぽい。FT232HのD5に繋いだ。
・SerialDataOutは、今回は入力信号だけなので繋がなくてもよいのか?とか思たけど、これ繋がないと動作しない感じだった。
↓ SPIのSCLK、MOSI、MISOについてはBlinkaで指定されているから迷うこともない。
image.png

※CSチップセレクトについて、恐らく(実態と違うかもしれないがコンセプト的には)、複数のSPI/I2Cデバイスでクロック等を共有し、CSで処理対象を切り替えるといった使い方をする。のかな(?)

CircuitPythonのMCP3XXXシリーズのバンドルを利用

ヘルパーというのかドライバーというのかしらないけど、要するに必要なものはすでに用意されているということ。
https://github.com/adafruit/Adafruit_CircuitPython_MCP3xxx/tree/df768ac18242e15077d96dd4aa6fc714de5c9133/adafruit_mcp3xxx

pipで追加インストール
> C:\**\python.exe  -m pip install adafruit-circuitpython-mcp3xxx

サンプルコード

MCP3004の0番ポート(1番ピン)にアナログ信号を入力する場合のサンプルです。

Python3
#!python3

import os
os.environ['BLINKA_FT232H'] = '1' #Setting Environmental Variable

import board
import busio
import digitalio

import adafruit_mcp3xxx.mcp3004 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn

##  https://github.com/adafruit/Adafruit_CircuitPython_MCP3xxx/blob/df768ac18242e15077d96dd4aa6fc714de5c9133/adafruit_mcp3xxx/mcp3004.py
##  ( https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/spi )

##  create library object using our Bus SPI port
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)

# create the cs (chip select)
cs = digitalio.DigitalInOut(board.D5)

# create the mcp object
VR=5.0  ##  3.3
mcp = MCP.MCP3004(spi, cs, ref_voltage=VR )

# create an analog input channel on pin 0
chan = AnalogIn(mcp, MCP.P0)

print("Raw ADC Value: %d / (Max%d) "%( chan.value>>6, 2**10) )
print("ADC Voltage: %g / (Max%g) V"%(chan.voltage, VR) )

※ ADコンバータMCP3004の分解能は10bitですが、PythonAPI上(MCP.MCP3004の中)で16bitに換算された値がchan.valueに格納されてます。
上のサンプルでは6ビットシフトして10bitに戻した値を表示しています。

ロジアナ

なんか妙に遅いので
ロジックアナライザで信号みてみました。

image.png

黄緑色チャンネル/橙色6角形が MISO(MPC3008の出力側)
ADの値は 509 = 0111111101 (値が一個ずれてるのはクロックの設定がまずいのかな)
0CHで非差動
(青色チャネル/黄緑6角形 MOSIの「1」2個はStart信号1と非差動の1で、直後の「0」3個がCH番号です。)
1個の値取得に3バイト分24単位ほど通信するようですね。
SPIクロック2MHz弱で作動している模様。cs0._pin.mpsse_gpio._controller.frequency の値2000000と一致。(?)
24 / 2M = 12 マイクロ秒 くらい。

ただし......

image.png

↑ このように CS が落ちてからと、CS 上がるまでのタイムラグが長い。
全体で0.8ミリ秒くらいかかってます。
ということは1チャンネルのデータ取得を反復したときに1000Hz強くらいのサンプリングレートになる。
遅いのこの部分か。

image.png

↑ 2 データ続けて取得した場合

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0