0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ラズパイ5 2023年10月更新 bookworm ⑥ CPUの温度を4桁7セグメントLED表示器に

Posted at

 ラズパイ4を用いた<ラズパイ 2023年10月更新 bookworm 連載記事>をラズパイ5で再検証した記事です。

 前回、I2Cバスに接続した4桁7セグメントLED表示器に、室温を表示しました。ここでは、ラズパイ本体のCPUの温度を表示します。

IMGP2095.png

CPU温度の取得

$ vcgencmd measure_temp

temp=37.4'C

 pythonで実行して、温度を取得します。subprocessライブラリを利用します。

 最初に、subprocess.check_output()関数を使います。結果はbyte列で受け取るので、デコードします。

proc = subprocess.check_output('vcgencmd measure_temp',shell=True )

print(proc.decode())

temp=37.0'C

が得られます。

 調べると、subprocess.run()関数を利用するほうが良いような記述が出てきたので実行します。

proc = subprocess.run('vcgencmd measure_temp',shell=True, capture_output=True, text=True)

 実行結果はデコードされて.stoutで得られます。

print(proc.stdout)

temp=37.0'C

 温度の数値が欲しいので、'='で分離します。

print(proc.stdout.split('='))

['temp', "37.0'C\n"]

 後ろ側を取り出します。

print((proc.stdout.split('='))[1])

37.0'C

 ’’’で分離します。

print(((proc.stdout.split('='))[1]).split('\''))

['37.0', 'C\n']

 前側を取り出します。

print((((proc.stdout.split('='))[1]).split('\''))[0])

37.0

 文字列を実数に変換します。

print(float((((proc.stdout.split('='))[1]).split('\''))[0]))

37.0

 プログラムです。

import subprocess

proc = subprocess.check_output('vcgencmd measure_temp',shell=True )
print(proc.decode())

proc = subprocess.run('vcgencmd measure_temp',shell=True, capture_output=True, text=True)
print(proc.stdout)
print(proc.stdout.split('='))
print((proc.stdout.split('='))[1])
print(((proc.stdout.split('='))[1]).split('\''))
print((((proc.stdout.split('='))[1]).split('\''))[0])
print(float((((proc.stdout.split('='))[1]).split('\''))[0]))

 別の方法、正規化reライブラリのsub()を併用します。

 '\D'は元の文字列から数字以外を削除(数字を抽出)を使って数字を抽出すると、小数点が文字として捨てられます。

num = re.sub( r'\D', '', proc.stdout)

 xx.yという温度が得られるのがわかっていて、xxyという数字が得られるので、実数に変換して10で割ります。

print(float(num)/10.0)

 検索して、小数点を含む数字を得られる記述がありました。

[^\d.]

 勉強不足でこの正規表現を理解できませんが、使ってみます。

num = re.sub( r'[^\d.]', '', proc.stdout)
print(float(num))

 どちらの方法も、CPUの温度を得られました。文字列中に数字が1か所しか出てこないという事例です。

 プログラムです。短くなりました。

import subprocess
import re

proc = subprocess.run('vcgencmd measure_temp',shell=True, capture_output=True, text=True)

num = re.sub( r'\D', '', proc.stdout)
print(float(num)/10.0)

num = re.sub( r'[^\d.]', '', proc.stdout)
print(float(num))

CPUの温度を4桁7セグメントLED表示器に表示

 上記で得られたCPUの温度を4桁7セグメントLED表示器に表示するプログラムです。

import time
import smbus2
import subprocess
import re

i2c_address=0x71
i2c=smbus2.SMBus(1)

HT16K33_GENERIC_SYSTEM_ON=0x21
HT16K33_GENERIC_DISPLAY_ON=0x81
i2c.write_byte_data(i2c_address,HT16K33_GENERIC_SYSTEM_ON,0)
i2c.write_byte_data(i2c_address,HT16K33_GENERIC_DISPLAY_ON,0)

HT16K33_GENERIC_CMD_BRIGHTNESS=0xe0
i2c.write_byte_data(i2c_address,HT16K33_GENERIC_CMD_BRIGHTNESS,8)

def clearLED():
   i2c.write_i2c_block_data(i2c_address,0,[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])

num={0:0x3f,1:0x06,2:0x5b,3:0x4f,4:0x66,5:0x6d,6:0x7d,7:0x07,8:0x7f,9:0x67} # -;0x40,dot;0x80
seg={1:0,2:2,3:6,4:8}

def dispLED(segment,number,dot):
   if dot:
       i2c.write_byte_data(i2c_address, seg[segment], num[number] +128)  #  |= 0x80
   else:
       i2c.write_byte_data(i2c_address, seg[segment], num[number])

def disp7seg(data):
   if data<0 :
       neg=True
   else:
       neg=False
   dataString=str(data)
   dotNumPlace=dataString.find('.')+1

   dataString=str(abs(data))
   dotNumPlace=dataString.find('.')+1

   segmentPlace=1
   if neg==True:
       i2c.write_byte_data(i2c_address, seg[1], 0x40)
       segmentPlace=2
   lenString= len(dataString)
   mojiichi=1

   while lenString>0:
       dispNum=dataString[mojiichi-1:mojiichi]
       if  dispNum==".":
           mojiichi=mojiichi-1
           segmentPlace=segmentPlace-1
           dispNum=dataString[mojiichi-1:mojiichi]
           dispLED(segmentPlace,int(dispNum),True)
           mojiichi=mojiichi+1
       else:
           dispLED(segmentPlace,int(dispNum),False)
       segmentPlace=segmentPlace+1
       lenString=lenString-1
       mojiichi=mojiichi+1

# main
print("test start")
while 1:
   clearLED()
   proc = subprocess.run('vcgencmd measure_temp',shell=True, capture_output=True, text=True)
   data=float(re.sub( r'[^\d.]', '', proc.stdout))
   print(data)
   disp7seg(data)
   time.sleep(3)

 このあと、ラズパイが立ち上がったら、このプログラムが自動で実行できるようにするという設定にチャレンジしましたが、実現できていません。bookwormに代わって、systemdの記述が変わったという解説は見つかっていませんが。

0
1
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?