はじめに
DS3231を使ったRTCの時刻設定をRaspberry Pi Picoではなく、Macからできないかなと思い、数年前に購入したAdafruit FT232H Breakoutを使ってRTCの時刻設定に挑戦し、てMacからPythonでRTCの日時を設定できたのでそれをまとめました。
検証環境
- macOS : 15.6
- Python : 3.12.2
- pip : 25.1.1
- Adafruit FT232H Original version
- WINGONEER 小型DS3231 AT24C32 I2Cモジュール用の高精度リアルタイムクロックモジュール,ボタン電池付き(A145)
FT232Hの役割
Raspberry Pi PicoなどのシングルボードコンピュータであればLEDやセンサーなどのデバイスを直接接続し、シングルボードコンピュータで動作するC言語やMicroPython、CircuitPythonなど書かれたプログラムからI2C、SPI、GPIOを利用してデバイスを制御できますが、デスクトップPCやラップトップPCにはIセンサーなどのデバイスを直接接続できないためI2CやSPIなどデバイスと通信できません。これを解決するのがFT232Hです。
FT232HがデスクトップPCやラップトップPCとセンサーなどのデバイスとの橋渡しをし、デスクトップPCやラップトップPCでシングルボードコンピュータと同じプログラムでセンサーなどを制御できるようにします。
CircuitPython Libraries on any Computer with FT232H Overviewにそのイメージが図解で説明されています。
デスクトップPCやラップトップPCで動作するPythonからCircuitPythonのライブラリを利用刷るためのライブラリblinkaが必要になります。
環境構築
FT232H経由でデバイスを制御するためにPythonを利用します。ここではPythonはインストールされていることを前提に説明します。
CircuitPython Libraries on any Computer with FT232Hを元に環境を構築します。
ライブラリのインストール
FT232HにUSB経由でアクセスするためのUSB接続用のライブラリlibusbをbrewでインストールします。
$ brew install libusb
Pythonモジュールのインストール
デスクトップPCやラップトップPCのPythonからFT232HにアクセスするためのライブラリpyftdiとFT232H経由で接続したセンサーなどのデバイスにアクセスするためのCircuitPythonライブラリを利用できるようにするライブラリ`adafruit-blink`をインストールします。
$ pip install pyftdi
$ pip install adafruit-blinka
動作テスト
ライブラリ、モジュールのインストールが完了したらデスクトップPCやラップトップPCとFT232HをUSBケーブルで接続し、ターミナルから次の操作で、FT232Hを認識しているかを確認するためにCircuitPython Libraries on any Computer with FT232HのMac OSXのテストに記載されている内容を実行します。
- 環境変数
BLINKA_FT232Hに1をセット - Pythonを起動し、REPLから
boardモジュールをロードし、FT232Hdir()関数でboardオブジェクトの内容を確認します。
正しくインストールできていると以下に示すようににエラーがなく、FT232Hのピン情報が表示されます。
$ export BLINKA_FT232H=1
$ python
Python 3.12.2 (main, Feb 29 2024, 19:33:31) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import board
>>> dir(board)
['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7', 'D4', 'D5', 'D6', 'D7',
'I2C', 'MISO', 'MOSI', 'SCK', 'SCL', 'SCLK', 'SDA', 'SPI', '__blinka__',
'__builtins__', '__cached__', '__doc__', '__file__', '__loader__',
'__name__', '__package__', '__repo__', '__spec__', '__version__',
'ap_board', 'board_id', 'detector', 'pin', 'sys']
>>>
インストール後のチェック
CircuitPython Libraries on any Computer with FT232HのPost Install Checksに示されているFT232Hを認識しているかを確認します。FT232HではUSB接続用チップとしてFTDIのチップを使用しています。PythonでFTDI用のモジュールをロードして確認します。直前の動作テストで認識できているのは確認できているので正しく動作するはずです。
Pythonを起動し、REPLから次のコードを入力します。
from pyftdi.ftdi import Ftdi
Ftdi().open_from_url('ftdi:///?')
実行結果を以下に示します。FT232HのURLがftdi://ftdi:232h:1/1であることが表示されました。
$ python
Python 3.12.2 (main, Feb 29 2024, 19:33:31) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyftdi.ftdi import Ftdi
>>> Ftdi().open_from_url('ftdi:///?')
Available interfaces:
ftdi://ftdi:232h:1/1 ()
Please specify the USB device
$
以上でMacからFT232Hが利用できるようになりました。
RTC用のPythonモジュールのインストール
FT232Hに接続するRTC用のPythonモジュールadafruit-circuitpython-ds3231をpipコマンドでインストールしてます。
pip install adafruit-circuitpython-ds3231
接続
RTCのVCCをFT232Hの5Vに、GNDをGNDに接続します。
FT232HでI2Cを利用するときはD0がSCL、D1とD2がSDAになります。D1とD2は互いに接続します。D0とRTCのSCL、D1とD2をRTCのSDAに接続します。
CircuitPython Libraries on any Computer with FT232HのPinoutを参照。
配線図を以下に示します。
I2Cデバイスのアドレスをスキャン
デバイスの接続が完了したら次のプログラムで接続したI2Cデバイスのアドレスをスキャンしてみます。
import board
i2c=board.I2C()
print("Scan port")
port = i2c.scan()
for i in port:
print(hex(i))
実行結果を示します。
$ python i2caddressscan.py
Scan port
0x57
0x5f
0x68
5つのアドレスが表示されました。それぞれは表に示すデバイスのアドレスです。
| アドレス | デバイス |
|---|---|
| 0x57 | RTCのEEPROM |
| 0x5F | RTCのEEPROM |
| 0x68 | DS3231 |
デバイスのアドレスを確認できました。
プログラム
ここまででMacからFT232Hを経由してRTCデバイスへのアクセスが可能になりました。
BLINKAを利用することが前提になるので環境変数を設定し忘れた場合も考慮して、下記のコードをプログラム冒頭部に配置するのが良いようです。
import os
os.environ['BLINKA_FT232H'] = '1'
RTCに日時を設定する
目的のRTCの日時設定のコードを以下に示します。
日時を扱うモジュールdatetime、デバイスとの通信などをサポートするモジュールboard,
RTC用モジュールadafruit_ds3231を読み込みます。
現在の日時のオブジェクトdtを生成し、RTCとI2C通信するオブジェクトrtcを生成し、dtオブジェクトのtimetuple()メソッドを用いてRTCへ書き込む日時のデータ(time.struct_time)を取得して、RTCの日時を設定しています。
import os
os.environ['BLINKA_FT232H'] = '1' # BLINKAを使用
from datetime import datetime
import board
import adafruit_ds3231
def main():
# 現在の日時取得
dt = datetime.now()
print(f"datetime:{dt}")
# I2Cを開く
i2c = board.I2C()
# RTCのオブジェクト
rtc = adafruit_ds3231.DS3231(i2c)
# 現在の日時でRTCの日時を設定
rtc.datetime = dt.timetuple()
# RTCの日時を取得し、表示
rtct = rtc.datetime
print(f"RTC:{rtct}")
if __name__ == "__main__":
main()
以上でFT232Hを通してMacからRTCデバイスの日時を設定できました。
さいごに
FT232H購入時にはなぜかうまくできず、放置していて今回の再挑戦でうまくできました。
ここには記していませんがADT7410を使った温度センサやSSD1306を使ったOLEDディスプレイもMacからFT232H経由で値の取得や表示ができました。ADT7410はSCLとSDAをプルアップしないと値の取得ができませんでした。プルアップには4.7kΩの抵抗器を使用しました。
