
今回はOLEDディスプレイを2つ使って様々な情報を表示するディスプレイを作ります。
使用したOLEDは裏面の抵抗の位置を変えることで異なるI2Cアドレスに変更することができるため、デュアル画面で多くの情報が表示できるようになっています。
oled.py
from busio import I2C
from adafruit_ssd1306 import SSD1306_I2C
import board
import time
from PIL import Image, ImageDraw, ImageFont
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
import datetime
import shutil
import dht11
import RPi.GPIO as GPIO
import os
import csv
GPIO.setmode(GPIO.BCM)
instance = dht11.DHT11(pin=14)
i2c = I2C(board.SCL, board.SDA)
ads = ADS.ADS1115(i2c)#addr=0x48
cahnnel0 = AnalogIn(ads, ADS.P0)
display_1 = SSD1306_I2C(128, 64, I2C(board.SCL, board.SDA), addr=0x3c)#addr=0x3c
display_2 = SSD1306_I2C(128, 64, I2C(board.SCL, board.SDA), addr=0x3d)#addr=0x3d
#初期化
display_1.fill(0)
display_2.fill(0)
display_1.show()
display_2.show()
image_1 = Image.new("1", (display_1.width, display_1.height))
draw_1 = ImageDraw.Draw(image_1)
image_2 = Image.new("1", (display_2.width, display_2.height))
draw_2 = ImageDraw.Draw(image_2)
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 17)
s_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 12)
ms_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 10)
m_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 8)
x = 0
temp_list = []
humi_list = []
print('[Program Activation]')
try:
while True:
#記録ファイル(データを記録する場合のみ)
dt_csv = datetime.date.today() #日付取得
path = '/home/pi/Desktop/mnt/data/' + str(dt_csv) + '.csv'
#今日のファイルがあるか
is_file = os.path.isfile(path)
if is_file:
pass
else:
#無い場合は作成する
with open(path, 'w') as f:
fieldnames = ['DateTime', 'Temperature', 'Humidity', 'Cds', 'Moist', 'Moist_label', 'Watering']
writer = csv.DictWriter(f, fieldnames=fieldnames )
writer.writeheader()
print('created', str(dt_csv) + '.csv')
#明るさを取得(cds)
cds_v = 0
c_label = 'Display ON'
#暗い時はディスプレイをOFFにする
if (cahnnel0.voltage) > 2.9:
cds_v = 1
c_label = 'Display OFF'
#CPU温度取得
with open('/sys/class/thermal/thermal_zone0/temp') as t:
temp = round(int(t.read()) / 1000, 1)
#日付を取得
dt = datetime.datetime.now().strftime('%H:%M')
dt_data = datetime.datetime.now().replace(microsecond=0)
#DHT11から温湿度データを取得する
while True:
temphumi = instance.read()
if temphumi.is_valid():
t = temphumi.temperature
h = temphumi.humidity
break
#Cdsデータ
c0_vol = str(round(cahnnel0.voltage, 3))
#共有ストレージの容量を取得
result = shutil.disk_usage('/home/pi/Desktop/mnt/')
total = str(round((result.total / 1024**4), 2)) + 'T'
used = str(round((result.used / 1024**3), 2)) + 'G'
free = str(round((result.free / 1024**4), 2)) + 'T'
#Display_1(cds, 温度, 湿度)
draw_1.rectangle((0,0,display_1.width,display_1.height), outline=0, fill=0)
draw_1.text((3, 42), 'Cds[v]', font=ms_font, fill=1)
draw_1.text((46, 42), 'TEMP', font=ms_font, fill=1)
draw_1.text((87, 42), 'HUMI', font=ms_font, fill=1)
draw_1.text((3, 52), c0_vol, font=ms_font, fill=1)
draw_1.text((46, 52), str(t) + 'C', font=ms_font, fill=1)
draw_1.text((87, 52), str(h) + '%', font=ms_font, fill=1)
draw_1.text((2, 0), str(40), font=m_font, fill=1)
draw_1.text((7, 30), str(0), font=m_font, fill=1)
draw_1.text((116, 0), str(1), font=m_font, fill=1)
draw_1.text((116, 30), str(0), font=m_font, fill=1)
draw_1.text((6, 15), 'T', font=m_font, fill=1)
draw_1.text((117, 15), 'H', font=m_font, fill=1)
#Display_2(更新時間, CPU温度, ストレージ状態)
draw_2.rectangle((0,0,display_1.width,display_1.height), outline=0, fill=0)
draw_2.text((0, 0), '[upd]' + str(dt), font=s_font, fill=1)
draw_2.text((85, 0), '[CPU]', font=s_font, fill=1)
draw_2.text((84, 18), str(temp) + 'C', font=s_font, fill=1)
draw_2.text((0, 18), '[DISK]', font=s_font, fill=1)
draw_2.text((3, 36), 'TOTAL', font=s_font, fill=1)
draw_2.text((46, 36), 'USED', font=s_font, fill=1)
draw_2.text((87, 36), 'FREE', font=s_font, fill=1)
draw_2.text((3, 48), total, font=s_font, fill=1)
draw_2.text((46, 48), used, font=s_font, fill=1)
draw_2.text((87, 48), free, font=s_font, fill=1)
#書き込み
display_1.image(image_1)
display_2.image(image_2)
#グラフの線
display_1.line(14,0,14,40,1)
display_1.line(114,0,114,40,1)
display_1.line(0,40,128,40,1)
#データセット
T = int(t)
H = int(h)
temp_list.append(T)
humi_list.append(H)
x = len(temp_list)
#リストの中身が100個になったら古い値を消す
if x == 100:
temp_list.pop(0)
humi_list.pop(0)
#温度グラフ表示(実線)
x = 0
for i in temp_list:
x += 1
display_1.circle(14+x,40-i,1,1)
#湿度グラフ表示(点線)
p = 1
x = 0
for i in humi_list:
x += 1
#交互に処理することで点線にする
if p == 1:
display_1.circle(14+x,int(40-(40*(i/100))),1,1)
p = 0
else:
display_1.circle(14+x,int(40-(40*(i/100))),0,0)
p = 1
print(str(T)+'C',str(H)+'%', c0_vol, c_label)
#ディスプレイに表示
if cds_v == 0:
display_1.show()
display_2.show()
else:
display_1.fill(0)
display_2.fill(0)
display_1.show()
display_2.show()
#####その他のデータを追加する場合#####
moist = 'NULL'
moist_label = 'NULL'
watering = 'NULL'
data = [[dt_data, t, h, c0_vol, moist, moist_label, watering]]
with open(path, 'a') as f:
writer = csv.writer(f)
writer.writerows(data)
latest = '/home/pi/Desktop/mnt/latestdata/latest.csv'
with open(latest, 'w', newline='') as f:
fieldnames = ['DateTime', 'Temperature', 'Humidity', 'Cds', 'Moist', 'Moist_label', 'Watering']
writer = csv.DictWriter(f, fieldnames=fieldnames )
writer.writeheader()
writer = csv.writer(f)
writer.writerows(data)
######################################
time.sleep(60)
except KeyboardInterrupt:
draw_1.rectangle((0,0,display_1.width,display_1.height), outline=0, fill=0)
draw_2.rectangle((0,0,display_1.width,display_1.height), outline=0, fill=0)
display_1.image(image_1)
display_2.image(image_2)
display_1.show()
display_2.show()
GPIO.cleanup()
print('Cleanup')

0 件のコメント:
コメントを投稿