はじめに
今回は、温湿度センサーと液晶表示器のクラスを作成し、Raspberry Pi Pico 2W(以下Pico 2W)にインポートして動作させてみます。なお、本実験にあたっては、「MicroPython プログラミング・ガイドブック」(CQ出版社) を参考にさせていただきました。このガイドブックは、MicroPython初心者に向けた入門書で、言語仕様やプログラミングの方法を各種デバイスの制御方法も交えて解説しており、先ずはMicroPythonを使ってみるために必要なノウハウを網羅した内容になっています。
概要
Pythonは、すぐに開発作業が始められるよう多種多様のモジュールが用意されており、利用者はモジュールの中から必要なクラスを選択できます。例えば、machineモジュールからPinクラスをインポートすることで、使用するGPIO番号,入力/出力,プルアップ/プルダウンなど引数から簡単に設定できます。モジュールが用意されていないセンサーや表示器などのデバイスは、クラスを作成すれば以降そのクラスをインポートするだけで使うことができます。
内容
この実験では、温湿度センサーにSHT31モジュール、液晶表示器にAQM0802(8文字2行)キャラクターLCDモジュールを使用しました。これらは、過去PICマイコンの実験でも度々使ったI2Cインターフェイスのデバイスです。統合開発環境は、前回同様Thonnyです。
先ず、前出のガイドブック記事と同じベース・プログラム(下)をPico 2W本体に作成します。以降は、この環境下での実験内容になります。

次に、common.deviceモジュールに、インポートするファイルをアップロードします。また、同フォルダの __init__.py は、common.deviceモジュールをインポートしたとき自動的に実行されるファイルです。__init__.py には、インポートするファイルと実行するクラスを “from .ファイル名 import クラス名” の形式で記述します。
例えば、”from .sht31 import SHT31″ は、sht31.pyファイルからSHT31クラスをインポートするという意味です。なお、モジュール内にファイルをアップロードしても、__init__.py に上記の記述がないとインポートされないので必ず記述します。
クラス作成
クラスを作成するにあたり、そもそもクラスとは何ぞや?ということで検索すると、”オブジェクト指向におけるクラスとは、オブジェクトを生成するうえで使われる型のようなもの” という解説が出てきました。解説の内容がピンとこなかったので、更に検索したところ、次のような例えが見つかりました。
“クラスをたい焼き器(型)に例えると、インスタンスはたい焼き(実体=オブジェクト)ということになります。型は1つですが、そこからいくつでも別々のインスタンス(餡子たい焼き,カスタードたい焼き,等々)を作ることができます。”
そこで、この例えを参考にして次のようなTaiyaki_kiクラスのスクリプトを作成しました。

クラス定義
class文の後にクラス名を書き、その配下に関数を定義することでクラスを定義します。また、クラス内で定義された関数はメソッドと呼ばれており、インスタンスに対して呼び出せる関数です。
コンストラクタ
__init__メソッドはコンストラクタとも呼ばれ、クラス定義内で定義するとインスタンスが生成される際に自動的に呼び出される特殊なメソッドです。コンストラクタは、クラス・オブジェクトの属性を初期化するメソッドで、self以外に引数を追加できます。
メソッド第1引数「self」
Pythonでは、メソッドが呼び出される際、インスタンス自身をメソッドに自動で渡してくるので、これを受ける引数をメソッドの第1引数に指定するルールになっています。この引数には、一般的に self が使用されます。selfは、呼び出したメソッドが、どのインスタンスのオブジェクトのデータを操作・参照しているかをプログラムに教える役割をします。
インスタンス変数
同じクラスから作られたインスタンスが複数あるとき、インスタンスごとに持っている固有の変数です。インスタンス変数は、self.変数 の形式で定義され、self.変数 = 値 と書くことで、インスタンスごとの値を持たせることができます。Taiyaki_kiクラスを例にとると、インスタンス変数 item_name の内容は、インスタンス item_A では ‘anko’、インスタンス item_B では ‘custard’ となります。
以上の解釈から、Taiyaki_kiクラスの処理を解説します。
① item_A と item_B はTaiyaki_kiクラスから作られるインスタンスで、インスタンス item_A = Taiyaki_ki(“anko”) の生成によりコンストラクタが呼び出され、第1引数 self にインスタンス item_A 自身が、第2引数 item にインスタンスが持つ値 ‘anko’ が渡され、self.item_name = item によって、インスタンス変数 item_name は ’anko’ に初期化されます。
② get_nameメソッドも引数 self にインスタンス item_A 自身が渡され、インスタンス変数 item_name を呼び出し、文字列 “{self.item_name}_Taiyaki” にしてf-string形式で返します。
➂ print(item_A.get_name()) でインスタンス item_A 属性のget_nameメソッドを呼び出し、生成オブジェクト ‘anko_taiyaki’ が出力されます。
インスタンス item_B についても同じTaiyaki_kiクラスで同様に処理されます。インスタンス item_B 自身がメソッドの引数 self に渡されると、クラス・オブジェクトは item_B の属性になり、インスタンス変数 item_name は ‘custard’ に初期化され、print(item_B.get_name()) でインスタンス item_B の生成オブジェクト ‘custard_taiyaki’ が出力されます。
前置きが長くなりましたが、クラスの概要を押さえたところで、本題の温湿度センサーと表示器のクラスを作成します。作成と言っても自分で一から作る必要はなく、生成AIが模範コードを提示してくれるので、後は都合が良いように少し手を加えます。
sht31.py (SHT31クラス):温湿度センサーSHT31モジュール用

このスクリプトでは、インポートしたI2Cクラスから i2c.writeto と i2c.readfrom のメソッドを使用しています。i2c.writeto は指定したI2Cデバイスにデータを書き込むメソッド、i2c.readfrom はデバイスからデータをバッファに保存するメソッドです。
measureメソッドの中の try – except 文は、プログラムでエラーが起きたときに処理を止めないための仕組みです。tryの下にエラーが起こるかもしれない(通常実行する)コードを書き、exceptの下にエラーが起きたときの処理(例外処置)コードを書きます。また、except Exception as e を使うことで、例外オブジェクトを変数eに代入し、エラーの内容を確認できます。
aqm0802.py (AQM0802クラス):液晶表示器 AQM0802キャラクターLCDモジュール

Pythonでは、上記スクリプトの ‘_addr’ や ‘_buf’ のように、変数やメソッドの頭にアンダースコア「_」を1つ付けると、その変数やメソッドはクラス内でのみ使用され(プライベート)、外部からアクセスすべきではない意を示す慣例があります。
sht31_test.py:本体ファイル

メイン・スクリプトでは、生成したインスタンスに対し、クラスが返してきた温度湿度値を表示するだけです。
結果
下は、回路図とブレッドボードでの実験の様子です。作成したクラス(AI任せですが)が問題なく動作することを確認しました。

まとめ
今回は、クラスのお勉強の備忘録のような実験となりましたが、これから先もいろいろなクラスを使ったり作成したりするには、クラスの理解は避けて通れないと思います。次回は、本実験結果を踏まえて、Pico 2WのWi-Fiを使って離れた場所からセンサーの計測値を取得してみようと思います。
– 以上 –