HOME → 1 Raspberry Pi → 03 作品集 → 

Raspberry Pi 気象情報をキャラクタLCDに表示 & CSVファイルへの書き出し

Raspberry Pi 作品集
温度・湿度・気圧を
液晶キャラクタデバイスへの表示 と CSVファイルへの保存
 
Raspberry Pi のLCDを見れば、温度・湿度・気圧が判る様にする。
 
液晶 16文字x2行 へ 月日・時刻・温度・湿度・気圧 を表示。
 

 

スポンサー リンク

 

 
 
 
1. Raspberry Pi モデル B+
 
使用中の「Raspberry Pi」は、初期のモデル「B+」でリビジョンは「0010」。
 
ハードウェアのモデルを確認する方法。
cat /proc/cpuinfo
 
cat /proc/cpuinfo
 
 
Pythonによる 基盤のリビジョン番号を確認するコマンド。
sudo python
>>> import RPi.GPIO as GPIO
>>> GPIO.RPI_REVISION
 ・・・ Ctrl + D で終了
 
Pythonによる 基盤のリビジョン番号を確認する
リビジョン番号は「3」と表示される。
I2Cのチャンネル番号(I2Cバス番号)は「i2c_channel = 1」とする。
 
 
※:次のコマンドが使えない。
cat /proc/device-tree/model
 → cat: /proc/device-tree/model: No such file or directory
 
初期のモデル「B+」を最新の「Raspberry Pi OS(32-bit)」で稼働させてみる → 立ち上がりに相当な時間を要するが、稼働OK!

「cat /proc/device-tree/model」コマンドが使える。
Raspberry Pi Model B Plus Rev 1.2

このコマンドでは、「Rev 1.2」と表示される。
 
 
OSのバージョンを確認するコマンド。
cat /etc/os-release
 
OSのバージョンを確認
 
カーネルのバージョンを確認するコマンド。
uname -a
 
カーネルのバージョンを確認
 
Pythonのバージョンを確認するコマンド。
python --version
 
Pythonのバージョンを確認する
 
 
 
2. Raspberry Pi で I2Cデバイスを利用するための準備
 
1. raspi-config で I2C を有効化する。
sudo raspi-config
 
「8 Advanced Options」を選択する。
「8 Advanced Options」を選択する
 
「A6 I2C」を選択する。
「A6 I2C」を選択する
 
「Yes」を選択する。
「Yes」を選択する
 
「OK」を選択する。
「OK」を選択する
 
 
2. I2Cのカーネルモジュールを有効化する。
/etc/modules の編集。
sudo nano /etc/modules
 
起動時にカーネルモジュールを自動的に読み込むために、以下のように /etc/modules に i2c-dev を追加する。
起動時にカーネルモジュールを自動的に読み込むために、以下のように /etc/modules に i2c-dev を追加する
 
 
3. 読み込み拒否設定の変更。
sudo nano /etc/modprobe.d/raspi-blacklist.conf
 
デフォルトで I2C のカーネルモジュールがブラックリストに入っていているため、以下のようにコメントアウトしてこれを外す。
デフォルトで I2C のカーネルモジュールがブラックリストに入っていているため、以下のようにコメントアウトしてこれを外す
 
 
4. I2Cの操作に利用するライブラリーやコマンドのインストール。
sudo apt-get install i2c-tools
 
 
5. 「ACM 1602NI」液晶キャラクタデバイス用に動作クロックを50Khzに設定。
sudo nano /etc/modprobe.d/i2c.conf
 
「options i2c_bcm2708 baudrate=50000」を追記する。
「options i2c_bcm2708 baudrate=50000」を追記する
 
 
6. smbus(I2C制御用ライブラリーのpython版)のインストール。
sudo apt-get install python-smbus
 
 
7. 再起動。
sudo reboot
 
 
8. シリアル通信 baudrate 設定の確認。
dmesg | grep i2c
 
実行結果。
シリアル通信 baudrate 設定の確認
 
 
 
3. 使用した部品
 

①.湿度センサー:
HIH6130:スイッチサイエンス 3,743 円

②.気圧センサー:
MPL115A2:秋月電子通商 600 円

③.照度測定用CdSセル(光センサー):
GL5528 1MΩ:秋月電子通商 40 円

④.ADコンバーター:
ADS1015:スイッチサイエンス 1,393 円

⑤.液晶キャラクタデバイス:
ACM1602NI-FLW-FBW:秋月電子通商 800円。 
 
①.HIH-6130 デジタル湿度センサ。slave addresses (0x27) 。
HIH-6130 デジタル湿度センサ
・動作電圧:2.3~5.5V
・補正された湿度の範囲:10~90% RH
・補正された温度の範囲:5℃~50℃ ← 5℃以下が不可
・I2C通信による出力 → 4バイト出力
 
 
②.MPL115A2 気圧センサモジュール。slave addresses (0x60) 。
MPL115A2 気圧センサモジュール
 
MPL115A2の利用に当たっては、急激な電圧変化に対応するために、2番端子(CAP)に「1μF」 の積層セラミックコンデンサーを接続し、コンデンサーへの充電や放電で電圧を滑らかにする。
2番端子(CAP)に「1μF」 の積層セラミックコンデンサーを接続し、コンデンサーへの充電や放電で滑らかな電圧にする
 
 
③.照度測定用 CdSセル(光センサー):GL5528 1MΩ。
・明るい状態(10Lux)10~20KΩ。
・暗い状態 500KΩ。
照度測定用CdSセル(光センサー):GL5528 1MΩ
 
CdSセルの抵抗値変化による電圧を取得して、デジタルに変換。
CdSセルの抵抗値変化による電圧を取得して、デジタルに変換
 
④.ADS1015: 12 ビット、3.3kSPS、4 チャネル・デルタ・シグマ ADC
CdSセル(光センサー)のアナログ情報を入力して、デジタル情報に変換するために購入。
ADS1015は、12 ビット(4096)のデータに変換するので約4000段階の値が取得できる。

ADS1015: 12 ビット、3.3kSPS、4 チャネル・デルタ・シグマ ADC
 
PGA (プログラマブル・ゲイン・アンプ) と発振器と VREF とコンパレータと I2C 搭載。https://www.ti.com/product/ja-jp/ADS1015
 
slave addresses(ADDRピンの接続先でアドレスが選択できる)。
ADS1015: slave addresses
 
 
⑤.液晶キャラクタデバイス:ACM1602NI-FLW-FBW。
I2C接続キャラLCDモジュール 16×2行 白色バックライト付。
液晶キャラクタデバイス:ACM1602NI-FLW-FBW
 
※:この I2C デバイスは「 i2cdetect 」でアドレスが取得できない ‼。
Slaver address could only set to 1010000, no other slaver address could be set.
 
液晶キャラクタデバイス:ACM1602NI-FLW-FBW
 
液晶に表示される文字のコントラストは、3番端子にかける電圧で調整できる。この為に抵抗で電圧を変化させるが、どの程度の電圧にすれば適切なコントラストになるか分からないので、「可変抵抗」を利用する。但し、一度調整したら変えることは無いので「10kΩの半固定抵抗」を使用した。
 
さらに、バックライトの点灯操作を行える様に、ACM1602NIの6番端子を「GPIO 4(端子番号:7番)」に接続し、電圧が不安定にならない様に「1kΩ」の抵抗でプルダウンする。
ACM1602NIの6番端子を「GPIO 4(端子番号:7番)」に接続し、電圧が不安定にならない様に「1kΩ」の抵抗でプルダウンする
 
 
 
 
4. 液晶キャラクタデバイスへの表示内容と表示位置
 
これらのセンサーから値を取得する回路と、取得した値をHDMI端子に接続しているディスプレイに表示するプログラムを作った。
 
しかしこれだと、ディスプレイがなければ役に立たないので、液晶キャラクタデバイスに表示し、 Raspberry Pi 単独で 『百葉箱』 になるようにした。
 
液晶キャラクタデバイスへの表示内容。 
LCDへの表示設計
 
表示位置の指定。
 
LCD表示位置
 
Raspberry Pi のコマンドやプログラムで、16進数を表記する場合は数字の前に「0x」を付ける。

表示位置をヘキサデシマルのアドレスで指定するというのが、EBCDIC(エビシディック)の汎用機で育った世代には何とも懐かしい。
 
表示結果。
液晶キャラクタデバイス
 
 
 
5. 気象情報取得回路図
 
 Raspberry Pi に用意されているGPIOに電子回路を接続すると、電子デバイスの制御ができる。
又、PythonにはI2Cデバイス制御用のライブラリが提供されているので、簡単にデバイスを操作することが出来る。
 

 I2C(Inter-Integrated Circuit)とは
 フィリップス社(現NXP社)が提唱する通信インターフェースで, クロックに同期させてデータの通信を行う同期式シリアル通信のひとつです。

 I2Cでは,クロック(SCL),データ入出力(SDA)の2本の信号線を用いて通信します。

 
I2Cは、各種デバイスを制御するマスター(Raspberry Pi)と、マスターからの命令によって制御されるスレーブ(I2Cデバイス)に分かれる。スレーブは、数珠つなぎに何台も接続可能。
I2Cは、各種デバイスを制御するマスター(Raspberry Pi)と、マスターからの命令によって制御されるスレーブ(I2Cデバイス)に分かれる
 
I2C デバイスには、出荷時に「 0x03 - 0x77 」の範囲でアドレスが割り当てられており、I2Cマスターはこのアドレスで、複数のスレーブの中から適切な対象を識別する。
 
Raspberry PiのGPIO端子と使用したピン。
Raspberry PiのGPIO端子と使用したピン
I2Cデバイスを Raspberry Pi に接続するには、GPIOと同じ端子を利用する。
データの送受信を行う「SDA」は端子番号3番、クロックの「SCL」は端子番号5番となっている。このI2Cのチャンネル番号(I2Cバス番号)は「1」。
 
 
気象情報取得回路図。
I2Cデバイス接続回路図
 
配線図。
キャラクタLCDへの表示 i2c回路図
 
 
I2Cで接続されているデバイスを確認するコマンド。
sudo i2cdetect -y 1
 ← バス番号は(0 か 1)で、エラーが出ない方を使う
 
I2C接続されているデバイスのアドレス。
(液晶キャラクタデバイスのACM1602NIを外して確認。)
I2C接続されているデバイスのアドレス
 
 
 
6. LCD表示 Python プログラム
 
照度は取得するも、LCDのスペースが無く表示せず。
 
Python PGM List。
#! /usr/bin/env /usr/bin/python
# -*- coding: utf-8 -*-

import datetime
import time
from Adafruit_ADS1x15 import ADS1x15 # ADS1015関連の関数等の読み込み
import smbus # I2C 通信には smbus ライブラリを使う
import mpl1152a2 # 圧力取得関数のインポート
from acm1602 import acm1602 # acm1602関連の関数等の読み込み

# アナログ変換セットアップ
ADS1015 = 0x00 # ADS1015を指定する値を定義
gain = 4096 # 3.3Vを4096に分割
sps = 250 # サンプリング数の設定
adc = ADS1x15( ic=ADS1015 ) # ADS1015から値を取得

# LCDセットアップ
# LCDの初期設定
lcd = acm1602( 1, 0x50, 4 ) # チャンネル番号、スレーブアドレス、GPIO番号
lcd.move_home() # カーソル位置を左上に移動
lcd.set_cursol( 0 ) # カーソルを非表示にする
lcd.set_blink( 0 ) # カーソルの点滅を止める

# ループ
SLEEPTIME = 300 # 60秒 x 5分
while True: # 条件式「True」は永続的に繰り返しを続ける

	# 日時取得
	d1 = datetime.datetime.today()
	d2 = datetime.datetime.strftime(d1,"%Y-%m-%d/%H:%M:%S")

	# 照度取得
	# チャンネル、ゲイン、サンプリング数を指定してアナログ入力の値を取得し
	# 1000で割っておおよその電圧に変換
	volts = adc.readADCSingleEnded( 0, gain, sps ) / 1000

	# 湿度・気温・気圧取得
	i2c_channel = 1 # I2Cのチャンネル(バス番号)を指定する
	i2c = smbus.SMBus( i2c_channel ) # コネクションオブジェクトを取得
	
	# スレーブアドレス「0x27」HIH-6130から4バイト分のデータを取得
	dac = i2c.read_i2c_block_data( 0x27, 0, 4 )
	#  1バイト目はdac[0]、2バイト目は dac[1] 、3バイト目はdac[2] 、4バイト目はdac[3]
	
	h = ( ( dac[0] & 0x3f ) << 8 ) | dac[1] # 湿度データのクレンジング
	humi = (float)(h) / 16383 * 100 # 湿度の計算
	t = ( dac[2] << 6 ) | (dac[3] >> 2) # 温度データのクレンジング
	temp = (float)(t) /16383 * 165 - 40 # 温度の計算
	
	# 圧力取得関数 mpl1152a2 を使って気圧を取得
	pres = mpl1152a2.getpressur( i2c_channel )

	d1 = datetime.datetime.today()
	d2 = datetime.datetime.strftime(d1,"%m%d")
	
	print d1
	print("Illuminance : " + str(volts) + " V" )
	print "Temperature : %.2f C" % temp
	print "Humidity    : %.2f %%" % humi
	print "Pressure    : %.2f hPa" % pres
	
	lcd.backlight(1) # LCDのバックライトを点灯する
	
	# LCDの表示位置を指定しデータを書き込む
	
	# 年月日
	lcd.move( 0x00, 0x00 )
	lcd.write( d2 )
	# 時分
	lcd.move( 0x05, 0x00 )
	lcd.write( time.strftime("%H%M") )
	# 温度
	lcd.move( 0x0a, 0x00 )
	lcd.write( "%.2fC" % temp )
	# 湿度
	lcd.move( 0x00, 0x01 )
	lcd.write( "%.2f%%" % humi)
	# 気圧
	lcd.move( 0x07, 0x01 )
	lcd.write("%.2fhP" % pres )

	time.sleep( SLEEPTIME ) # SLEEPTIME の値まで待機する
 
 
HIH-6130 デジタル湿度センサの出力内容(4バイト)とクレンジング
 
出力内容(4バイト)の詳細。

HIH-6130 デジタル湿度センサの出力内容(4バイト)とクレンジング
 
湿度データの1バイト目の前2ビットを取り除く
 
①.dac[0] & 0x3f:湿度データの1バイト目の前2ビット(Status分)が不要なので「00111111=3f」でANDして「00」にする。
②. ( dac[0] & 0x3f ) << 8 :1バイト目を8桁分左にシフトする(動かして空いた桁には「0」が入る)。
③.( ( dac[0] & 0x3f ) << 8 ) | dac[1] :シフトした1バイト目と2バイト目をORでつなぐ。
→ 取り出したデータは前2ビットが「00」なので「14ビットが値」。

湿度データの1バイト目の前2ビットを取り除く
 
 
温度データの4バイト目の後ろ2ビットを取り除く
 
④.(dac[3] >> 2:温度データの4バイト目を右に2桁分シフトする(動かして空いた桁には「0」が入る)。
②.dac[2] << 6 ) :3バイト目を左に6桁分シフトする(動かして空いた桁には「0」が入る)。
③.( dac[2] << 6 ) | (dac[3] >> 2):変換した3バイト目と4バイト目をORでつなぐ。
→ 取り出したデータは8ビットに6ビットが結合されたので「14ビットが値」。

温度データの4バイト目の後ろ2ビットを取り除く
 
 
print()関数での表示結果。
print()関数での表示結果
 
 
 
7. PythonからCSVファイルへの書き込み
 
液晶デバイスを見ていると、気象情報を時系列で保存し、変化をグラフで見たくなる。 そこで、取得したデータを「CSV」で保存し、このファイルをパソコンに取り込んで、 エクセルでグラフ表示にして見る。
 
手順。
①.PythonでCSVファイルを新規に作成する。
②.作成した csvファイル に時系列データを追記する。
③.パソコンにダウンロードしてエクセルでグラフにする。
 
 
①.気象データを保存する csvファイル を作る
 
 csvファイル を保存するディレクトリーを作る。
mkdir /home/pi/data
 
csvファイル を作るpythonプログラム。
sudo nano /home/pi/Python_PGM/makecsv_01.py
import csv

with open('data/weather-data_01.csv', 'w') as f:
    writer = csv.writer(f)
    writer.writerow(['日付','時刻','気温','湿度','気圧'])
    writer.writerow(['2023-02-15','09:07:38',18.54,53.46,1068.60])
 
open()の第一引数には、新たなファイルへのパスを指定する。
csvファイルの名前を「weather-data_01.csv」とした。
第二引数は「mode」で、書き込みモードを'w'とすると上書きとなり、元の内容は削除される。
 
writerow()メソッドで1行ずつ書き込む。引数はリスト。
 
 
②.作成した csvファイル に気象データを追記する
 
csvファイル に「30分」毎の時系列データを追記するpythonプログラム。
#! /usr/bin/env /usr/bin/python
# -*- coding: utf-8 -*-

import datetime
import time
import smbus
import mpl1152a2
from acm1602 import acm1602
import csv

# ループ
interval = 1800 # 60秒 x 30分
while True: # 条件式「True」は永続的に繰り返しを続ける

	i2c_channel = 1
	i2c = smbus.SMBus( i2c_channel )
	dac = i2c.read_i2c_block_data( 0x27, 0, 4 )
	h = ( ( dac[0] & 0x3f ) << 8 ) | dac[1]
	humi = (float)(h) / 16383 * 100
	t = ( dac[2] << 6 ) | (dac[3] >> 2)
	temp = (float)(t) /16383 * 165 - 40
	pres = mpl1152a2.getpressur( i2c_channel )
	
	d1 = datetime.datetime.today()
	date = d1.strftime('%Y-%m-%d') #日付の整形 yyyy-mm-dd
	jkok = d1.strftime('%H:%M') #時間の整形 hh:mm

	temp = "{:.2f}" . format(temp) #気温(小数点第2位まで)
	humi = "{:.2f}" . format(humi) #湿度(小数点第2位まで)
	pres = "{:.2f}" . format(pres) #湿度(小数点第2位まで)
	
	print date
	print jkok
	print temp
	print humi
	print pres
	
	# CSV書き出し
	with open('/home/pi/data/weather-data_01.csv','a') as f:
		writer = csv.writer(f)
		writer.writerow([date,jkok,temp,humi,pres])

	time.sleep(interval) # intervalの値まで待機する
 
既存のCSVファイルに追記したい場合は、 open()の追記モード‘a’ でファイルを開く。
書き込み自体は新規作成の場合と同じくwriterow()やwriterows()
末尾に追記される。
 
※:sleepという関数「time.sleep(interval)」を使用しているため、 「time」と言う名前の変数は使用できない。
 
csvファイルの内容を見てみる。
sudo nano /home/pi/data/weather-data_01.csv
 
カンマ区切りで、データが保存されている。
カンマ区切りで、データが保存されている
 
 
③.パソコンにダウンロードしてエクセルでグラフにする
 
 csvファイルを「FileZilla」を使って、パソコンにダウンロードする。
 
パソコン側でcsvファイルを開き、エクセルでグラフにする。
パソコン側でcsvファイルを開き、エクセルでグラフにする
 
 
参考:Raspberry Pi 気象情報をスマホにメールで送信する
 
参考:Raspberry Pi 監視カメラを構築し遠隔監視が出来るようにする
 

 

以上。
(2015.01.02)

 

 

スポンサー リンク

 

             

 

 

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください