diff --git a/FC_InferfaceBoard/.theia/launch.json b/FC_InferfaceBoard/.theia/launch.json index 7e4253b..9a49ac9 100644 --- a/FC_InferfaceBoard/.theia/launch.json +++ b/FC_InferfaceBoard/.theia/launch.json @@ -3,6 +3,6 @@ // Hover to view descriptions of existing attributes. "version": "0.2.0", "configurations": [ - + ] } diff --git a/FC_InferfaceBoard/Data_process.vi b/FC_InferfaceBoard/Data_process.vi new file mode 100644 index 0000000..85673e7 Binary files /dev/null and b/FC_InferfaceBoard/Data_process.vi differ diff --git a/FC_InferfaceBoard/Ethernet.ino b/FC_InferfaceBoard/Ethernet.ino index e408fc0..78801c8 100644 --- a/FC_InferfaceBoard/Ethernet.ino +++ b/FC_InferfaceBoard/Ethernet.ino @@ -44,7 +44,7 @@ void webReponse(){ String response = "HTTP/1.1 200 OK\r\n"; response += "Content-Type: text/html\r\n\r\n"; response += ""; - response += Prcss_AI(); + response += Prcss_AI_Read(); //response += "

Hello, World!

"; response += ""; @@ -62,8 +62,8 @@ void webReponse(){ String demuxCMD(String command, String* rightPart) { - // "::"를 기준으로 문자열을 분리 - int separatorIndex = command.indexOf("::"); + // ":"를 기준으로 문자열을 분리 + int separatorIndex = command.indexOf(":"); String leftPart = command.substring(0, separatorIndex); *rightPart = command.substring(separatorIndex + 2); diff --git a/FC_InferfaceBoard/FC_InferfaceBoard.ino b/FC_InferfaceBoard/FC_InferfaceBoard.ino index b29f7bf..1a87758 100644 --- a/FC_InferfaceBoard/FC_InferfaceBoard.ino +++ b/FC_InferfaceBoard/FC_InferfaceBoard.ino @@ -10,7 +10,13 @@ #define RcvErr "ER\r\n" #define MODE_DEBUG false - +const int BUFF_SIZE = 512; +char Buff_Eth_Rd[BUFF_SIZE] = {0}; +char Buff_485_Wr[BUFF_SIZE] = {0}; +char Buff_485_Rd[BUFF_SIZE] = {0}; +String latest_sent_msg; +int numOf485 = 0; +int returnTime = 0; // ========== ========== Periodic Flags bool T_10ms = false; bool T_20ms = false; @@ -18,9 +24,9 @@ bool T_50ms = false; bool T_100ms = false; bool T_200ms = false; bool T_500ms = false; -bool T_500ms_2 = false; bool T_1000ms = false; - +bool T_2000ms = false; +bool T_5000ms = false; // ========== ========== Communication // ---------- Ethernet @@ -49,8 +55,9 @@ int Wait_485_cnt; int Size_AI = 16; int Values_AI[16]; int Size_PV = 8; -int Values_PV[8]; - +int Values_10_PV[8]; +int Size_SV = 8; +int Values_10_SV[8]; int msCnt = 0; unsigned long timer = 0; @@ -63,7 +70,8 @@ void setup() { // modules setup (init.) Ethernet_setup(); GPIO_setup(); - MC9_setup(); + //MC9_setup(); + RS485_setup(); // Timer set MsTimer2::set(10, timer_10ms); @@ -73,7 +81,7 @@ void setup() { void loop() { // wait for a new client: - webReponse(); + //webReponse(); client = server.available(); if (client) { @@ -95,6 +103,15 @@ void loop() { char c ;//= client.read(); while((c = client.read())) { + + if((c == '\n') && (Buff_Eth_Rd[strlen(Buff_Eth_Rd)-1] == '\r')){ + write_buff_c(Buff_Eth_Rd, c); + break; + }else{ + write_buff_c(Buff_Eth_Rd, c); + } + + /* //If endwith CRLF if((c == 10) && (Buf_eth.endsWith("\r"))){ Buf_eth.remove(Buf_eth.length() - 1); //remove CR @@ -104,32 +121,33 @@ void loop() { }else{ Buf_eth += c; } + */ } // 데이터를 수신했으므로 타임아웃 타이머 초기화 lastDataReceivedTime = millis(); } - + message = read_buff(Buff_Eth_Rd); // If data read if(message != ""){ cmd = demuxCMD(message, &cmdData); message = ""; - if(cmd=="AI"){ - client.print(Prcss_AI()); + if(cmd=="AI?"){ + client.print(Prcss_AI_Read()); - }else if(cmd=="AO"){ + }else if(cmd=="AO!"){ dataSize = demuxNum(cmdData, data); client.print(Prcss_AO(data, dataSize)); - }else if(cmd=="PV"){ - client.print(Prcss_PV()); + }else if(cmd=="PV?"){ + client.print(Prcss_PV_Read()); - }else if(cmd=="SV"){ - dataSize = demuxNum(cmdData, data); - client.print(Prcss_SV(data, dataSize)); + }else if(cmd=="SV?"){ + client.print(Prcss_SV_Read()); - }else if(cmd=="RS"){ - client.print(Prcss_RS(cmdData)); + }else if(cmd=="SV!"){ + dataSize = demuxNum(cmdData, data); + client.print(Prcss_SV_Write(data, dataSize)); }//else if(cmd==""){ diff --git a/FC_InferfaceBoard/GPIO.ino b/FC_InferfaceBoard/GPIO.ino index 89087ab..6a2390b 100644 --- a/FC_InferfaceBoard/GPIO.ino +++ b/FC_InferfaceBoard/GPIO.ino @@ -1,14 +1,14 @@ -int aipin[] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15}; +const int aipin[] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15}; void GPIO_setup(){ } -void read_analog(int arr[], int size){ +void read_analog(){ int i = 0; - for(i = 0 ; i < size ; i++){ - arr[i] = analogRead(aipin[i]); + for(i = 0 ; i < Size_AI ; i++){ + Values_AI[i] = analogRead(aipin[i]); } } \ No newline at end of file diff --git a/FC_InferfaceBoard/MC9.ino b/FC_InferfaceBoard/MC9.ino index cb43b09..3ba5eec 100644 --- a/FC_InferfaceBoard/MC9.ino +++ b/FC_InferfaceBoard/MC9.ino @@ -1,16 +1,5 @@ -// Sample communication Code for RS 485 Shield with Arduino Mega 2560 -#define RS485_OE_1 22 //RS485 CH#1 Output Enable => pin 22 for CH#1 -#define Snd_485 HIGH -#define Rcv_485 LOW - -void MC9_setup(){ - Serial1.setTimeout(300); - Serial1.begin(9600); - pinMode(RS485_OE_1, OUTPUT); - delay(10); - digitalWrite(RS485_OE_1, Rcv_485); -} +/* void read_mc9_req(String address){ if(!Wait_485){ String command = ""; @@ -70,4 +59,5 @@ void write_mc9(int arr[], int size){ Serial1.print("485 Write^^\r\n"); //Serial Write ADC_Value to RS-485 Bus Serial1.flush(); digitalWrite(RS485_OE_1, Rcv_485); delay(5); -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/FC_InferfaceBoard/Processes.ino b/FC_InferfaceBoard/Processes.ino index 5cc8bd4..bc78848 100644 --- a/FC_InferfaceBoard/Processes.ino +++ b/FC_InferfaceBoard/Processes.ino @@ -1,6 +1,6 @@ // -String Prcss_AI(){ - String str = ""; +String Prcss_AI_Read(){ + String str = "AI?:"; for (int i = 0; i < Size_AI; i++) { char formattedNumber[5]; // 4자리 숫자 + 널 종료 문자 @@ -14,7 +14,7 @@ String Prcss_AI(){ } String Prcss_AO(unsigned int data[], int dataSize){ - String str = ""; + String str = "AO!:"; for(int i=0 ; i pin 22 for CH#1 +#define Snd_485 HIGH +#define Rcv_485 LOW + +#define MC9_10_PV "10DRS,08,0001CB" +#define MC9_10_SV "10DRS,08,0011CC" + +void RS485_setup(){ + Serial1.setTimeout(300); + Serial1.begin(9600); + pinMode(RS485_OE_1, OUTPUT); + delay(10); + digitalWrite(RS485_OE_1, Rcv_485); +} + +void send_485(){ + if(!Wait_485){ + String message = read_buff(Buff_485_Wr); + // Send request to return pv data + //Serial.println(Buff_485_Wr); + //Serial.print(message); + //Serial.print(" : "); + if(message != ""){ + latest_sent_msg = message; + message += "\r\n"; + digitalWrite(RS485_OE_1, Snd_485); delay(5); + Serial1.print(message); + returnTime = millis(); + Serial1.flush(); + digitalWrite(RS485_OE_1, Rcv_485); delay(5); + + Wait_485 = true; + Wait_485_cnt = 0; + } + else{ + //Serial.println("Free"); + } + + } + +} + +int read_485(){ + // Timeout code + if(Wait_485){ + Wait_485_cnt++; + if(Wait_485_cnt > 200){ // Timeout = periodic(100ms) x 200 = 2 sec + Serial.println("485 not responced... (Timeout)"); + latest_sent_msg = ""; + Wait_485 = false; + Wait_485_cnt = 0; + numOf485--; + return 0; + } + } + // Receive pv data + while(Wait_485 && (Serial1.available() > 0)) { + char c = Serial1.read(); + write_buff_c(Buff_485_Rd, c); + } + + String message = read_buff(Buff_485_Rd); + if(message != ""){ + + int addr; + String mode; + int data[8]; + int crc; + numOf485--; + //message.replace("\r\n",""); + //Serial.println(message); + if (parseMessage(message, addr, mode, data, crc)) { + + if(latest_sent_msg == MC9_10_PV){ + for(int i = 0 ; i < Size_PV ; i++){ + Values_10_PV[i] = data[i]; + } + } + if(latest_sent_msg == MC9_10_SV){ + for(int i = 0 ; i < Size_SV ; i++){ + Values_10_SV[i] = data[i]; + } + } + } else { + // OK가 아닌 경우 또는 파싱 오류가 발생한 경우 + Serial.println("error 485 read"); + } + Wait_485 = false; + Wait_485_cnt = 0; + } + return 1; +} + +int parseMessage(const String& message, int& addr, String& mode, int data[8], int& crc) { + char addrC[3], modeC[4], statusC[3]; + int dataC[8], crcC; + + if (message[0] == '\x02') { + message = message.substring(1); + } + + int ret = sscanf(message.c_str(), "%2s%3s,%2s,%4x,%4x,%4x,%4x,%4x,%4x,%4x,%4x%2x", + addrC, modeC, statusC, &dataC[0], &dataC[1], &dataC[2], &dataC[3], &dataC[4], &dataC[5], &dataC[6], &dataC[7], &crcC); + + + if (strcmp(statusC, "OK") != 0 || ret != 12) { + // 오류 처리 + return 0; + } + + // 복사 + addr = atoi(addrC); + mode = String(modeC); + for (int i = 0; i < 8; i++) { + data[i] = dataC[i]; + } + crc = crcC; + + return 1; +} + diff --git a/FC_InferfaceBoard/TCPIP - Write Read.vi b/FC_InferfaceBoard/TCPIP - Write Read.vi index 6973b41..cd2adc2 100644 Binary files a/FC_InferfaceBoard/TCPIP - Write Read.vi and b/FC_InferfaceBoard/TCPIP - Write Read.vi differ diff --git a/FC_InferfaceBoard/Utils.ino b/FC_InferfaceBoard/Utils.ino index e69de29..b4a5a75 100644 --- a/FC_InferfaceBoard/Utils.ino +++ b/FC_InferfaceBoard/Utils.ino @@ -0,0 +1,54 @@ +int write_buff_c(char* buff, char c) { + size_t len = strlen(buff); + if (len + 1 < BUFF_SIZE) { + buff[len] = c; + buff[len + 1] = '\0'; // 문자열의 끝을 나타내는 null 문자를 추가해야 합니다. + return 1; + } else { + Serial.println("Not enough space in buffer! (write c)"); + return 0; + } +} + + +int write_buff(char* buff, String str) { + const char* cstr = str.c_str(); + size_t len = strlen(cstr); + if (strlen(buff) + len < BUFF_SIZE) { + strcat(buff, cstr); + numOf485++; + return 1; + } else { + Serial.println("Not enough space in buffer! (write)"); + return 0; + } +} + +int write_buff_first(char* buff, String str) { + const char* cstr = str.c_str(); + size_t len = strlen(cstr); + if (strlen(buff) + len < BUFF_SIZE) { + char temp[BUFF_SIZE]; + strcpy(temp, buff); // copy existing content to temp buffer + strcpy(buff, cstr); // copy new string to buffer + strcat(buff, temp); // append old content to buffer + numOf485++; + return 1; + } else { + Serial.println("Not enough space in buffer! (prepend)"); + return 0; + } +} + +String read_buff(char* buff) { + char* pos = strstr(buff, "\r\n"); + String output = ""; + if (pos != nullptr) { + size_t len = pos - buff; + output = String(buff).substring(0, len); + + // Shift remaining string to the start + memmove(buff, pos + 2, strlen(pos + 2) + 1); + } + return output; +} \ No newline at end of file diff --git a/FC_InferfaceBoard/periodics.ino b/FC_InferfaceBoard/periodics.ino index ce01890..89b338a 100644 --- a/FC_InferfaceBoard/periodics.ino +++ b/FC_InferfaceBoard/periodics.ino @@ -1,38 +1,42 @@ // void Periodic_run(){ if(T_10ms){ - read_analog(Values_AI, Size_AI); - read_mc9(Values_PV, Size_PV); + read_analog(); T_10ms = false; } if(T_20ms){ - + read_485(); + send_485(); T_20ms = false; } if(T_50ms){ - + T_50ms = false; } if(T_100ms){ - + T_100ms = false; } if(T_200ms){ - + T_200ms = false; } if(T_500ms){ - read_mc9_req("10"); T_500ms = false; } - if(T_500ms_2){ - read_mc9_req("11"); - T_500ms_2 = false; - } if(T_1000ms){ - AnalogIn_Print(); + write_buff(Buff_485_Wr, MC9_10_PV); // 10 DRS num 8 from ch1 PV T_1000ms = false; } + if(T_2000ms){ + Serial.print("----- remain 485 buff : "); + Serial.println(numOf485); + T_2000ms = false; + } + if(T_5000ms){ + write_buff(Buff_485_Wr, MC9_10_SV); // 10 DRS num 8 from ch1 SV + T_5000ms = false; + } } void timer_10ms(){ msCnt += 10; @@ -53,11 +57,14 @@ void timer_10ms(){ if (msCnt % 500 == 0){ T_500ms = true; } - if ((msCnt+250) % 500 == 0){ - T_500ms_2 = true; - } - if (msCnt > 1000){ + if (msCnt % 1000 == 0){ T_1000ms = true; + } + if (msCnt % 2000 == 0){ + T_2000ms = true; + } + if (msCnt > 5000){ + T_5000ms = true; msCnt = 0; }