【ラズパイ】OLEDで情報ステーションを作成!グラフも表示

2024/07/19

OLED ラズパイ

  • B!
サムネ
サムネ

今回はOLEDディスプレイを2つ使って様々な情報を表示するディスプレイを作ります。

使用したOLEDは裏面の抵抗の位置を変えることで異なるI2Cアドレスに変更することができるため、デュアル画面で多くの情報が表示できるようになっています。

oled.py
  1. from busio import I2C
  2. from adafruit_ssd1306 import SSD1306_I2C
  3. import board
  4. import time
  5. from PIL import Image, ImageDraw, ImageFont
  6. import adafruit_ads1x15.ads1115 as ADS
  7. from adafruit_ads1x15.analog_in import AnalogIn
  8. import datetime
  9. import shutil
  10. import dht11
  11. import RPi.GPIO as GPIO
  12. import os
  13. import csv
  14.  
  15. GPIO.setmode(GPIO.BCM)
  16. instance = dht11.DHT11(pin=14)
  17.  
  18. i2c = I2C(board.SCL, board.SDA)
  19. ads = ADS.ADS1115(i2c)#addr=0x48
  20. cahnnel0 = AnalogIn(ads, ADS.P0)
  21.  
  22. display_1 = SSD1306_I2C(128, 64, I2C(board.SCL, board.SDA), addr=0x3c)#addr=0x3c
  23. display_2 = SSD1306_I2C(128, 64, I2C(board.SCL, board.SDA), addr=0x3d)#addr=0x3d
  24.  
  25. #初期化
  26. display_1.fill(0)
  27. display_2.fill(0)
  28. display_1.show()
  29. display_2.show()
  30.  
  31. image_1 = Image.new("1", (display_1.width, display_1.height))
  32. draw_1 = ImageDraw.Draw(image_1)
  33.  
  34. image_2 = Image.new("1", (display_2.width, display_2.height))
  35. draw_2 = ImageDraw.Draw(image_2)
  36.  
  37. font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 17)
  38. s_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 12)
  39. ms_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 10)
  40. m_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 8)
  41.  
  42. x = 0
  43. temp_list = []
  44. humi_list = []
  45. print('[Program Activation]')
  46.  
  47. try:
  48. while True:
  49. #記録ファイル(データを記録する場合のみ)
  50. dt_csv = datetime.date.today() #日付取得
  51. path = '/home/pi/Desktop/mnt/data/' + str(dt_csv) + '.csv'
  52. #今日のファイルがあるか
  53. is_file = os.path.isfile(path)
  54. if is_file:
  55. pass
  56. else:
  57. #無い場合は作成する
  58. with open(path, 'w') as f:
  59. fieldnames = ['DateTime', 'Temperature', 'Humidity', 'Cds', 'Moist', 'Moist_label', 'Watering']
  60. writer = csv.DictWriter(f, fieldnames=fieldnames )
  61. writer.writeheader()
  62. print('created', str(dt_csv) + '.csv')
  63. #明るさを取得(cds)
  64. cds_v = 0
  65. c_label = 'Display ON'
  66. #暗い時はディスプレイをOFFにする
  67. if (cahnnel0.voltage) > 2.9:
  68. cds_v = 1
  69. c_label = 'Display OFF'
  70. #CPU温度取得
  71. with open('/sys/class/thermal/thermal_zone0/temp') as t:
  72. temp = round(int(t.read()) / 1000, 1)
  73.  
  74. #日付を取得
  75. dt = datetime.datetime.now().strftime('%H:%M')
  76. dt_data = datetime.datetime.now().replace(microsecond=0)
  77. #DHT11から温湿度データを取得する
  78. while True:
  79. temphumi = instance.read()
  80. if temphumi.is_valid():
  81. t = temphumi.temperature
  82. h = temphumi.humidity
  83. break
  84. #Cdsデータ
  85. c0_vol = str(round(cahnnel0.voltage, 3))
  86. #共有ストレージの容量を取得
  87. result = shutil.disk_usage('/home/pi/Desktop/mnt/')
  88. total = str(round((result.total / 1024**4), 2)) + 'T'
  89. used = str(round((result.used / 1024**3), 2)) + 'G'
  90. free = str(round((result.free / 1024**4), 2)) + 'T'
  91. #Display_1(cds, 温度, 湿度)
  92. draw_1.rectangle((0,0,display_1.width,display_1.height), outline=0, fill=0)
  93. draw_1.text((3, 42), 'Cds[v]', font=ms_font, fill=1)
  94. draw_1.text((46, 42), 'TEMP', font=ms_font, fill=1)
  95. draw_1.text((87, 42), 'HUMI', font=ms_font, fill=1)
  96. draw_1.text((3, 52), c0_vol, font=ms_font, fill=1)
  97. draw_1.text((46, 52), str(t) + 'C', font=ms_font, fill=1)
  98. draw_1.text((87, 52), str(h) + '%', font=ms_font, fill=1)
  99. draw_1.text((2, 0), str(40), font=m_font, fill=1)
  100. draw_1.text((7, 30), str(0), font=m_font, fill=1)
  101. draw_1.text((116, 0), str(1), font=m_font, fill=1)
  102. draw_1.text((116, 30), str(0), font=m_font, fill=1)
  103. draw_1.text((6, 15), 'T', font=m_font, fill=1)
  104. draw_1.text((117, 15), 'H', font=m_font, fill=1)
  105.  
  106. #Display_2(更新時間, CPU温度, ストレージ状態)
  107. draw_2.rectangle((0,0,display_1.width,display_1.height), outline=0, fill=0)
  108. draw_2.text((0, 0), '[upd]' + str(dt), font=s_font, fill=1)
  109. draw_2.text((85, 0), '[CPU]', font=s_font, fill=1)
  110. draw_2.text((84, 18), str(temp) + 'C', font=s_font, fill=1)
  111. draw_2.text((0, 18), '[DISK]', font=s_font, fill=1)
  112. draw_2.text((3, 36), 'TOTAL', font=s_font, fill=1)
  113. draw_2.text((46, 36), 'USED', font=s_font, fill=1)
  114. draw_2.text((87, 36), 'FREE', font=s_font, fill=1)
  115. draw_2.text((3, 48), total, font=s_font, fill=1)
  116. draw_2.text((46, 48), used, font=s_font, fill=1)
  117. draw_2.text((87, 48), free, font=s_font, fill=1)
  118.  
  119. #書き込み
  120. display_1.image(image_1)
  121. display_2.image(image_2)
  122.  
  123. #グラフの線
  124. display_1.line(14,0,14,40,1)
  125. display_1.line(114,0,114,40,1)
  126. display_1.line(0,40,128,40,1)
  127. #データセット
  128. T = int(t)
  129. H = int(h)
  130. temp_list.append(T)
  131. humi_list.append(H)
  132. x = len(temp_list)
  133. #リストの中身が100個になったら古い値を消す
  134. if x == 100:
  135. temp_list.pop(0)
  136. humi_list.pop(0)
  137. #温度グラフ表示(実線)
  138. x = 0
  139. for i in temp_list:
  140. x += 1
  141. display_1.circle(14+x,40-i,1,1)
  142. #湿度グラフ表示(点線)
  143. p = 1
  144. x = 0
  145. for i in humi_list:
  146. x += 1
  147. #交互に処理することで点線にする
  148. if p == 1:
  149. display_1.circle(14+x,int(40-(40*(i/100))),1,1)
  150. p = 0
  151. else:
  152. display_1.circle(14+x,int(40-(40*(i/100))),0,0)
  153. p = 1
  154.  
  155. print(str(T)+'C',str(H)+'%', c0_vol, c_label)
  156. #ディスプレイに表示
  157. if cds_v == 0:
  158. display_1.show()
  159. display_2.show()
  160. else:
  161. display_1.fill(0)
  162. display_2.fill(0)
  163. display_1.show()
  164. display_2.show()
  165. #####その他のデータを追加する場合#####
  166. moist = 'NULL'
  167. moist_label = 'NULL'
  168. watering = 'NULL'
  169. data = [[dt_data, t, h, c0_vol, moist, moist_label, watering]]
  170. with open(path, 'a') as f:
  171. writer = csv.writer(f)
  172. writer.writerows(data)
  173. latest = '/home/pi/Desktop/mnt/latestdata/latest.csv'
  174. with open(latest, 'w', newline='') as f:
  175. fieldnames = ['DateTime', 'Temperature', 'Humidity', 'Cds', 'Moist', 'Moist_label', 'Watering']
  176. writer = csv.DictWriter(f, fieldnames=fieldnames )
  177. writer.writeheader()
  178. writer = csv.writer(f)
  179. writer.writerows(data)
  180. ######################################
  181. time.sleep(60)
  182.  
  183. except KeyboardInterrupt:
  184. draw_1.rectangle((0,0,display_1.width,display_1.height), outline=0, fill=0)
  185. draw_2.rectangle((0,0,display_1.width,display_1.height), outline=0, fill=0)
  186. display_1.image(image_1)
  187. display_2.image(image_2)
  188. display_1.show()
  189. display_2.show()
  190. GPIO.cleanup()
  191. print('Cleanup')

Writer

アイコン
Python×Raspi IoTシステム・Bot・ラズパイの記録
  • プログラミング
  • IoT
  • Python
\FOLLOW ME/ 𝕏

Ranking

blogmura_pvcount

Community

Search