570 lines
15 KiB
C++
570 lines
15 KiB
C++
#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;
|