技術コラム(第26回)Raspberry Pi Pico(MicroPython)で温度センサを使う

はじめに

 第24回技術コラムにてRaspberry Pi Pico(以下Pico)について解説いたしました。Raspberry Pi PicoはRaspberry Pi財団自身が販売しているお手頃な開発ボードです。Raspberry Pi 財団が開発した独自プロセッサRP2040を搭載しています。開発環境としてはC/C++、Pythonを使う事ができ、第24回はMicroPythonの環境設定までをご紹介致しました。

 今回は第24回にて説明したPicoのMicroPythonを使い、温度測定を行うプログラムをご紹介したいと思います。なお、第24回技術コラムの詳細については技術コラム(第24回)Raspberry Pi PicoのPythonを使うをご覧ください。

RaspberryPi pico

ピン配置について

Picoのピン配置について示します。

RaspberryPiPicoピン配置

 ピン配置の記載を見てみると、UART0/1・GPIO・ADC・SPI・I2Cと、いくつかのインタフェースを備えている事が確認出来ます。

 今回使用する温度センサ(後述)ではADCを接続し測定を行います。実際に使うピンのみ抜き出すと以下になります。

  • ピン31:ADC0
  • ピン38:GND
  • ピン40:VBUS

 ピン36に3.3Vがありますが、今回使用する温度センサでは、動作電圧が足りません。そのため、USBから供給され、USB電圧として出力されるVBUS(5V)を使用致します。

RaspberryPiPico使用ポートのみ

温度センサについて

 温度センサとして使用するのはLM35DZというTI社(Texas Instruments Inc. :テキサス・インスツルメンツ社)の製品になります。以下、特徴を示します。

  • 動作温度範囲:0~100℃
  • 動作電圧:4~30V
  • 出力電圧:10.0mV/℃
  • 精度:±0.75℃(室温では±0.25℃)
  • パッケージ:TO-92
  • サイズ:5.2×4.19×5.2mm
LM35DZ_表_写真
LM35DZ_裏_写真

接続図について

 Picoと温度センサとの接続については、以下のようになります。

接続図

図に示したように、温度センサからの出力をADC0へ入力する事で温度測定を行います。

PicoのADCとその読み取りについて

 RP2040 ADC はオンボードのリファレンスを持っていないため、自身の電源をリファレンスとして使用します。この電圧は3.3Vで生成(生成方法について※1付きで後述)されているようです。

 ADCの分解能はPicoのデータシートより、12bit(※2付きで後述)となっており、読み出された0~3.3Vを12bit(0~4096)で表します。さらにMicroPythonを使用するため、12bitで表されたデータを16bit(0~65535)で読み取ります。(APIとしてread_u16()を使用するため)

 従って、温度センサが出力した温度値を算出するため、以下の手順で変換していく必要があります

  • ADC値の読み取り時に16bitと12bitの逆変換をする
  • ADC電圧3.3Vより参照電圧である3.3Vをかけて、温度センサの出力電圧値を算出する
  • 出力電圧値を、温度センサ仕様書にある変換式を用いて温度値へと変換する

※1 Raspberry Pi Pico Datasheet – 4.3. Using the ADC(P17)
 The RP2040 ADC does not have an on-board reference and therefore uses its own power supply as a reference. On Pico the ADC_AVDD pin (the ADC supply) is generated from the SMPS 3.3V by using an R-C filter (201ohms into 2.2μF).

※2 Raspberry Pi Pico Datasheet – 1. About Raspberry Pi Pico(P4)
 12-bit 500ksps Analogue to Digital Converter (ADC)

温度測定コードについて

import machine #ハード関連のライブラリをインポート
import utime #1s waitするためにタイマー関連のライブラリをインポート

#PIN31(ADC0)を入力として使用
adc = machine.ADC(0)
while True:
    # ADC値の読み取りに16bit(0~65535)と12bit(0~4095)の変換があるので、逆変換を行う。
    adc_voltage = adc.read_u16() / (65535 + 4095)
    # ADC電源は3.3Vのため、3.3Vをかけて電圧変換する。
    convert_voltage = adc_voltage * 3.3
    # 温度センサ仕様書の変換式を作って、温度を割り出す。
    temp = convert_voltage / (10.0 / 1000)
    
    # 表示
    print(temp)
    # 1s waitする
    utime.sleep_ms(1000)
 import machine
 import utime

 上記importにより、MicroPythonモジュールとして提供されている各種処理(ADCポート設定、タイマ設定等)を使えるようになります。本モジュール使用する場合に、特別インストールするものはなく、第24回の環境構築を行っていれば使用出来ます。

 MicroPythonハードウェア関連(Raspberry Pi Pico依存の処理)はmachineモジュールにまとまっています。machineモジュールは”特定のボード上のハードウェアに関連する固有の関数をまとめたモジュール”として抽象化されているようです。GPIO/ADCポートからの読み書きなどは、本モジュールから提供されている関数を用いる事で、他ボードとの差異を気にせずに移植等できると思われます。

adc_voltage = adc.read_u16() / (65535 + 4095) - ①

①処理により、adc_voltageにはADCより読み取られた値の逆変換された値が入ります。PicoのADCとその読み取りについての章でも記載した通り、16bit表現の最大値(:65535)と12bit表現の最大値(:4095)で読み取った値を割り、逆変換しています。

 convert_voltage = adc_voltage * 3.3 - ②

 ②処理により、温度センサから出力された電圧値へと変換しています。前述したようにADC電源は3.3Vなので、3.3Vをかけて温度センサ出力電圧値を算出します。

 temp = convert_voltage / (10.0 / 1000) - ③

 ③処理により、変換式を用いて出力電圧値を温度値に変換し、温度を算出しています。温度値へと変換するため、LM35の仕様書にある、以下変換式を変形し、T:温度測定に関する内容にして、コード化しています。

  VOUT = 10 mv/°C × T

温度測定結果

 温度測定コードを動作させた場合の結果について以下に示します。

実行結果
  print(temp)

 にてShellに表示するようにしています。

 本測定時、温度変化を見るためエアコン室温を26℃にしていました。温度センサによる測定値を見てみると、同じく26℃程度になっています。 近くに低精度ではありますが、アナログ温度計を設置しており、こちらも26℃を示していました。それなりに正確に測定できているようです。

終わりに

 今回は、MicroPythonについて簡単に調査し実験した結果をまとめさせていただきました。

組込開発.comでは、色々な開発実績を持っています。これまでの開発実績は以下リンクよりご確認ください。 

投稿者プロフィール

PicoPo
PicoPo
組込み開発歴もうすぐ10年?な者。ですがまだまだひよっこな開発者。電子基板を片手に色々とやるぞ!と意気込みだけは十分…でしょうか。Raspberry系のものを触ったり、飽きればまた別のも触ります。この頃自分が飽きっぽい性格な事に気づきました。そんな自分ですが、VR系も好きでUnityとかも趣味で触り勉強中。3Dは難しい。