はじめに
RaspberryPi PicoでMicroPythonを使って、温度センサ「TMP102」とI2C通信をする方法を解説します。
TMP102は配線や通信内容が簡単なので、はじめてI2C通信をする方にもおすすめのセンサーです。
~ この記事の内容 / Contents ~
- 初めてI2C通信をする。
- MicroPythonでサクッとI2C通信をしてみたい。
- センサーで温度を測ってみたい。
環境
この記事は以下の環境で作成しています。
環境 | バージョン | 備考 |
開発用PCのOS | Windows 11 | Windows7,10でもOKです |
言語 | MicroPython | |
開発環境 Thonny | 4.1.4 | |
温度センサ | TMP102 | |
ボード | RaspberryPi Pico |
※ Picoのセットアップ方法については、こちらの記事をご覧ください。
温度センサ TMP102
初心者でも扱いやすいI2C通信型の温度センサです。1.4~3.4Vで動作可能なので、Picoの3.3Vピンをつなぐだけで動きます。通信内容もシンプルなのでプログラミングを学びたい方にもおすすめです。配線・プログラムとも、後述の内容をコピぺで動せます。
※ 画像はSparkFunのHPより引用
PicoとTMP102の接続
以下のように、PicoとTMP102を接続します。旧型のためADD0の位置が違いますが、右側の赤い基盤がTMP102です。
ピン番号 | Pico | TMP102 |
1 | I2C0 SDA | SDA |
2 | I2C0 SCL | SCL |
3 | GND | GND |
23 | GND | ADD0 |
36 | 3.3V (OUT) | V+ |
Picoピンアサイン(Pin-Out)
※ Pico公式サイトより引用
使用する部品
今回の回路では、以下の部品を使用します。
RaspberryPi Pico
Pico本体です。一時期は半導体不足の影響がありましたが、今は価格・納期とも安定しています。
温度センサTMP102
今回使い方を解説する温度センサです。
ブレッドボード
国内サンハヤト製のブレッドボードです。少々堅めの指し心地ですが、海外製と違ってピン穴の番号がすべて印刷されており、品質も高いのでおすすめです。
ジャンパワイヤ(キット)
固いジャンパワイヤがセットになったキットです。やわらかい配線よりスッキリした回路が作れます。
ジャンパワイヤ(自作用)
キットだと丁度いい長さがない、色がない。という方は以下の配線で自作できます。ジャンパワイヤとほぼ同じ固さの配線なので、切って曲げるだけで理想のジャンパワイヤが作れます。
実行結果
後述する「温度取得のコード」の実行結果は以下の通りです。
TMP102から取得した温度情報がThonny下部のシェル画面に表示されます。
全体コード
TMP102から温度情報を取得する、MicroPythonのコードです。
from machine import Pin, I2C
import time
# I2Cに使うピンの設定です
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)
# デバイスのアドレスをスキャンします
addr = i2c.scan()
print( "address is :" + str(addr) )
# 温度情報を100回取得します
for i in range(100):
# OSのI/Oエラーが良く出るので、Try-exceptで囲います
try:
# tmp102の温度情報(12bit)は2byteに分かれて送られるため
# 2byte分Readします。
data = []
data = i2c.readfrom(72,2)
# 12bit は 1つ目の8bit全て、2つ目の下位4bitをに分かれます。
# そのため、2つのデータをビットシフトして足します。
tmp = data[0] << 4
tmp += data >> 4
# 値1で、0.0625度となるため、計算した値にその値を掛け算して
# 温度情報に変換します。
print(tmp * 0.0625)
time.sleep(1)
except:
print("Error")
time.sleep(1)
コードのポイント
I2Cのピン設定とアドレスの取得
I2C通信に使うピンを設定します。ピン番号は以下の「GP〇」の番号を指定してください。今回は「GP0」と「GP1」を使います。
正しいピン番号が指定できていれば、i2c.scan()で、TMP102のアドレス「72(0x48)」が取得できます。
# I2Cに使うピンの設定です
i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)
# デバイスのアドレスをスキャンします
addr = i2c.scan()
ADD0でアドレス番号を安定させる
TMP102は「ADD0」のピンに電圧をかけるかどうかで、デバイスのアドレスが変わります。ADD0への接続は必須ではありませんが、アドレスが不安定になる場合は、ADD0への接続を試してみてください。
(今回はPicoのGNDに接続してアドレスを72に設定しています)
ADDR0への接続 | アドレス |
3V3 (OUT) を接続 | 73 |
0V(GND)を接続 | 72 |
未接続 | 73 / 72 が不安定に切り替わる場合あり |
i2c.readfrom()で温度データを取得する
i2c.readfromで温度データを取得します。引数に「取得するデバイスのアドレス」と「データ数」を指定すると、戻り値でTMP102からの温度データが配列が返されます。
TMP102の温度データは2byteなので、以下のようにデバイスのアドレス(72)と、データ数(2)を指定します。温度情報はdataの配列に代入されます。
# tmp102の温度情報(12bit)は2byteに分かれて送られるため
# 2byte分Readします。
data = []
data = i2c.readfrom(72,2)
温度データから温度へ変換する
取得した配列2byte(16bit)のデータうち、温度データとして使われるのは12bitのみです。
そのため、以下のビットシフト・計算をしてデータから温度を作成します。ビットシフトの内容はイメージと合わせて後述します。
# 12bit は 1つ目の8bit全て、2つ目の下位4bitをに分かれます。
# そのため、2つのデータをビットシフトして足します。
tmp = data[0] << 4
tmp += data >> 4
# 値1で、0.0625度となるため、計算した値にその値を掛け算して
# 温度情報に変換します。
print(tmp * 0.0625)
① 1つ目のデータ(data[0])を、左に4ビットシフト
1つ目のデータの「8~1のビット」に、温度データの「12~5ビット」のデータが格納されています。
そのままではビットの番号が合わないので、ビットを左にシフトして温度データのビットの番号に合わせます。シフトした結果は、tmpという変数に代入します。
② 2つ目のデータ (data[ 1])を右に4ビットシフト
2つめのデータの「8~5ビット」に、温度データの「4~1ビット」のデータが格納されています。
こちらもビット番号が合わないので、ビットを右にシフトして温度データのビットの番号に合わせます。
(右にあふれたデータは削除、左側には0が追加されます)
シフトすると、tmpの空いている部分にピッタリと合うようになるので、2つ目のデータをtmpに結合(足し算)します。
この変換で、「tmp」に、TMP102の温度データ(12bit)の値をセットすることができます。
実際の温度への変換
TMP102からの温度データの単位は、0.0625度となっています。そのためtmpの内容に0.0625を掛け算すると、実際の温度の数値になります。
上のイメージの、tmp(0001 1010 0000)を十進数にすると「416」になります。
416 × 0.0625の掛け算をすると「26度」になります。
まとめ
Raspberry Pi Picoで、MicroPythonを使ってI2C通信を行う方法について解説しました。参考になればうれしいです。
I2Cで使える機器は他にもたくさん
温度センサ以外にも、I2Cで接続できる機器はたくさんあります。今回覚えた知識を使って、ぜひ他のデバイスにもチャレンジしてみてください。
以下はPicoで使えるデバイスの一例です。
ディスプレイ
小型のディスプレイです。MicroPythonの用のライブラリが用意されている「SSD1306」が制御ICに使われているので、ライブラリを使って簡単にプログラムすることができます。
※ 以下のリンク先から購入して、こちらの記事で使い方を解説しています。
CO2センサ
二酸化炭素濃度を測るセンサーです。コロナ渦ですっかり身近になりました。3V~5Vで動作するのでPicoでも扱えます。
IMU (3軸角度/加速度センサー)
3.3V、I2Cで使える3軸の角度/加速度センサーです。とても安価ですが、遊びや勉強用途には十分な性能を持つセンサーです。
お知らせ
MicroPythonのプログラミングガイドブックが遂に発売!
「MicroPython」の本が遂にでました。
この一冊で、MicroPythonの言語仕様から、プログラミングの仕方まで”ガッツリ”学べます!。
内容は、普段別言語で開発している人や、これからマイコンを始める(工学系の)学生を対象としているので「初心者向け」ではありません。しかし、「自前のライブラリの作成」が目標なので、これ一冊で「ガッツリ」とMicroPythonを学ぶことができます。
全ての内容はここでは紹介しきれないので、詳細は以下のAmazonページをご覧ください。目次だけでも”ガッツリ”なのが確認できると思います。
Pico/Pico W関連のおすすめ本
RaspberryPi Pico / Pico W関連のおすすめ本を独断と偏見で3つ選んでみました。Picoやるならとりあえずこれ買っとけ的な本や、電子工作全般で使える本などを厳選しています。
質問・要望 大歓迎です
「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。
使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。
こんにちは、初見です。大変参考になります。
ところで、秋月電子通商でM-14538という「距離センサー」があります。サンプルソフトはArduinoしかありません。
これを複数個使いたいと考えてます。
I2Cのセンサーをアナログスイッチで切り替える事例をみたことあります。今回センサーのSCLを10kΩでプルアップしてから、TLP222(フォトMOSリレー(ON抵抗2Ω)で複数個のSCLを切り替えて使おうと思ってます。
本題はここからで、Arduino ではなくpicoでやりたいと思ったのですが I2C通信について Arduino からマイクロパイソンに書き換える方法が判らなくて断念しているところです
Arduino が複雑でパイソンがシンプルなのは なぜなのか
知りたいところです。
電気だいすきオジサンさん こんにちは。
ご質問ありがとうございます。
私もM-14538は使ったことはないのですが、
秋月のM-14538のサンプルコード(Arduino)を見てみました。
後半のreadDistanceの関数は参考(?)として書かれているだけなので、なくても動きそうですね。
MicroPythonとの違いや、書き換えについては、もう少しコード見てから再度コメントさせてもらいます。
秋月のコードを少し読み進めてみました。
MicroPythonがなぜシンプルなのか、については以下の要因があるかしれません。
・Serial.begin() や Serial.print() が print()のみでシンプルに書ける。
・変数の宣言時に型の指定がいらない。
・setup(), loop()など必須の関数がない。
ただそれよりも秋月のサンプルコードの書き方が複雑さを高めている気がします。
(使わない関数を記載、同じ変数を関数間で使えるように関数の外で定義など)
いずれにしても、M-14538を動かせるPythonのコードがあったほうが話が早いかと思ったので、
秋月にM-14538を一つ発注してみました。
届き次第コードの移植と動作確認をして、記事を作成する予定ですので、
もう少々お待ちいただければと思います。
ちなみに秋月は発注が多く納期が延びているようです。
電子工作の輪が広がるのはいいことですが、困ったものですね ^^;
M-14538(mtof171000c0)が届いたので、MicroPythonで動かく方法を記事にまとめました。よろしければご覧ください。
【質問回答】RaspberryPi Pico MicroPythonでMTOF171000C0を動かす方法
同じようなことを動かしたことがあります、参考になれば・・・
Maker_Pi_RP2040の紹介
人についていくロボットカー
今話題の、マイコンラズハ゜イ・PICO(RP2040)を使ってロボットカーを動かしてみました
ハード構成は、たったこれだけ
1)制御用マイコンボード:Maker_Pi_RP2040
2)距離センサ:vl53l0x 2個
3)DC-モータ 2個
ソフトは、adafruit社のライブラリとサンプルのおかげで、ほとんどコピーしただけです。
結果の動きは、ロボットカーについてきてもらうには、コツがいりますが、かえってその動きが楽しく、良い運動になってます!!!
youtubeに動画をアップしておきました。
https://youtu.be/Xsuf-nzJ51A
プログラム含むファイルをギガファイル便にアップしておきました
https://xgf.nu/gHZA
jh1cdv00さん、コメントありがとうございます。
ロボットカーいいですね~。
vl53l0の距離センサも、Picoで動かすのは簡単なんですね。
ソースも見てみたいところなんですが、ギガファイル便のURLへ飛ぶと、
アップロード画面に飛んでしまうみたいです。URL確認してもらると助かります。
ビット演算 << >> などがわからず 解説を調べていました
このサイトは どこよりも 詳しく解説されていますね
ありがとうございます
次は是非とも AD変換を同じようにわかりやすく解説してほしいです
よろしくお願いいたします
吉田さん
コメントありがとうございます。えすです。
ビット演算は分かりづらいですよね。
私も初めは苦戦して、図にすると一番分かりやすかったのでイメージ図で解説してみました。
お役に立ててうれしいです。
AD変換についても、同じように解説できればと思います。
以下の「Pico内蔵のAD変換の記事の補足が欲しい」「別のAD変換基板などの使い方が知りたいなど」
詳細なリクエストはありますでしょうか?
https://tech-and-investment.com/raspberrypi-pico7-adc-cds/
お気軽にコメントいただければとうれしいです。
えす様
メッセージを書いていただきありがとうございました
arduinoでは温度センサとか湿度センサなどはスケッチのサンプルがあったのでコピーして 電子工作していました
raspberrypiではAD変換するためにコードを書かなければなりませんが
大変難しく いろいろなサイトを見ていました
その中で えす様のサイトに辿り着きました
ビット操作についての解説がとてもわかりやすく書かれています
多分 温度センサ ADコンバータの仕組みは似ているだろうと思いますが
まだまだ 理解不足です
次回は是非 えす様に解説を書いていただきたいと思っております
例えば 下記のようなコードなど詳しく書いていただければと思っております
https://101010.fun/iot/raspi-adc-mcp3425.html
吉田さん
詳細ありがとうございます。えすです。
URLありがとうございます。拝見しました。
恐らく、Picoではなくて、ノーマルのRaspberryPiをお使いのようですね。
RaspberryPi <--(I2C)--- A/Dコンバータ(基板) <--(アナログ値)-- 温度センサ という感じで使用されたいのかな?と推測しています。 URLとは違うものですが、手持ちでI2C接続のA/Dコンバータがあったので、 RaspberryPiでの使い方の記事を書いてみたいと思います。 ご期待に添えるかわかりませんが、 少々お待ちいただければと思います。
吉田さん
えすです。
リクエストをいただいた、A/D変換の記事を作成してみました。
https://tech-and-investment.com/raspberrypi2-5-ads1015/
手持ちかつ、ライブラリから簡単に使える「ADS1015」を使った内容にしてみたのですが、リクエストに応えられていますでしょうか?
不足や疑問、感想・他のリクエスト等があれば、
お気軽にコメントしてくださいね。