光センサを使用して、設備機器の赤ランプが点灯したら、担当者へ通知する実験
概要
設備機器に装備されている信号灯や警告灯の赤ランプ(やその他の色のランプ)が点灯したら、それを光センサで検出して、メール送信やSNS(Slack)投稿により、メッセージや写真を担当者へ通知する実験を行いました。これにより、IoT未対応の設備がIoT化でき、担当者の負担軽減が期待できます。
実験したシステムの構成
以下に、送信されたメールの例を示します(ほぼモザイクとなっています(汗)。
送信されたメールの例
これは、ある大型の加工設備にて、加工中の異常停止により赤ランプが点灯したときに送信されたメールです。この加工設備には進捗などを示す状態表示器がありましたので、その写真をメールに添付しています。
この加工設備は、IoT機能やネットワーク機能がありませんが、本実験のシステムを後付けしてIoT化することで、担当者への通知機能が付加できました。
このようなシステムでは、たとえば以下のようなメリットが考えられます。
- 設備機器の改造が不要(光センサを貼り付けるだけなので)
- IoT機能やネットワーク機能がなくても使用可能(マイコンが担当するので)
- 単なる光センサなので、パイロットランプやインジケータ等でも使用可能(明暗の差が検出できれば、どこでも)
- ランプ点灯だけでなく、別のトリガでメール送信等が可能(例えば、温度センサを取り付け、筐体温度が上限値を超えた時、など)
- データベースなどを併用することで、過去の履歴等も閲覧可能(過去の何時何分にどのような通知をしたか、など)
なお、本実験は、令和3年度(2021年度)に行ったもので、メール送信やSlack投稿も当時の方法となります。インターネット上のサービスは、セキュリティ等の理由で頻繁に仕様変更が行われますので、ここに記載した方法では既に実行できない可能性もあります。ご了承ください。
使用したもの
機器
項目 | 内容 | 型番等 |
---|---|---|
マイコン | ラズベリーパイ | RaspberryPi 3B+ |
光センサ | CdSセンサ | (不明) |
A/Dコンバータ | 10bit、2ch、SPI接続 | Microchip MCP3002 |
カメラ | USB接続のWebカメラ | Logicool C615n |
サービス
分類 | サービス | 運営会社 |
---|---|---|
メール | Gmail | Google社 |
SNS | Slack | Slack Technologies社 |
実際の機材
ラズベリーパイと光センサ
今回の実験は、2つの現場で行っています。1番目に行った実験機材の写真を以下に示します。ラズベリーパイは、専用ケース(写真の赤いもの)に入れ、ケース底面にブレッドボードを貼り付けました(つまり、写真の状態でラズベリーパイは逆さまになっています)。
そして、ブレッドボード上に光センサの回路を構成しました。使用した光センサは、CdSセルと呼ばれるもので、明るさに反比例して抵抗値が増減するものです。
ラズベリーパイとブレッドボード (大きい写真)
光センサ
明るさ調整ボリュームとオン検出確認LED
現場毎に赤ランプの明るさや周囲の明るさが異なります。これを考慮して、明るさ調整用のボリュームを付けました。ボリュームの抵抗値をしきい値として、光センサの抵抗値がしきい値を下回った(あるいは上回った)ときに、オンを検出するようにしました。これにより、現場毎の環境の違いに対応できます。
実際の調整は、現場の赤ランプに光センサを貼り付けたあと、赤ランプを強制点灯させ、ボリュームを上下させて調整します。調整時のオン検出が分かるようにボリュームの横にLEDを配置しました(下の写真の緑LED)。具体的には、次のように調整します。
- 赤ランプを強制点灯
- ボリュームを上下させ、確認LEDが点灯する位置で固定
- 赤ランプを消灯し、確認LEDも消灯することを確認
明るさ調整ボリュームとオン検出確認LED
実験
取り付け
1番目の実験にて、実際に加工設備に取り付けた様子を以下に示します。ラズベリーパイは、赤ランプのすぐ近くに設置しました。ネットワーク接続は、有線LANを使用しました。また、光センサの取り付けは、透明な粘着テープで貼り付けました。
設置(左上:赤ランプ、右下:ラズベリーパイ)
光センサを赤ランプへ取り付け(透明な粘着テープで貼り付け)
プログラム概要
プログラムは、Python3で作成しました。使用した主なモジュールは以下の通りです。
種別 | モジュール |
---|---|
GPIO入出力 | RPi.GPIO |
Slack投稿 | requests、json等 |
メール送信 | smtplib、email.mime(MIMEMultipart、MIMEText、MIMEApplication)等 |
プログラムの大まかな流れは、次のとおりです。
- 異常検出(赤ランプ点灯)待ち
- 異常検出(赤ランプ点灯)したら、写真撮影
- さらに、Slackへ投稿、あるいは、メール送信
異常検出(赤ランプ点灯)待ち
赤ランプが点灯したかどうかは、上記「明るさ調整ボリュームとオン検出確認LED」にも書いたとおり、ボリュームの抵抗値をしきい値として、光センサの抵抗値がしきい値を下回った(あるいは上回った)かどうかを定期的に見るようにしています。
今回使用したラズベリーパイは、アナログ値の入力ができませんので、抵抗値(抵抗の電圧値)は、外付けのA/Dコンバータにより入力しました。
なお、異常検出してメール送信等を行った後は、異常が解消されるまで(赤ランプが消灯するまで)、異常が継続中とみなし、メール送信等を行いません。つまり、異常検出~異常解消の間に最初の1回だけメール送信等が行われます。
点滅への対応
2番目の実験では、異常停止時の赤ランプは点灯ではなく、点滅でした。約0.5秒間隔で、点灯と消灯を繰り返します。人間が見れば、点滅で異常を知らせている、と簡単に認識できますが、プログラムでこれを検出するには、工夫する必要があります。
なぜなら、従来の方式の「赤ランプ点灯で異常検出」で判定すると、以下のようにメール送信が繰り返される事態となります。
- 最初の点灯:異常検出なのでメール送信
- 0.5秒後に消灯:異常解消
- 0.5秒後に点灯:異常検出なのでメール送信
- 0.5秒後に消灯:異常解消
- …
一度異常検出したら、それ以降、異常検出をロックする、などの機能で対処できますが、折角なので、プログラムによる点滅の検出に挑戦してみました。
結論のみ書くと、今回は、点灯と消灯の累積時間を一定時間計測して、その割合から点滅判定する方式としました。たとえば、0.5秒間隔で点滅する赤ランプにて、3秒~5秒間計測し、点灯の割合が50%程度になっていれば異常検出と判定するプログラムとしました。(誤差もあるため30%~70%等かなり広く許容範囲をとりました。)
この方式は、
赤ランプ点灯 → 即、異常検出
とはならず、
赤ランプ点灯 → 3秒~5秒計測 → 異常検出
と少し遅れが生じます。計測時間を長くすれば精度は高まりますが、異常検出の遅れとのトレードオフとなりますので、今回は計測時間を3秒~5秒程度としました。
写真撮影
写真撮影は、当初OpenCVを使用し、Pythonプログラムで行いましたが、カメラとの相性なのか(別のカメラでは問題なかった)、画像の乱れが発生したので、外部の写真撮影コマンドを使用しました。外部コマンドで撮影した写真は、特定のディレクトリに保存させ、それをPythonプログラム側でファイルとして受け取る方法としました。使用した写真撮影コマンドは「fswebcam」です。
「怪我の功名」でしょうか。外部コマンドによるファイルの受け渡し方式にしたことで、実行する外部コマンドを変更するだけで、写真撮影以外にも使用できました。たとえば、スクリーンキャプチャした画像を使用するなどです。極端な話、画像でなくても、表計算ファイルやプレゼンテーションファイルなどを使用することも可能です。
Slack投稿
1番目の実験でSlack投稿を試しました。
事前にSlack側で、アプリケーションを登録し、トークンと投稿先のチャンネルIDを取得しておきます。
そして、以下のような関数により、メッセージを投稿しました。引数mess
が送信するメッセージです。
def slack_post_mess(mess):
global token_full, chan_id, slack_url
headers = {'Authorization': token_full}
param = {
'channel': chan_id,
'text': mess,
}
#送信
res = requests.post(url=slack_url, params=param, headers=headers)
#結果
res_d = json.loads(res.text)
return res_d['ok']
また、以下の関数により、写真の投稿を行いました。引数のimg_file
が画像ファイルのパスです。
def slack_post_img(img_file, header_mess=''):
global token_full, chan_id, slack_url
files = {'file': open(img_file, 'rb')}
headers = {'Authorization': token_full}
param = {
'channels': chan_id, #チャンネルID(必須)
#'filename': 'new-filename', #アップロード後のファイル名
#'title': '画像のタイトル', #画像の上に表示されるタイトル
#'initial_comment': '投稿者', #投稿者部分に表示される
}
if header_mess: param['initial_comment'] = header_mess
#送信
res = requests.post(url=slack_url, params=param, files=files, headers=headers)
#結果
res_d = json.loads(res.text)
return res_d['ok']
なお、実験した装置の担当者から、「異常が発生していなくても、任意のタイミングで写真が欲しい」との要望があり、Slackのボットも作成しました。担当者がSlackに'photo'と投稿すると、その時点で写真撮影し投稿する単純なボットです。構築方法等は省略します。
任意のタイミングで写真を上げるボット
メール送信
2番目の実験でメール送信を行いました。
メールサービスは、GoogleのGmailを使用しました。事前にアプリパスワードの取得等を行っておく必要があります。
メール送信は、以下のような関数により行いました。関数の引数は、img_file
が画像ファイルのパス、img_title
が画像ファイルの題名です。これにより、記事冒頭で示したメール例が送信されます。
def send_mail(img_file, img_title=''):
if not conf_data['header']['to']:
return False
msg = MIMEMultipart()
msg["Subject"] = conf_data['header']['sub']
msg["From"] = conf_data['header']['from']
msg["To"] = conf_data['header']['to']
msg.attach(MIMEText(conf_data['header']['body'], "plain", "utf-8"))
if os.path.isfile(img_file):
#添付ファイル
with open(img_file, "rb") as f:
mb = MIMEApplication(f.read())
if not img_title: img_title = os.path.basename(img_file)
mb.add_header("Content-Disposition", "attachment", filename=img_title)
msg.attach(mb)
try:
#メール送信
sendToList = conf_data['header']['to'].split(',')
s = smtplib.SMTP(conf_data['server']['addr'], conf_data['server']['port'])
s.starttls()
s.login(conf_data['server']['user'], conf_data['server']['pass'])
s.sendmail(conf_data['header']['from'], sendToList, msg.as_string())
s.quit()
except Exception as e:
return False
return True
メール送信に関する情報は、ほぼ固定されていますので、変数conf_data
に様々なデータを集約しています(実際には、設定ファイルから読み込んでいます)。メール送信で使用してるメンバを以下に示します。
1次元目 | 2次元目 | 意味 |
---|---|---|
header | to | 送信先メールアドレス |
sub | 送信メールの題名 | |
from | 送信元メールアドレス | |
body | メール本文 | |
server | addr | メールサーバのアドレス |
port | メールサーバのポート番号 | |
user | メールサーバのユーザ名 | |
pass | メールサーバのパスワード |
設定等
今回の実験ではラズベリーパイを使用したため、モニタやキーボードは接続せず、設定等のUIをWebとしました。ラズベリーパイ上でWebサーバを動かし、PHPにて以下の機能を実装しました。
- カメラの画角調整(一定間隔(1秒間隔)で現在のカメラ画像を表示、これを見ながら画角調整)
- 送信先メールアドレス等の設定(メール送信時のみ)
- 過去送信したカメラ画像の閲覧
- ラズベリーパイのシャットダウン
- など
Web UI(カメラの画角調整)
Web UI(送信先メールアドレス)
Web UI(過去送信したカメラ画像)
その他のデータ
2番目の実験では、温湿度センサと電流センサ2個にて、常時データ取得を行いました。電流センサは設備機器のモータの配線に接続し、稼働状況を見るために使用しました。
これらのデータは、ラズベリーパイ上で InfluxDB、Grafana、telegraf 等を動作させ、グラフで確認できるようにしました。
その他のデータのグラフ表示(Grafana)
参考:
IoT実験:ラズパイで温度取得しグラフ表示 (1)ラズパイで温度取得
IoT実験:ラズパイで温度取得しグラフ表示 (2)サーバでデータベース
IoT実験:ラズパイで温度取得しグラフ表示 (3)ラズパイでデータ送信、サーバで可視化
まとめ
今回は、設備機器の信号灯の赤ランプが点灯したタイミングで、何らかのアクション(メール送信やSNS投稿で担当作業者へ通知)を行う実験をしました。
元々IoT機能が装備されていない設備機器において、後付けでIoT機能を付加することができ、ほんの少しですが、作業者の負担軽減が図れました。
Discussion
コメント失礼します、
配線の写真をもっと見やすい状態で投稿して欲しいのですが、お願い出来ますでしょうか。
返信が遅くなり申し訳ありません。
記事中の「ラズベリーパイとブレッドボード」の写真部分に、大きい写真へのリンクを付けました。
もし、他の写真等をご希望の場合、直接やり取りさせて頂きたいので、
お問い合わせフォームからご連絡ください。
お問い合わせフォーム https://dsl.gunma.jp/contact/
写真ありがとうございます。
ちなみになのですが、通知だけのシステムでteamsにメールが来るシステムの作り方などわかったりしますでしょうか、