PLCとマイコンの接続で躓いたこと

# はじめに

こんにちは、株式会社COSMでインターンをしている東京大学工学部4年の前澤です。

今回、製造業のDXを推進するCOSM IoT Gateの開発にあたり、PLC（キーエンス製KV-8000シリーズ）とマイコン（ラズベリーパイを使用）を接続し、センサデータを取得しました。その方法、および苦戦したことの解説をします。

## COSM IoT Gateについて

工場内の機械についている、センサを通してあらゆるデータを取得し、その情報をオンラインで一元管理を可能にし、DXを推進するプラットフォームです。

具体的には、センサ情報をリアルタイムで監視し、さらにそれらを時系列データとしてクラウド上で保存、機械学習での分析を行うことで、故障や部品の交換タイミングの予測を行います。

[COSM IoT Gate](https://gate.cosmcorp.jp/)

## 背景

上記で解説したCOSM IoT Gateの最も予想されるユースケースは、工場内のマシンの情報を取得し、管理するというものです。

ここで重要になるのが、PLCからのリアルタイムでの情報の取得です。

製造業向けの展示会である、インターネプコンジャパン2023においてCOSM IoT Gateの展示用モックの作成を行いました。

このモックでは、PLCに取り付けたファイバセンサから水槽内の水位を取得し、ダッシュボード上でリアルタイムにそれを表示するもので、特にPLCとマイコンの接続に時間がかかりました。

## PLCとは

> 「PLC（Programmable Logic Controller）とは、工場や設備の自動制御に使用される制御装置（コントローラ）であり、多種多様な機器の制御を可能にします。PLCはシーケンス制御を基に機器の順序動作を記憶し、それに従って機器を稼働させるため、従来のリレー回路よりも複雑な制御が容易になります。
> 
> 
> PLCは、工業用機械、エレベーター、自動車、信号機、家電製品など幅広い分野で活用されています。例えば、エレベーターの扉の開閉や移動を制御する際にPLCが使われることがあります。」
> 

参考（以下記事をChatGPTで要約しました。）：[「PLCとは？仕組み・導入メリット・主な種類をまとめて解説」コラム｜三菱電機ITソリューションズ](https://www.mdsol.co.jp/column/column_120_2039.html)


# 概要
## 主な仕様

今回作成したものの概略図は以下です。
![](https://storage.googleapis.com/zenn-user-upload/7e69b77683eb-20240524.png)

PLCとラズパイの接続には、LANケーブルを仕様して、上位リンクを用いた通信を試みました。

そこで、以下のPythonのコードを使用しました。その際、こちらの[コード](https://qiita.com/y_kmori/items/e38e0aaf29571e199292)を参照しました。

```python
import socket
import time

host_ip = '192.168.1.3'
host_port = 8501

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:
    client.connect((host_ip, host_port))
except:
    print("PLC connection NG")
    client.close()
    exit()

comand = "RDS R313 3\r"
previous_water_level = 1

try:
    while True:
        client.send(comand.encode("ascii"))
        response = client.recv(64)
        response = response.decode("UTF-8")

        HH = response[0] == '1'
        H = response[2] == '1'
        L = response[4] == '1'
        
        if L and H and HH:
            waterLevel = 4
        elif L and H:
            waterLevel = 3
        elif L:
            waterLevel = 2
        else:
            waterLevel = 1

        if waterLevel != previous_water_level:
            message = str(waterLevel)
            previous_water_level = waterLevel
            print("water level:", message)

        time.sleep(0.2)

except KeyboardInterrupt:
    print("\nfinish program")
finally:
    client.close()
```

LANケーブルを接続し、ラズベリーパイ上でこのコードを実行すると、0.2秒ごとにR313、R314、R315[^1]の情報（水を検出していたら1、検出していなかったら0）を取得し、それに応じて水位を決定するというプログラムを簡単に作成しました。
[^1]:※ここで、R313、R314、R315はラダープログラムを使用して設定した、三つのファイバセンサのデータです。

しかし、、、

実際に接続して、ラズパイ上でこのプログラムを実行しても、うまくいかず、そもそも接続自体が成立していないという状況に陥りました。

## 原因

単刀直入に言うと、原因はラズパイのIP設定にありました。

LANケーブルとWi-FiのIP設定は別々で、ラズパイのLANポートのIPが接続のたびに変わり、PLCとラズパイのIPアドレスのネットワーク部が一致していなかったために接続が成立していませんでした。

## 解決方法

PLCのIPアドレスを192.168.1.3に設定し、ラズパイ側のIPアドレスを192.168.1.2に固定することで、IPアドレスのネットワーク部（192.168.1）を一致させました。

いろいろ試しましたが、PLC側のその他の設定はデフォルトで良かったです。

# 終わりに

現代は、クラウドやあらゆる無線通信が発達しており、これまで有線での情報の通信をする機会が開発の中であまりなかったので、初歩的なところで躓きました。

今回のような、有線での情報の通信などは古い技術ではないのですが、開発していく中ではいわんやクラウドインフラであったり、新しい技術を触れる機会が圧倒的に多く、自分自身に知見として蓄積されていくのはそういった先端的な技術に対する経験である、という実感があります。

しかしながら、実際に業務で開発していくにあたって製造業などはやはりレガシーなシステム、昔ながらの技術を使用されている箇所が多分にあります。そのため我々は製造業向けのプロダクトを作る身として例えばネットワーク技術であればクラウドだけでなく、もっと包括的にネットワーク技術に対する知識を得る必要があると痛感しました。