미쓰비시 PLC 통신을 위해 Python 프로그램으로 제작되었으며, PLC에서 데이터를 읽어와 파일에 저장하고 로그인을 관리하는 역할을 수행합니다. 주요 pymcprotocol기능을 사용하여 PLC와 통신을 구현하고 있으며, 이 프로그램의 주요 기능은 다음과 같습니다.
주요 기능 문장:
- 출력 및 파일 생성 :
- makedir(directory)함수는 외부에서 생성됩니다.
- makefile(file, sHead)함수는 파일이 작성되는 경우 헤더 정보를 추가합니다.
- 서버 메시지 출력 :
- displaymsg(msg, imode)함수는 로그인 메시지를 콘솔에 출력하고 파일을 기록할 수 있습니다. imode값이 1이면 파일을 기록하는 데 사용됩니다.
- PLC연결 :
- PLCCon(sIP, iport)PLC와 연결을 시도합니다. 연결에 실패하면 업무 시간을 응답하고 재시도합니다. 연결이 성공하면 PLC 연결 OK메시지를 출력합니다.
- 파일 및 데이터 이동 :
- 프로그램 실행 시점의 날짜 정보를 바탕으로, 데이터 저장과 파일을 생성합니다.
- PLC 헤더 및 초기 값 plcadrm.txt파일에서 시작되는 데이터입니다. 이 파일은 데이터에 대한 정보를 포함하는 것으로 보입니다.
- PLC와의 메인 루프 :
- PLC와 연결 후 루프로 데이터를 처리하고 메인 루프를 실행합니다. 이 루프에서는 다음과 같은 작업을 수행합니다:
- PLC에서 D11490위치부터 33개의 명령 데이터를 읽었습니다.
- 읽은 데이터를 파일로 기록하고 로그를 남깁니다.
- 특정 데이터에 따라 조건을 추가로 처리하여 생성합니다.
- 주소로 D11579주소 1를 써서 PLC에 신호를 보냅니다.
- PLC와 연결 후 루프로 데이터를 처리하고 메인 루프를 실행합니다. 이 루프에서는 다음과 같은 작업을 수행합니다:
코드 흐름 분석:
- 생성 :
- 출력 및 파일을 준비하고 파일인을 설정 plcadrm.txt하고 PLC 데이터의 헤더와 값을 설정합니다.
- PLC에 연결을 시도하여 성공하면 메인 루프로 존재합니다.
- 메인 루프 :
- 메인 루프에서는 PLC에서 데이터를 입력하고, 로그인 파일과 CSV 파일로 저장합니다.
- 데이터를 기반으로 하는 D11579작업을 수행합니다.
- 데이터 읽기에 실패할 경우 재연결을 시도하며 일정 시간이 파일과 작성을 생성합니다.
주요 변수 및 의미:
- sIP, iport : PLC의 IP 주소와 포트 번호입니다. 이 정보를 바탕으로 PLC에 연결을 시도합니다.
- w_values : PLC에서 가져온 데이터의 목록입니다.
- sHead, sValue : plcadrm.txt파일에서 태그온 헤더 정보와 초기 값입니다. 데이터 구조를 정의하는 역할을 합니다.
- iErr : PLC 통신을 하면 카운트됩니다. 180번 이상 발생하면 재연결을 시도합니다.
- pymc3e : pymcprotocol.Type3E클래스의 참여로, PLC 통신을 담당합니다.
이 프로그램은 주로 제조 환경에서 PLC 데이터를 로드하고 CSV 파일로 기록하고 장비의 상태를 모니터링하기 위해 사용됩니다.
현재 LG전자 협력사에 적용중인 프로그램으로 초기 버젼입니다. 참조하여 미쓰비시 PLC I/F에 충분히 활용 가능합니다.
C#으로 변환한 소스입니다.
using System;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Collections.Generic;
using McProtocolLib; // Add MC Protocol library
class MitsubishiPLCInterface
{
static void Main(string[] args)
{
string directory = $"c:/tong/{DateTime.Now.ToString("yyyyMM")}";
MakeDirectory(directory);
string sIP = "192.168.40.165";
int iport = 1025;
DisplayMessage("## PLC 연결 ##_IP: " + sIP + "_PORT: " + iport, true);
McProtocolTcp mcProtocol = new McProtocolTcp(sIP, iport); // Instantiate MC Protocol client
while (true)
{
if (ConnectToPLC(mcProtocol))
{
DisplayMessage("## PLC 연결 OK!!! ## _IP: " + sIP, true);
break;
}
else
{
DisplayMessage("## PLC 연결 오류!!! ## _IP: " + sIP, false);
Thread.Sleep(5000);
}
}
int i = 0;
while (true)
{
DisplayMessage($"{i}_## PLC Read...##", false);
try
{
// PLC 값 읽기
List<int> w_values = BatchReadWordUnits(mcProtocol, "D11490", 33);
if (w_values.Count == 0)
{
DisplayMessage("## 값이 없습니다 ##", true);
BatchWriteWordUnits(mcProtocol, "D11579", new List<int> { 0 });
}
else
{
// 데이터를 파일에 기록
string logPath = $"c:/tong/Plog/{DateTime.Now.ToString("yyyy-MM-dd")}.txt";
using (StreamWriter file = new StreamWriter(logPath, true))
{
foreach (var value in w_values)
{
file.Write("[" + value + "]");
}
file.WriteLine();
}
}
if (i % 2 == 0)
{
BatchWriteWordUnits(mcProtocol, "D11579", new List<int> { 1 });
DisplayMessage("## D11579에 1 전송 ##", true);
}
}
catch (Exception ex)
{
DisplayMessage($"## MC Protocol Error ##: {ex.Message}", true);
}
i++;
if (i > 3000)
{
i = 0;
MakeDirectory(directory);
}
Thread.Sleep(1000);
}
}
static void MakeDirectory(string directory)
{
try
{
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: Failed to create the directory - {ex.Message}");
}
}
static void DisplayMessage(string msg, bool writeToLog)
{
string sMsg = DateTime.Now.ToString() + " : " + msg;
Console.WriteLine(sMsg);
if (writeToLog)
{
string logPath = $"c:/tong/Plog/{DateTime.Now.ToString("yyyy-MM-dd")}.txt";
using (StreamWriter file = new StreamWriter(logPath, true))
{
file.WriteLine(sMsg);
}
}
}
static bool ConnectToPLC(McProtocolTcp mcProtocol)
{
try
{
mcProtocol.Open();
return true;
}
catch (Exception)
{
return false;
}
}
static List<int> BatchReadWordUnits(McProtocolTcp mcProtocol, string headDevice, int readSize)
{
try
{
int[] readValues = mcProtocol.GetDevice(blockType: "D", headDeviceNo: int.Parse(headDevice.Substring(1)), points: readSize);
return new List<int>(readValues);
}
catch (Exception)
{
return new List<int>();
}
}
static void BatchWriteWordUnits(McProtocolTcp mcProtocol, string headDevice, List<int> values)
{
try
{
mcProtocol.SetDevice(blockType: "D", headDeviceNo: int.Parse(headDevice.Substring(1)), values.ToArray());
}
catch (Exception ex)
{
DisplayMessage($"## PLC Write Error ##: {ex.Message}", true);
}
}
}
'PYTHON(파이썬) > 파이썬 활용' 카테고리의 다른 글
| 첨부파일을 포함한 e-mail 보내기 (18) | 2024.11.14 |
|---|---|
| python으로 간단하게 e-mail 보내기 (2) | 2024.11.13 |
| 네이버에서 PYTHON으로 삼성전자 주가 가져오기 (5) | 2024.11.01 |
| 파이썬으로 작성한 SERIAL 통신 프로그램 (0) | 2024.10.31 |
| PC에 연결된 SERIAL PORT 찾기 (파이썬 그리고 C#) (2) | 2024.10.31 |