initial commit
This commit is contained in:
569
Arduino_PLC/HmiClass.cpp
Normal file
569
Arduino_PLC/HmiClass.cpp
Normal file
@@ -0,0 +1,569 @@
|
||||
#include "IO.h"
|
||||
#include "VarClass.h"
|
||||
#include "HmiClass.h"
|
||||
#include "UtilClass.h"
|
||||
#include "motor.h"
|
||||
#include "arduino.h"
|
||||
|
||||
unsigned long errtime = 0;
|
||||
unsigned long eruntime = 0;
|
||||
|
||||
void HmiClass::Setup()
|
||||
{
|
||||
hmi.SendMessage("##:HMI:SETUP", false);
|
||||
updatetime = millis();
|
||||
ClearTempBuffer0();
|
||||
ClearTempBuffer1();
|
||||
}
|
||||
|
||||
void HmiClass::Update()
|
||||
{
|
||||
//데이터는 일정 주기로 전송한다.
|
||||
unsigned long runtime = millis() - updatetime;
|
||||
uint8_t loopterm = var._eep_iosendinterval;
|
||||
|
||||
loopterm = 500;
|
||||
|
||||
//설정 중에는 통신속도를 초당 10번으로 고정한다
|
||||
if (var.getFlag(FLAG_SETUP) == true) loopterm = 100;
|
||||
if (runtime > loopterm)
|
||||
{
|
||||
//IO상태전송
|
||||
SendIOStatus();
|
||||
|
||||
//설정모드에서는 계속 전송 한다
|
||||
if (var.getFlag(FLAG_SETUP) == true)
|
||||
{
|
||||
//EEP정보 전송
|
||||
SendSetupInfo();
|
||||
}
|
||||
updatetime = millis();
|
||||
}
|
||||
|
||||
//입력값 감지 190319
|
||||
CheckReceiveS0();
|
||||
CheckReceiveS1();
|
||||
}
|
||||
|
||||
void HmiClass::SendIOStatus()
|
||||
{
|
||||
//전송데이터처리
|
||||
byte payload[29]; //IO4바이트(uint32), A0~A3 A는 각 2바이트(uint16)
|
||||
byte payidx = 0;
|
||||
|
||||
payload[payidx++] = '@'; //@
|
||||
payload[payidx++] = '@'; //@
|
||||
payload[payidx++] = 10; //데이터 길이
|
||||
payload[payidx++] = 'I'; //49=I(IO)
|
||||
payload[payidx++] = (byte)(var.IOData >> 0); //INPUT(16)
|
||||
payload[payidx++] = (byte)(var.IOData >> 8); //OUTPUT(16)
|
||||
payload[payidx++] = (byte)(var.IOData >> 16);
|
||||
payload[payidx++] = (byte)(var.IOData >> 24);
|
||||
|
||||
uint32_t flagValue = var.getFlagValue();
|
||||
payload[payidx++] = (byte)(flagValue >> 0); //FLAG (0~31)
|
||||
payload[payidx++] = (byte)(flagValue >> 8);
|
||||
payload[payidx++] = (byte)(flagValue >> 16);
|
||||
payload[payidx++] = (byte)(flagValue >> 24);
|
||||
|
||||
//쓰레드진행시간
|
||||
payload[payidx++] = (byte)var.runtime;
|
||||
|
||||
//checksum
|
||||
byte checksum = 0;
|
||||
for (int i = 3; i < payidx; i++)
|
||||
checksum = checksum ^ payload[i];
|
||||
|
||||
payload[payidx++] = checksum;
|
||||
payload[payidx++] = 0x0D;
|
||||
payload[payidx++] = 0x0A;
|
||||
|
||||
//Serial.print("Send Payload len=");
|
||||
//Serial.println(payidx);
|
||||
|
||||
hmiSerial.write(payload, payidx);
|
||||
hmiSerial.flush();
|
||||
|
||||
//20190325 - 1번포트로 미러링
|
||||
//dbgSerial.write(payload, sizeof(payload));
|
||||
//dbgSerial.flush();
|
||||
}
|
||||
|
||||
void HmiClass::SendSetupInfo()
|
||||
{
|
||||
//전송데이터처리
|
||||
byte payload[19]; //IO4바이트(uint32), A0~A3 A는 각 2바이트(uint16)
|
||||
byte payidx = 0;
|
||||
|
||||
payload[payidx++] = '@'; //@
|
||||
payload[payidx++] = '@'; //@
|
||||
payload[payidx++] = 5; //데이터 길이
|
||||
payload[payidx++] = 'S'; //49=I(IO),T=TEXT,S=SETUP
|
||||
payload[payidx++] = var._eep_iosendinterval;
|
||||
payload[payidx++] = var._eep_resetcount;
|
||||
payload[payidx++] = var._eep_pindir_iH;
|
||||
payload[payidx++] = var._eep_pindir_iL;
|
||||
|
||||
//checksum
|
||||
byte checksum = 0;
|
||||
for (int i = 3; i < payidx; i++)
|
||||
checksum = checksum ^ payload[i];
|
||||
|
||||
payload[payidx++] = checksum;
|
||||
payload[payidx++] = 0x0D;
|
||||
payload[payidx++] = 0x0A;
|
||||
|
||||
//Serial.print("Send Payload len=");
|
||||
//Serial.println(sizeof(payload));
|
||||
|
||||
hmiSerial.write(payload, sizeof(payload));
|
||||
hmiSerial.flush();
|
||||
|
||||
//20190325 - 1번포트로 미러링
|
||||
//dbgSerial.write(payload, sizeof(payload));
|
||||
//dbgSerial.flush();
|
||||
}
|
||||
|
||||
void HmiClass::CheckReceiveS0()
|
||||
{
|
||||
//수신데이터가 있는경우에만 처리함
|
||||
//bool newdata = hmiSerial.available() > 0;
|
||||
//if (newdata) sprint(F("HMI Received Data ["));
|
||||
while (hmiSerial.available() > 0) {
|
||||
incomingByte0 = (char)(hmiSerial.read());
|
||||
|
||||
if (STX1S0 == false)
|
||||
{
|
||||
if (incomingByte0 != '@')
|
||||
{
|
||||
STX2S0 = false;
|
||||
ETX1S0 = false;
|
||||
SendMessage(F("ERROR:STX1"), true);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
STX1S0 = true;
|
||||
ClearTempBuffer0();
|
||||
Tempbuffer1[bufferIndex0++] = incomingByte0; //Tempbuffer1 += incomingByte;
|
||||
}
|
||||
}
|
||||
else if (STX2S0 == false)
|
||||
{
|
||||
if (bufferIndex0 != 1 || bufferIndex0 < 1 || Tempbuffer1[0] != '@' || incomingByte0 != '@')
|
||||
{
|
||||
STX1S0 = false;
|
||||
ETX1S0 = false;
|
||||
SendMessage(F("ERROR:STX2"), true);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
STX2S0 = true;
|
||||
Tempbuffer1[bufferIndex0++] = incomingByte0; //Tempbuffer1 += incomingByte;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Tempbuffer1[bufferIndex0++] = incomingByte0; //Tempbuffer1 += incomingByte;
|
||||
|
||||
//여기서부터는무조건 누적한다.
|
||||
if (bufferIndex0 == 3)
|
||||
{
|
||||
if (Tempbuffer1[0] != 0x40 || Tempbuffer1[1] != '@')
|
||||
{
|
||||
STX1S0 = false;
|
||||
STX2S0 = false;
|
||||
ETX1S0 = false;
|
||||
|
||||
bufferIndex0 = 0; // = "";
|
||||
}
|
||||
else LEN1 = incomingByte0; //데이터 길이가온다
|
||||
}
|
||||
else if (bufferIndex0 == LEN1 + 2 + 1 + 1) //체크섬이 왔다
|
||||
{
|
||||
CHK1 = incomingByte0;
|
||||
}
|
||||
else if (bufferIndex0 == LEN1 + 2 + 1 + 1 + 1) //ETX1
|
||||
{
|
||||
if (incomingByte0 != 0x0D)
|
||||
{
|
||||
//ETX가 와야하는데 다른데이터가 왔다
|
||||
STX1S0 = false;
|
||||
STX2S0 = false;
|
||||
ETX1S0 = false;
|
||||
bufferIndex0 = 0;//
|
||||
SendMessage(F("ERROR:STX3"), true);
|
||||
}
|
||||
}
|
||||
else if (bufferIndex0 == LEN1 + 2 + 1 + 1 + 1 + 1)
|
||||
{
|
||||
//전체길이를 만족햇다.
|
||||
if (incomingByte0 != 0x0A)
|
||||
{
|
||||
//ETX가 와야하는데 다른데이터가 왔다
|
||||
STX1S0 = false;
|
||||
STX2S0 = false;
|
||||
ETX1S0 = false;
|
||||
//Console.WriteLine("에러 모두 파기");
|
||||
bufferIndex0 = 0;// == "";//.Clear();
|
||||
SendMessage(F("ERROR:STX4"), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
STX1S0 = false;
|
||||
STX2S0 = false;
|
||||
ETX1S0 = false;
|
||||
|
||||
//임시버퍼의 데이터를 수신데이터 변수에 넣는다
|
||||
//memcpy(buffer.c_str(), Tempbuffer1.c_str(), sizeof(Tempbuffer1));
|
||||
//Tempbuffer1.toCharArray()
|
||||
//buffer = Tempbuffer1;
|
||||
Parser(bufferIndex0);
|
||||
bufferIndex0 = 0;
|
||||
//Tempbuffer1[0] = 0; //첫비트에 nullstring 을 넣는다
|
||||
//var.runCommand( parser(buffer1, addMsg1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////stx ,etx 는 hex 처리하고 번호와 값을 ascii처리함
|
||||
//if (incomingByte == 0x02) buffer = "";
|
||||
//else if (incomingByte == 0x03)
|
||||
//{
|
||||
// //ETX값이나 전체 길이가 4가아니라면 추가해야함
|
||||
// uint8_t butNo = (uint8_t)(buffer.substring(0, 3).toInt());
|
||||
// uint8_t butValue = (uint8_t)(buffer.substring(3, 4).toInt());
|
||||
// //remote 명령과 공유하기 위해서 util로 이동
|
||||
// var.runCommand((eCommand)butNo, butValue,0); //NewMsgEvent(butNo, butValue);
|
||||
// break;
|
||||
//}
|
||||
//else{
|
||||
// buffer += (char)incomingByte; //문자를 누적시킨다.
|
||||
// if (buffer.length() > 10) {
|
||||
// sprintln(F("HMI buffer Over error"));
|
||||
// buffer = "";
|
||||
// }
|
||||
//}
|
||||
}
|
||||
//if (newdata) sprintln("]");
|
||||
}
|
||||
|
||||
void HmiClass::CheckReceiveS1()
|
||||
{
|
||||
//수신데이터가 있는경우에만 처리함
|
||||
//bool newdata = dbgSerial.available() > 0;
|
||||
//if (newdata) sprint(F("HMI Received Data ["));
|
||||
while (dbgSerial.available() > 0) {
|
||||
incomingByte1 = (char)(dbgSerial.read());
|
||||
|
||||
if(incomingByte1 == 0x0A) //if newline
|
||||
{
|
||||
String cmd = "";
|
||||
for(int i = 0 ; i < bufferIndex1;i++)
|
||||
{
|
||||
cmd += String((char)Tempbuffer1[i]);
|
||||
}
|
||||
|
||||
if(cmd.equals("UP")||cmd.equals("up"))
|
||||
{
|
||||
Serial.println("User command : z-up");
|
||||
mot.SetZRun(ZRUN_UP);
|
||||
}
|
||||
else if(cmd.equals("DN")||cmd.equals("dn"))
|
||||
{
|
||||
Serial.println("User command : z-down");
|
||||
mot.SetZRun(ZRUN_DN);
|
||||
}
|
||||
else if(cmd.equals("STOP")||cmd.equals("stop"))
|
||||
{
|
||||
Serial.println("User command : z-stop");
|
||||
mot.SetZRun(ZRUN_STOP);
|
||||
}
|
||||
else{
|
||||
Serial.print("Unknown Command : ");
|
||||
Serial.println(cmd);
|
||||
}
|
||||
|
||||
bufferIndex1 = 0;
|
||||
}
|
||||
else if(bufferIndex1 > 99)
|
||||
{
|
||||
Serial.println(F("recv1 length error(>99"));
|
||||
bufferIndex1 = 0;
|
||||
}
|
||||
else {
|
||||
Tempbuffer1[bufferIndex1++] = incomingByte1; //Tempbuffer1 += incomingByte;
|
||||
}
|
||||
}
|
||||
//if (newdata) sprintln("]");
|
||||
}
|
||||
/*
|
||||
void HmiClass::CheckReceiveS1_Backup_221117()
|
||||
{
|
||||
//수신데이터가 있는경우에만 처리함
|
||||
bool newdata = dbgSerial.available() > 0;
|
||||
//if (newdata) sprint(F("HMI Received Data ["));
|
||||
while (dbgSerial.available() > 0) {
|
||||
incomingByte1 = (char)(dbgSerial.read());
|
||||
|
||||
if (STX1S1 == false)
|
||||
{
|
||||
if (incomingByte1 != '@')
|
||||
{
|
||||
STX2S1 = false;
|
||||
ETX1S1 = false;
|
||||
SendMessage(F("ERROR:STX1"), true);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
STX1S1 = true;
|
||||
ClearTempBuffer1();
|
||||
Tempbuffer1[bufferIndex1++] = incomingByte1; //Tempbuffer1 += incomingByte;
|
||||
}
|
||||
}
|
||||
else if (STX2S1 == false)
|
||||
{
|
||||
if (bufferIndex1 != 1 || bufferIndex1 < 1 || Tempbuffer1[0] != '@' || incomingByte1 != '@')
|
||||
{
|
||||
STX1S1 = false;
|
||||
ETX1S1 = false;
|
||||
SendMessage(F("ERROR:STX2"), true);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
STX2S1 = true;
|
||||
Tempbuffer1[bufferIndex1++] = incomingByte1; //Tempbuffer1 += incomingByte;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Tempbuffer1[bufferIndex1++] = incomingByte1; //Tempbuffer1 += incomingByte;
|
||||
|
||||
//여기서부터는무조건 누적한다.
|
||||
if (bufferIndex1 == 3)
|
||||
{
|
||||
if (Tempbuffer1[0] != 0x40 || Tempbuffer1[1] != '@')
|
||||
{
|
||||
STX1S1 = false;
|
||||
STX2S1 = false;
|
||||
ETX1S1 = false;
|
||||
|
||||
bufferIndex1 = 0; // = "";
|
||||
}
|
||||
else LEN1 = incomingByte1; //데이터 길이가온다
|
||||
}
|
||||
else if (bufferIndex1 == LEN1 + 2 + 1 + 1) //체크섬이 왔다
|
||||
{
|
||||
CHK1 = incomingByte1;
|
||||
}
|
||||
else if (bufferIndex1 == LEN1 + 2 + 1 + 1 + 1) //ETX1
|
||||
{
|
||||
if (incomingByte1 != 0x0D)
|
||||
{
|
||||
//ETX가 와야하는데 다른데이터가 왔다
|
||||
STX1S1 = false;
|
||||
STX2S1 = false;
|
||||
ETX1S1 = false;
|
||||
bufferIndex1 = 0;//
|
||||
SendMessage(F("ERROR:STX3"), true);
|
||||
}
|
||||
}
|
||||
else if (bufferIndex1 == LEN1 + 2 + 1 + 1 + 1 + 1)
|
||||
{
|
||||
//전체길이를 만족햇다.
|
||||
if (incomingByte1 != 0x0A)
|
||||
{
|
||||
//ETX가 와야하는데 다른데이터가 왔다
|
||||
STX1S1 = false;
|
||||
STX2S1 = false;
|
||||
ETX1S1 = false;
|
||||
//Console.WriteLine("에러 모두 파기");
|
||||
bufferIndex1 = 0;// == "";//.Clear();
|
||||
SendMessage(F("ERROR:STX4"), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
STX1S1 = false;
|
||||
STX2S1 = false;
|
||||
ETX1S1 = false;
|
||||
|
||||
//임시버퍼의 데이터를 수신데이터 변수에 넣는다
|
||||
//memcpy(buffer.c_str(), Tempbuffer1.c_str(), sizeof(Tempbuffer1));
|
||||
//Tempbuffer1.toCharArray()
|
||||
//buffer = Tempbuffer1;
|
||||
Parser(bufferIndex1);
|
||||
bufferIndex1 = 0;
|
||||
//Tempbuffer1[0] = 0; //첫비트에 nullstring 을 넣는다
|
||||
//var.runCommand( parser(buffer1, addMsg1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////stx ,etx 는 hex 처리하고 번호와 값을 ascii처리함
|
||||
//if (incomingByte == 0x02) buffer = "";
|
||||
//else if (incomingByte == 0x03)
|
||||
//{
|
||||
// //ETX값이나 전체 길이가 4가아니라면 추가해야함
|
||||
// uint8_t butNo = (uint8_t)(buffer.substring(0, 3).toInt());
|
||||
// uint8_t butValue = (uint8_t)(buffer.substring(3, 4).toInt());
|
||||
// //remote 명령과 공유하기 위해서 util로 이동
|
||||
// var.runCommand((eCommand)butNo, butValue,0); //NewMsgEvent(butNo, butValue);
|
||||
// break;
|
||||
//}
|
||||
//else{
|
||||
// buffer += (char)incomingByte; //문자를 누적시킨다.
|
||||
// if (buffer.length() > 10) {
|
||||
// sprintln(F("HMI buffer Over error"));
|
||||
// buffer = "";
|
||||
// }
|
||||
//}
|
||||
}
|
||||
//if (newdata) sprintln("]");
|
||||
}
|
||||
*/
|
||||
|
||||
void HmiClass::Parser(byte bufferIndex)
|
||||
{
|
||||
Serial.println("Remote Command Parse");
|
||||
|
||||
//데이터를 분석해야 함
|
||||
if (Tempbuffer1[0] == '@' && Tempbuffer1[1] == '@' &&
|
||||
Tempbuffer1[bufferIndex - 2] == 0x0D && Tempbuffer1[bufferIndex - 1] == 0x0A)
|
||||
{
|
||||
byte len = Tempbuffer1[2];
|
||||
byte chk = Tempbuffer1[len + 3];
|
||||
if (bufferIndex != len + 6)
|
||||
{
|
||||
String msg = ("===>Frame length error len=");
|
||||
msg += String(bufferIndex);
|
||||
msg += (",receive=");
|
||||
msg += String(len + 6);
|
||||
SendMessage(msg, true);
|
||||
}
|
||||
else {
|
||||
//체크섬확인
|
||||
byte cs = 0;
|
||||
for (int i = 3; i < (3 + len); i++)
|
||||
cs = cs ^ Tempbuffer1[i];
|
||||
if (chk != cs)
|
||||
{
|
||||
String msg = ("===>checksum error calc=");
|
||||
msg.concat( String(cs));
|
||||
msg.concat("receive=");
|
||||
msg.concat(String(chk));
|
||||
SendMessage(msg, true);
|
||||
}
|
||||
else {
|
||||
//체크섬일치
|
||||
byte command = Tempbuffer1[3];
|
||||
byte param1 = Tempbuffer1[4];
|
||||
byte param2 = Tempbuffer1[5];
|
||||
var.runCommand((eCommand)command, param1, param2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//프레임이 이상하다.
|
||||
//sprintln("===>Frame error stx, etx");
|
||||
SendMessage("==>Frame error no stx,etx", true);
|
||||
}
|
||||
}
|
||||
void HmiClass::ClearTempBuffer0()
|
||||
{
|
||||
LEN0 = 0;
|
||||
bufferIndex0 = 0;
|
||||
memcpy(Tempbuffer0, 0, sizeof(Tempbuffer0));
|
||||
}
|
||||
void HmiClass::ClearTempBuffer1()
|
||||
{
|
||||
LEN1 = 0;
|
||||
bufferIndex1 = 0;
|
||||
memcpy(Tempbuffer1, 0, sizeof(Tempbuffer1));
|
||||
}
|
||||
|
||||
void HmiClass::SendMessage(String message, bool isError)
|
||||
{
|
||||
if(message.equals(hmimessage))
|
||||
{
|
||||
//동일메세지가 왓다면 1초이내로 다시 전송하지 못하게 한다.
|
||||
if(hmimessagerepeat == 0 || hmimessagerepeat > millis())
|
||||
hmimessagerepeat = millis();
|
||||
|
||||
hmimessagetime = millis()-hmimessagerepeat;
|
||||
if(hmimessagetime < 999) return;
|
||||
|
||||
} else{
|
||||
hmimessagerepeat = millis();
|
||||
hmimessage = message;
|
||||
}
|
||||
// test = len 4 , totals 4+4=8
|
||||
// @ @ 6 T 0 t e s t chk \r \n
|
||||
byte totalLength = message.length() + 8;
|
||||
byte payload[100]; //IO4바이트(uint32), A0~A3 A는 각 2바이트(uint16)
|
||||
byte payidx = 0;
|
||||
|
||||
payload[payidx++] = '@'; //@
|
||||
payload[payidx++] = '@'; //@
|
||||
payload[payidx++] = message.length() + 2; //데이터 길이
|
||||
payload[payidx++] = 'T';
|
||||
payload[payidx++] = isError; //오류여부
|
||||
for (int i = 0; i < message.length(); i++)
|
||||
{
|
||||
payload[payidx++] = message[i];
|
||||
}
|
||||
|
||||
//checksum
|
||||
byte checksum = 0;
|
||||
for (int i = 3; i < (3 + message.length() + 2); i++)
|
||||
checksum = checksum ^ payload[i];
|
||||
|
||||
payload[payidx++] = checksum;
|
||||
payload[payidx++] = 0x0D;
|
||||
payload[payidx++] = 0x0A;
|
||||
|
||||
hmiSerial.write(payload, totalLength);
|
||||
hmiSerial.flush();
|
||||
|
||||
//20190325 - 1번포트로 미러링
|
||||
dbgSerial.println(message);
|
||||
//dbgSerial.write(message, message.length);
|
||||
//dbgSerial.flush();
|
||||
|
||||
}
|
||||
bool HmiClass::SendValue(char msg, uint32_t value)
|
||||
{
|
||||
byte totalLength = 11;
|
||||
byte payload[100]; //IO4바이트(uint32), A0~A3 A는 각 2바이트(uint16)
|
||||
byte payidx = 0;
|
||||
|
||||
payload[payidx++] = '@'; //@
|
||||
payload[payidx++] = '@'; //@
|
||||
payload[payidx++] = 6; //데이터 길이
|
||||
payload[payidx++] = 'V';
|
||||
payload[payidx++] = msg; //값종류
|
||||
payload[payidx++] = (byte)(value >> 0);
|
||||
payload[payidx++] = (byte)(value >> 8);
|
||||
payload[payidx++] = (byte)(value >> 16);
|
||||
payload[payidx++] = (byte)(value >> 24);
|
||||
|
||||
//checksum
|
||||
byte checksum = 0;
|
||||
for (int i = 3; i < (3 + 4 + 2); i++)
|
||||
checksum = checksum ^ payload[i];
|
||||
|
||||
payload[payidx++] = checksum;
|
||||
payload[payidx++] = 0x0D;
|
||||
payload[payidx++] = 0x0C;
|
||||
|
||||
hmiSerial.write(payload, totalLength);
|
||||
hmiSerial.flush();
|
||||
|
||||
//20190325 - 1번포트로 미러링
|
||||
dbgSerial.write(payload, totalLength);
|
||||
dbgSerial.flush();
|
||||
}
|
||||
|
||||
HmiClass hmi;
|
||||
Reference in New Issue
Block a user