前回の“Genuino101プログラム”に続き、今回は「Raspberry Piプログラム」の作成について紹介を致します。
sudo apt-get install libglib2.0-dev
(2) ライブラリをインストールします。Pythonのバージョンにより実行するコマンドが異なります。
sudo pip install bluepy
sudo pip3 install bluepy
以上でライブラリのインストールは終了です。
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# モジュールをインポート
import bluepy.btle as btle
import struct
import tkinter as Tk # Python3.4
import tkinter.messagebox as Msg # Python3.4
#import Tkinter as Tk # Python2.7
#import tkMessageBox as Msg # Python2.7
import sys
# Frameクラスを定義
class Frame(Tk.Frame):
def __init__(self, master=None):
Tk.Frame.__init__(self, master)
# Variableオブジェクトのインスタンスを生成
self.stat = Tk.StringVar()
self.sig = Tk.StringVar()
self.rly = Tk.StringVar()
self.eep = Tk.StringVar()
self.life = Tk.IntVar()
self.rmlife = Tk.StringVar()
# 変数の初期化
self.cnt = 10
self.pcdata = 0
self.prv_data = 0
self.rlydata = 0
self.eepdata = 0
self.lifedata = 100000
self.started = False
# Variableに値を設定
self.var_set()
# ウィンドウのタイトルを設定
self.master.title('Relay Control Demo')
# リレーの状態を表示するフレームを設定
f_display = Tk.Frame(self, relief=Tk.RIDGE, bd=4)
f_display.pack( padx=5, pady=5 )
# リレーの状態を表示するラベルを設定
self.fc_display = Tk.Label(f_display, textvariable=self.stat, width=15, relief=Tk.SUNKEN, bd=2, font=('Helvetica', '24'), bg='white')
self.fc_display.pack()
# リレーの入出力信号の状態を表示するフレームを設定
g_display = Tk.Frame(self, relief=Tk.RIDGE, bd=4)
g_display.pack( padx=5, pady=5 )
# リレーの入力信号の状態を表示するラベルを設定
self.g1_display = Tk.Label(g_display, textvariable=self.sig, width=30, relief=Tk.SUNKEN, bd=2, font=('Helvetica', '12'), bg='white')
self.g1_display.pack()
# リレーの出力信号の状態を表示するラベルを設定
self.g2_display = Tk.Label(g_display, textvariable=self.rly, width=30, relief=Tk.SUNKEN, bd=2, font=('Helvetica', '12'), bg='white')
self.g2_display.pack()
# リレーの寿命を表示するフレームを設定
h_display = Tk.Frame(self, relief=Tk.RIDGE, bd=4)
h_display.pack( padx=5, pady=5 )
# リレーの駆動回数を表示するラベルを設定
self.h1_display = Tk.Label(h_display, textvariable=self.eep, width=30, relief=Tk.SUNKEN, bd=2, font=('Helvetica', '12'), bg='white')
self.h1_display.grid(row=0,column=0, columnspan=2)
# リレーの寿命を表示するラベルを設定
self.h2_display = Tk.Label(h_display, text='Life:', width=15, relief=Tk.SUNKEN, bd=2, font=('Helvetica', '12'), bg='white')
self.h2_display.grid(row=1,column=0)
# リレーの寿命を入力するテキストボックスを設定
self.lifeentry = Tk.Entry(h_display, textvariable=self.life, width=14, justify=Tk.RIGHT, relief=Tk.SUNKEN, bd=2, font=('Helvetica', '12'), bg='white')
self.lifeentry.grid(row=1,column=1)
self.lifeentry.bind('', self.func)
# リレーの残り寿命を表示するラベルを設定
self.h3_display = Tk.Label(h_display, textvariable=self.rmlife, width=30, relief=Tk.SUNKEN, bd=2, font=('Helvetica', '12'), bg='white')
self.h3_display.grid(row=2,column=0, columnspan=2)
# ボタンを表示するフレームを設定
f_button = Tk.Frame(self)
f_button.pack(pady=2)
# スタートボタンを設定
self.b_start = Tk.Button(f_button, text='Start', command=self.start)
self.b_start.pack(side=Tk.LEFT, padx=1)
# ストップボタンを設定
self.b_stop = Tk.Button(f_button, text='Stop', command=self.stop, state=Tk.DISABLED)
self.b_stop.pack(side=Tk.LEFT, padx=1)
# self.measureを実行
self.measure()
# テキストボックスに入力された値を型変換して変数に代入
def func(self, ev):
self.lifedata = int(self.life.get())
# Genuino101からデータを取得してVariableに値を設定
def var_set(self):
# Genuino101からデータを取得
try:
self.pcdata = struct.unpack( 'B', PC.read() ) # 入力信号の状態
self.rlydata = struct.unpack( 'B', Relay.read() ) # 出力信号の状態
self.eepdata = struct.unpack( 'I', EEPROM.read() ) # 駆動回数
# エラー処理
except btle.BTLEException:
Msg.showerror(title = 'Error', message = 'BLE Device fail or not found')
root.destroy()
sys.exit()
# Variableに値を設定
self.stat.set('Relay Status:OFF') # リレーの状態
self.sig.set('Input Signal:%d' % (self.pcdata)) # 入力信号の状態
self.rly.set('Output Signal:%d' % (self.rlydata)) # 出力信号の状態
self.eep.set('Total Count:%d' % (self.eepdata)) # 駆動回数
self.life.set(self.lifedata) # 寿命回数
self.rmlife.set('Remain Life:%d' % (self.lifedata - int(self.eepdata[0]))) # 残り寿命回数
# Startボタンを押したとき
def start(self):
# Genuino101にデータを送信
try:
Switch.write(struct.pack('<b', 1))
# エラー処理
except btle.BTLEException:
Msg.showerror(title = 'Error', message = 'BLE Device fail or not found')
root.destroy()
sys.exit()
self.started = True
self.cnt = 10
# ボタンの状態を変更
self.b_start.configure(state=Tk.DISABLED)
self.b_stop.configure(state=Tk.NORMAL)
# self.countingを実行
self.counting()
# Stopボタンを押したとき
def stop(self):
# Genuino101にデータを送信
try:
Switch.write(struct.pack('<b', 0))
# エラー処理
except btle.BTLEException:
Msg.showerror(title = 'Error', message = 'BLE Device fail or not found')
root.destroy()
sys.exit()
self.started = False
# ボタンの状態を変更
self.b_start.configure(state=Tk.NORMAL)
self.b_stop.configure(state=Tk.DISABLED)
# Variableに値を設定
self.stat.set('Relay Status:OFF')
# Genuino101からデータを取得
def measure(self):
# Genuino101からデータを取得
try:
self.pcdata = struct.unpack( 'B', PC.read() )
self.rlydata = struct.unpack( 'B', Relay.read() )
self.eepdata = struct.unpack( 'I', EEPROM.read() )
# エラー処理
except btle.BTLEException:
Msg.showerror(title = 'Error', message = 'BLE Device fail or not found')
root.destroy()
sys.exit()
# 入力信号が変化したか判定
if self.prv_data != self.pcdata:
self.cnt = 5
self.prv_data = self.pcdata
# Variableに値を設定
self.sig.set('Input Signal:%d' % (self.pcdata))
self.rly.set('Output Signal:%d' % (self.rlydata))
self.eep.set('Total Count:%d' % (self.eepdata))
self.rmlife.set('Remain Life:%d' % (self.lifedata - int(self.eepdata[0])))
# 残り寿命の判定
if (self.lifedata - int(self.eepdata[0])) <
self.h3_display.configure(bg='red')
elif (self.lifedata - int(self.eepdata[0])) <
self.h3_display.configure(bg='yellow')
else:
self.h3_display.configure(bg='white')
# 100m秒後にself.measureを実行
self.after(100, self.measure)
# 入力信号が一定時間内に変化するか判定
def counting(self):
if self.started:
# 入力信号が変化しなかったとき
if self.cnt <=
self.stat.set('Relay Status:NG')
self.fc_display.configure(bg='red')
# 入力信号が変化したとき
else:
self.stat.set('Relay Status:OK')
self.fc_display.configure(bg='white')
self.cnt -=1
# 1秒後にself.countingを実行
self.after(1000, self.counting)
# メインウィンドウを生成
root = Tk.Tk()
# ウィンドウサイズを350×250ドットに指定
root.geometry("350x280")
# メインウィンドウのサイズ変更を禁止
root.resizable(0,0)
# Genuino101と接続
try:
Rly = btle.Peripheral(":4F:EE:0F:CC:7E")
# エラー処理
except btle.BTLEException:
Msg.showerror(title = 'Error', message = 'BLE Device fail or not found')
root.destroy()
sys.exit()
# キャラクタリスティックのリストを取得
chrts = Rly.getCharacteristics()
# UUIDに対応したキャラクタリスティックのインスタンスを生成
for chrt in chrts:
# リレー制御開始用キャラクタリスティック
if chrt.uuid == btle.UUID("19b10011-E8F2-537E-4F6C-D104768A1214"):
Switch = chrt
# リレー接点信号用キャラクタリスティック
elif chrt.uuid == btle.UUID("19B10012-E8F2-537E-4F6C-D104768A1214"):
PC = chrt
# リレー励磁信号用キャラクタリスティック
elif chrt.uuid == btle.UUID("19B10013-E8F2-537E-4F6C-D104768A1214"):
Relay = chrt
# リレー駆動回数用キャラクタリスティック
elif chrt.uuid == btle.UUID("19B10014-E8F2-537E-4F6C-D104768A1214"):
EEPROM = chrt
# Frameクラスのインスタンスを生成
f = Frame(master=root)
# Frameを配置
f.pack()
# mainloopを実行
root.mainloop()
それではこのプログラムを順番に説明します。
Copyright © 2025 TAHARA ELECTRIC CO., LTD. all right reserved