diff --git a/FC_InferfaceBoard/Ethernet.ino b/FC_InferfaceBoard/Ethernet.ino new file mode 100644 index 0000000..e408fc0 --- /dev/null +++ b/FC_InferfaceBoard/Ethernet.ino @@ -0,0 +1,100 @@ +// +void Ethernet_setup(){ + byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x00 }; + IPAddress ip(192, 168, 20, 177); + IPAddress gateway(192, 168, 20, 1); + IPAddress subnet(255, 255, 255, 0); + + // Mac as unique value by change last byte from ip last value. + mac[5] = ip[3] & 0xFF; + // initialize the ethernet device + Ethernet.begin(mac, ip, gateway, subnet); + // start listening for clients + server.begin(); + web.begin(); + + // Report address + Serial.print("MAC>>"); + for (int i = 0; i < 6; i++) { + if (mac[i] < 16) { + Serial.print("0"); + } + Serial.print(mac[i], HEX); + if (i < 5) { + Serial.print(":"); + } + } + Serial.println(); + Serial.print("IP >>"); + Serial.println(Ethernet.localIP()); +} + +void webReponse(){ + EthernetClient webClient = web.available(); + if (webClient) { + Serial.println("Web client connected"); + while (webClient.connected()) { + if (webClient.available()) { + // 웹 브라우저에서 요청이 도착한 경우 + String request = webClient.readStringUntil('\r'); + //Serial.println(request); + webClient.flush(); + + // 웹 브라우저에 출력할 문구 작성 + String response = "HTTP/1.1 200 OK\r\n"; + response += "Content-Type: text/html\r\n\r\n"; + response += ""; + response += Prcss_AI(); + //response += "

Hello, World!

"; + response += ""; + + // 문구를 웹 브라우저로 전송 + webClient.print(response); + delay(1); + + // 클라이언트 연결 종료 + webClient.stop(); + } + } + } + +} + +String demuxCMD(String command, String* rightPart) { + + // "::"를 기준으로 문자열을 분리 + int separatorIndex = command.indexOf("::"); + String leftPart = command.substring(0, separatorIndex); + *rightPart = command.substring(separatorIndex + 2); + + leftPart.replace(" ", ""); + return leftPart; +} + + +int demuxNum(String rightPart, unsigned int data[]) { + + // 우측의 16진수 배열을 분리하여 추출 + const char* delimiter = ","; + int startIndex = 0; + int endIndex = rightPart.indexOf(delimiter); + int index = 0; + + while (endIndex >= 0) { + String hexValue = rightPart.substring(startIndex, endIndex); + // 16진수 문자열을 16진수 숫자로 변환하여 data 배열에 저장 + data[index] = strtoul(hexValue.c_str(), NULL, 16); + index++; + + startIndex = endIndex + 1; + endIndex = rightPart.indexOf(delimiter, startIndex); + } + + // 남은 마지막 16진수 배열 원소 처리 + String hexValue = rightPart.substring(startIndex); + data[index] = strtoul(hexValue.c_str(), NULL, 16); + index++; + + // 왼쪽 부분인 "ABC"을 반환 + return index; +} diff --git a/FC_InferfaceBoard/FC_InferfaceBoard.ino b/FC_InferfaceBoard/FC_InferfaceBoard.ino index 891bdb3..b29f7bf 100644 --- a/FC_InferfaceBoard/FC_InferfaceBoard.ino +++ b/FC_InferfaceBoard/FC_InferfaceBoard.ino @@ -10,39 +10,47 @@ #define RcvErr "ER\r\n" #define MODE_DEBUG false -String demuxCMD(String command, String* rightPart); -int demuxNum(String rightPart, unsigned int data[]); -// Enter a MAC address and IP address for your controller below. -// The IP address will be dependent on your local network. -// gateway and subnet are optional: -byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x00 }; -IPAddress ip(192, 168, 20, 177); -IPAddress gateway(192, 168, 20, 1); -IPAddress subnet(255, 255, 255, 0); +// ========== ========== Periodic Flags +bool T_10ms = false; +bool T_20ms = false; +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; + +// ========== ========== Communication +// ---------- Ethernet + +// Ethernet Client +EthernetClient client; // SCPI defaults to port 5025 EthernetServer server(5025); -EthernetClient client; - // HTTP defaults to port 5025 EthernetServer web(80); unsigned long lastDataReceivedTime; unsigned long timeoutPeriod = 5000; // 타임아웃 시간 (5초) -bool busy = false; -bool connection = false; -char buffer[1024]; +bool State_eth = false; + + +// ---------- 485 +String Buf_485; +bool Wait_485; +int Wait_485_cnt; + +// ========== ========== Processing +// Read Datas int Size_AI = 16; int Values_AI[16]; int Size_PV = 8; int Values_PV[8]; -String Buf_485; -bool Wait_485; -int Wait_485_cnt; int msCnt = 0; unsigned long timer = 0; @@ -51,135 +59,107 @@ void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial.println("Start!"); - - TCPIP_setup(mac, ip, gateway, subnet); - - // scitech korea Library + + // modules setup (init.) + Ethernet_setup(); GPIO_setup(); MC9_setup(); // Timer set - MsTimer2::set(10, periodic_10ms); + MsTimer2::set(10, timer_10ms); MsTimer2::start(); - - // Report address - Serial.print("MAC>>"); - for (int i = 0; i < 6; i++) { - if (mac[i] < 16) { - Serial.print("0"); - } - Serial.print(mac[i], HEX); - if (i < 5) { - Serial.print(":"); - } - } - Serial.println(); - Serial.print("IP >>"); - Serial.println(Ethernet.localIP()); - } void loop() { + // wait for a new client: - webReponse(); client = server.available(); - - //Prcss_SV(); - //delay(100); + if (client) { + String Buf_eth; + String message; + String cmd; + String cmdData; + unsigned int data[32]; + int dataSize; + // check if client is connected Serial.println("Client Connected!!!"); // Do What Message Command while(client.connected()){ - int buffCnt = 0; - - // check for command byte - if (client.available() > 0) { - char c; - bool cr = false; - - String command; - String cmd; - unsigned int data[32]; - String message; - int dataSize; - - busy = true; - // Read message by byte - while ((c = client.read())) { - - // Read data until CR or LF - if((c != 13) && (c != 10)){ - command += c; - }else{ + // read data check + if(client.available() > 0) { + char c ;//= client.read(); + + while((c = client.read())) { + //If endwith CRLF + if((c == 10) && (Buf_eth.endsWith("\r"))){ + Buf_eth.remove(Buf_eth.length() - 1); //remove CR + message = Buf_eth; + Buf_eth = ""; break; + }else{ + Buf_eth += c; } } - - // -------------------- Process CMD -------------------- // - cmd = demuxCMD(command, &message); + // 데이터를 수신했으므로 타임아웃 타이머 초기화 + lastDataReceivedTime = millis(); + } + + // If data read + if(message != ""){ + cmd = demuxCMD(message, &cmdData); + message = ""; if(cmd=="AI"){ client.print(Prcss_AI()); }else if(cmd=="AO"){ - dataSize = demuxNum(message, data); + dataSize = demuxNum(cmdData, data); client.print(Prcss_AO(data, dataSize)); + }else if(cmd=="PV"){ client.print(Prcss_PV()); + }else if(cmd=="SV"){ - client.print(Prcss_SV()); + dataSize = demuxNum(cmdData, data); + client.print(Prcss_SV(data, dataSize)); }else if(cmd=="RS"){ - client.print(Prcss_RS(message)); + client.print(Prcss_RS(cmdData)); }//else if(cmd==""){ //} else{ client.print(cmd + " " + RcvErr); - - } - - - // Debug - if(MODE_DEBUG){ - //Serial.print("Received command: "); - //Serial.println(command); } + message = ""; + } + + // Debug + if(MODE_DEBUG){ + //Serial.print("Received command: "); + //Serial.println(command); + } - busy = false; - // 데이터를 수신했으므로 타임아웃 타이머 초기화 - lastDataReceivedTime = millis(); - - }// if end, client.available() - //Serial.println("end client available"); - - // 타임아웃 확인 + // check Timeout if (millis() - lastDataReceivedTime > timeoutPeriod) { Serial.println("Client Disconnected... (Timeout)"); client.stop(); } - + Periodic_run(); } Serial.println("Client Disconnected..."); - } - + Periodic_run(); } -void TCPIP_setup(byte mac[], IPAddress ip, IPAddress gateway, IPAddress subnet){ - mac[5] = ip[3] & 0xFF; - // initialize the ethernet device - Ethernet.begin(mac, ip, gateway, subnet); - // start listening for clients - server.begin(); - web.begin(); -} + void AnalogIn_Print(){ @@ -192,33 +172,3 @@ void AnalogIn_Print(){ -void webReponse(){ - EthernetClient webClient = web.available(); - if (webClient) { - Serial.println("Web client connected"); - while (webClient.connected()) { - if (webClient.available()) { - // 웹 브라우저에서 요청이 도착한 경우 - String request = webClient.readStringUntil('\r'); - //Serial.println(request); - webClient.flush(); - - // 웹 브라우저에 출력할 문구 작성 - String response = "HTTP/1.1 200 OK\r\n"; - response += "Content-Type: text/html\r\n\r\n"; - response += ""; - response += Prcss_AI(); - //response += "

Hello, World!

"; - response += ""; - - // 문구를 웹 브라우저로 전송 - webClient.print(response); - delay(1); - - // 클라이언트 연결 종료 - webClient.stop(); - } - } - } - -} \ No newline at end of file diff --git a/FC_InferfaceBoard/MC9.ino b/FC_InferfaceBoard/MC9.ino index e1db381..cb43b09 100644 --- a/FC_InferfaceBoard/MC9.ino +++ b/FC_InferfaceBoard/MC9.ino @@ -11,15 +11,18 @@ void MC9_setup(){ digitalWrite(RS485_OE_1, Rcv_485); } -void read_mc9_req(){ +void read_mc9_req(String address){ if(!Wait_485){ - String command = "10DRS,03,0011C7\r\n"; + String command = ""; + command += address; + command += "DRS,03,0011C7\r\n"; // Send request to return pv data digitalWrite(RS485_OE_1, Snd_485); delay(5); Serial1.print(command); Serial1.flush(); digitalWrite(RS485_OE_1, Rcv_485); delay(5); + Wait_485 = true; Wait_485_cnt = 0; } @@ -32,34 +35,39 @@ void read_mc9(int arr[], int size){ // Timeout code if(Wait_485){ Wait_485_cnt++; - if(Wait_485_cnt > 200){ // Timeout = periodic(10ms) x 200 = 2sec + if(Wait_485_cnt > 10){ // Timeout = periodic(10ms) x 10 = 10 msec Wait_485 = false; Wait_485_cnt = 0; } } // Receive pv data while(Wait_485 && (Serial1.available() > 0)) { - c = Serial1.read(); - Buf_485 += c; - Serial.print(c, HEX); - Serial.print(" "); + c = Serial1.read(); - if(c == '\n'){ + if((c == '\n') && (Buf_485.endsWith("\r"))){ + Buf_485.remove(Buf_485.length() - 1); //remove CR message = Buf_485; Buf_485 = ""; + Wait_485 = false; Wait_485_cnt = 0; } + else{ + Buf_485 += c; + } } - + // save pv if(message != ""){ - Serial.println(message); + for(int i = 0 ; i < size ; i++){ + //arr[i] = ???; + } } } void write_mc9(int arr[], int size){ - cli();//stop interrupts - Serial1.print("485 Write^^"); //Serial Write ADC_Value to RS-485 Bus - sei();//allow interrupts + digitalWrite(RS485_OE_1, Snd_485); delay(5); + 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 diff --git a/FC_InferfaceBoard/Processes.ino b/FC_InferfaceBoard/Processes.ino index c906066..5cc8bd4 100644 --- a/FC_InferfaceBoard/Processes.ino +++ b/FC_InferfaceBoard/Processes.ino @@ -1,13 +1,13 @@ +// String Prcss_AI(){ - String str = ""; - for (int i = 0; i < Size_AI; i++) { - char formattedNumber[5]; // 4자리 숫자 + 널 종료 문자 - sprintf(formattedNumber, "%04X", Values_AI[i]); // 4자리로 고정된 형식의 문자열 생성 - str += formattedNumber; // 형식화된 문자열 추가 - //str += String(AI_VALUES[i]); - str += ','; - } + + for (int i = 0; i < Size_AI; i++) { + char formattedNumber[5]; // 4자리 숫자 + 널 종료 문자 + sprintf(formattedNumber, "%04X", Values_AI[i]); // 4자리로 고정된 형식의 문자열 생성 + str += formattedNumber; // 형식화된 문자열 추가 + str += ','; + } str += RcvOK; return str; @@ -29,18 +29,23 @@ String Prcss_RS(String message){ } String Prcss_PV(){ + String str = ""; + + for (int i = 0; i < Size_PV; i++) { + char formattedNumber[5]; // 4자리 숫자 + 널 종료 문자 + sprintf(formattedNumber, "%04X", Values_PV[i]); // 4자리로 고정된 형식의 문자열 생성 + str += formattedNumber; // 형식화된 문자열 추가 + str += ','; + } - String str = "PV "; - digitalWrite(RS485_OE_1, Snd_485); - Serial1.print("485 Read!!"); //Serial Write ADC_Value to RS-485 Bus str += RcvOK; return str; } -String Prcss_SV(){ +String Prcss_SV(unsigned int data[], int dataSize){ String str = "SV "; - + write_mc9(data, dataSize); str += RcvOK; return str; diff --git a/FC_InferfaceBoard/TCPIP - Write Read.vi b/FC_InferfaceBoard/TCPIP - Write Read.vi index 5ea2f96..6973b41 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 c6f011b..e69de29 100644 --- a/FC_InferfaceBoard/Utils.ino +++ b/FC_InferfaceBoard/Utils.ino @@ -1,38 +0,0 @@ -String demuxCMD(String command, String* rightPart) { - - // "::"를 기준으로 문자열을 분리 - int separatorIndex = command.indexOf("::"); - String leftPart = command.substring(0, separatorIndex); - *rightPart = command.substring(separatorIndex + 2); - - leftPart.replace(" ", ""); - return leftPart; -} - - -int demuxNum(String rightPart, unsigned int data[]) { - - // 우측의 16진수 배열을 분리하여 추출 - const char* delimiter = ","; - int startIndex = 0; - int endIndex = rightPart.indexOf(delimiter); - int index = 0; - - while (endIndex >= 0) { - String hexValue = rightPart.substring(startIndex, endIndex); - // 16진수 문자열을 16진수 숫자로 변환하여 data 배열에 저장 - data[index] = strtoul(hexValue.c_str(), NULL, 16); - index++; - - startIndex = endIndex + 1; - endIndex = rightPart.indexOf(delimiter, startIndex); - } - - // 남은 마지막 16진수 배열 원소 처리 - String hexValue = rightPart.substring(startIndex); - data[index] = strtoul(hexValue.c_str(), NULL, 16); - index++; - - // 왼쪽 부분인 "ABC"을 반환 - return index; -} diff --git a/FC_InferfaceBoard/periodics.ino b/FC_InferfaceBoard/periodics.ino index 97c7cff..ce01890 100644 --- a/FC_InferfaceBoard/periodics.ino +++ b/FC_InferfaceBoard/periodics.ino @@ -1,34 +1,64 @@ -void periodic_10ms(){ - msCnt += 10; - - if(!busy){ - // Call a function every 10ms +// +void Periodic_run(){ + if(T_10ms){ read_analog(Values_AI, Size_AI); read_mc9(Values_PV, Size_PV); - - // Call a function every 50ms - if (msCnt % 20 == 0){ - - } + T_10ms = false; + } + if(T_20ms){ - // Call a function every 50ms - if (msCnt % 50 == 0){ - - } + T_20ms = false; + } + if(T_50ms){ - // Call a function every 100ms - if (msCnt % 100 == 0){ + T_50ms = false; + } + if(T_100ms){ - } + T_100ms = false; + } + if(T_200ms){ - // Call a function every 500ms - if (msCnt % 500 == 0){ - read_mc9_req(); - } + 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(); + T_1000ms = false; + } +} +void timer_10ms(){ + msCnt += 10; - // Call a function every 1000ms - if (msCnt > 1000){ - msCnt = 0; - } + T_10ms = true; + if (msCnt % 20 == 0){ + T_20ms = true; + } + if (msCnt % 50 == 0){ + T_50ms = true; + } + if (msCnt % 100 == 0){ + T_100ms = true; + } + if (msCnt % 200 == 0){ + T_200ms = true; } + if (msCnt % 500 == 0){ + T_500ms = true; + } + if ((msCnt+250) % 500 == 0){ + T_500ms_2 = true; + } + if (msCnt > 1000){ + T_1000ms = true; + msCnt = 0; + } + }