ラズパイ5 pythonの仮想環境 ⑧ 12ビットA-DコンバータADS1015<その1>
ラズパイにはアナログ入力はありません。I2Cバスに接続して利用できるAdafruitの12ビットA-DコンバータADS1015を利用します。
Stemma QT/Qwiic(JST SH 4ピン)コネクタは2か所に装着されていて、どちらにつないでもかまいません。このコネクタを使ってI2Cで制御する場合、特に、ジャンパ線をつなぐなどは不要です。
コネクタは、表と裏のどちらも差し込めそうですが、ピンが内部の上部に並んでいるので、差し込める方向は一意です。ロック機構はないですが、すぐに抜けるということはありません。
●ADS1015の主なスペック
- 解像度 12ビット
- 基準電圧 内蔵
- 電源電圧 2.0~5.5V
- 入力 差動(A0-A1、A0-A3、A1-A3、A2-A3)、シングル(A0、A1、A2、A3とGND)
- 増幅器 プログラマブル前置アンプ内蔵(PGA)フルスケール;±6.144V、±4.096V、±2.048V、±1.024V、±0.512V、±0.256V
- 変換方式 ΔΣ(デルタ・シグマ)方式
- 変換速度 128、250 、490 、920、1600 、2400 、3300、3300SPS
- インターフェース I2C(0kHz~3.4MHz)
- I2Cのスレーブ・アドレス デフォルト0x48、A0ピンをショートすると0x49(0x4a、0x4bも設定可能)
●環境
- ハードウェア Raspberry Pi 5(4GBモデル)
- OS Raspberry Pi OS (64ビット)、リリース日December 5th 2023
- Windows10 22H2にて、ssh(OpenSSH_9.2p1 Debian-2+deb12u2, OpenSSL 3.0.11 19 Sep 2023)および、VNC Viewerを動作させている
●接続
●仮想環境に入る
このA-Dコンバータを動かすための専用の仮想環境encadcを作ります。
yoshi@ras05:~ $ python -m venv envadc
yoshi@ras05:~ $ source envadc/bin/activate
(envadc) yoshi@ras05:~ $ pip list
Package Version
---------- -------
pip 23.0.1
setuptools 66.1.1
(envadc) yoshi@ras05:~ $
●pythonのADS1015ライブラリをインストール
(envadc) yoshi@ras05:~ $ pip install ads1015
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting ads1015
Downloading https://www.piwheels.org/simple/ads1015/ads1015-1.0.0-py3-none-any.whl (9.0 kB)
Collecting i2cdevice>=1.0.0
Downloading https://www.piwheels.org/simple/i2cdevice/i2cdevice-1.0.0-py3-none-any.whl (10 kB)
Collecting smbus2
Using cached https://www.piwheels.org/simple/smbus2/smbus2-0.4.3-py2.py3-none-any.whl (11 kB)
Installing collected packages: smbus2, i2cdevice, ads1015
Successfully installed ads1015-1.0.0 i2cdevice-1.0.0 smbus2-0.4.3
(envadc) yoshi@ras05:~ $ pip list
Package Version
---------- -------
ads1015 1.0.0
i2cdevice 1.0.0
pip 23.0.1
setuptools 66.1.1
smbus2 0.4.3
ADS1015のライブラリがありました。
ADS1015 4 channel differential/single-ended ADC
デバイス自体は古いのですが、4か月前にGitHubで更新されているので、放置されてはいないようです。
●サンプル・プログラムの実行
GitHub ads1015-python/examplesにあるread-all.py をads1015.pyの名称で保存し実行しました。
(envadc) yoshi@ras05:~ $ python ads1015.py
Traceback (most recent call last):
File "/home/yoshi/ads1015.py", line 3, in <module>
from ads1015 import ADS1015
File "/home/yoshi/ads1015.py", line 3, in <module>
from ads1015 import ADS1015
ImportError: cannot import name 'ADS1015' from partially initialized module 'ads1015' (most likely due to a circular import) (/home/yoshi/ads1015.py)
自分自身を import して循環してしまったというエラーのようです。ファイル名をads1015a.pyに変更して実行しました。
(envadc) yoshi@ras05:~ $ python ads1015a.py
read-all.py - read all three inputs of the ADC
Press Ctrl+C to exit!
Found: ADS1015
Reference voltage: 0.295v
in0/ref: 0.295v
in1/ref: 0.295v
in2/ref: 0.295v
A0-GNDをショートしました。
in0/ref: -5.981v
in1/ref: -0.382v
in2/ref: 0.313v
in0/ref: -6.065v
in1/ref: 0.439v
in2/ref: 0.292v
0Vであるはずですが、正しく読み出せていないようです。
●pythonのsmbus2ライブラリを使う
先ほどのADS1015ライブラリを削除します。
(envadc) yoshi@ras05:~ $ pip uninstall ads1015
Found existing installation: ads1015 1.0.0
Uninstalling ads1015-1.0.0:
Would remove:
/home/yoshi/envadc/lib/python3.11/site-packages/CHANGELOG.md
/home/yoshi/envadc/lib/python3.11/site-packages/LICENSE
/home/yoshi/envadc/lib/python3.11/site-packages/README.md
/home/yoshi/envadc/lib/python3.11/site-packages/ads1015-1.0.0.dist-info/*
/home/yoshi/envadc/lib/python3.11/site-packages/ads1015/*
Proceed (Y/n)? Y
Successfully uninstalled ads1015-1.0.0
(envadc) yoshi@ras05:~ $ pip list
Package Version
---------- -------
i2cdevice 1.0.0
pip 23.0.1
setuptools 66.1.1
smbus2 0.4.3
smbus2は残されたようです。
プログラムです。デバッグのためにprint文がたくさん入っています。オシロスコープで波形を常時出したいので、初期設定もループの中に入れてあります。
i2c_rdwrは、combined write/read transactions with repeated startです。ADS1015は、リピーテッド・スタート・コンディションを要求しているデバイスです。
ループの際ののブロックでは、Config Register(0x01)に設定値を書き込んでいます。二番目のブロックは、そのConfig Registerを読み出しています。
3番目のブロックは、Conversion Register(0)を読み出し、16ビットのデータを2の補数の処理sign16(x)をし、12ビットのデータを取り出し(raw_s >> 4)、今回は、フルスケールを±6.144 Vに設定したので乗じて、11ビット(2^11=2048)で割ることで、電圧を計算しています。
●各種設定をするコンフィグ・レジスタ
プログラムの最初で、コンフィグ・レジスタ(Config Register)を設定します。アドレス・ポインタ・レジスタは0x01です。
- bit1 OS。'1'で変換開始。デフォルト1
- bit14、bi13、bit12 チャネル・セレクト。
000 : AINP = AIN0 and AINN = AIN1 (デフォルト)
001 : AINP = AIN0 and AINN = AIN3
010 : AINP = AIN1 and AINN = AIN3
011 : AINP = AIN2 and AINN = AIN3
100 : AINP = AIN0 and AINN = GND
101 : AINP = AIN1 and AINN = GND
110 : AINP = AIN2 and AINN = GND
111 : AINP = AIN3 and AINN = GND - bit11、bit10、bit9 PGA。
000 : FSR = ±6.144 V
001 : FSR = ±4.096 V
010 : FSR = ±2.048 V (デフォルト)
011 : FSR = ±1.024 V
100 : FSR = ±0.512 V
101 : FSR = ±0.256 V
110 : FSR = ±0.256 V
111 : FSR = ±0.256 V - bit8 MODE。0;連続、1;ワンショット(デフォルト)
- bit7、bit6、bit5 サンプルレート。
000 : 128 SPS
001 : 250 SPS
010 : 490 SPS
011 : 920 SPS
100 : 1600 SPS (デフォルト)
101 : 2400 SPS
110 : 3300 SPS
111 : 3300 SPS - bit4 COMP_MODE;コンパレータ。 0
- bit3 COMP_POL ;コンパレータ。0
- bit2 COMP_LAT ;コンパレータ。0
- bit1、bit0 COMP_QUE[1:0] ;コンパレータ。11
from smbus2 import SMBus, i2c_msg addr = 0x48 def sign16(x): print('start test') while 1: with SMBus(1) as bus: write = i2c_msg.write(addr, [1]) write = i2c_msg.write(addr, [0]) |
●入力に電圧源をつなぐ
基準電圧源TL431を電池で駆動した電源をA0-A1につなぎます。テスタで測ると2.49Vでした。
実行中のターミナルの様子です。2.49xVが電源のA0-A1間の電圧です。
●関数化した
from smbus2 import SMBus, i2c_msg addr = 0x48 i2c = SMBus(1) def sign16(x): def readVoltage(): # main while 1: |
◆入力を、A0端子とGND間のシングルエンドに変更;100 : AINP = AIN0 and AINN = GND
コンフィグ・レジスタ(Config Register)を設定内容[0x80,0x83]を[0xc0,0x83])に変更し、A0端子をGNDへショートしました。0Vです。
A0端子をVin端子につなぎました。3.3Vです。