[제품종류] IEC1000
[개발환경] Visual Studio 2008 C#
=============== 질 문 ===============SmartModbus를 사용하여 여러 device와 RS485를 통해 MODBUS 통신을 하고 있습니다.
System.Threading.Timer 객체를 사용하여 1.5초 마다 MODBUS read를 수행합니다. (ReadHoldingRegister 함수 사용)
→ SmartThread를 사용하여 구현했더니 너무 버벅거리는 문제가 있었습니다.
SmartButton의 Click 이벤트를 통해 MODBUS write를 수행하는 함수를 구현하였습니다. (WriteSingleRegister 함수 사용)
문제는 Click 이벤트와 System.Threading.Timer의 Tick 이벤트가 충돌되는 경우가 발생하여 원하는 대로 동작이 되지 않는 경우가 가끔씩 발생합니다.
이벤트의 실행 우선순위를 설정할 수 있는 방법이 있는지요?
- 구현 예시 -
private void form_Load(object sender, EventArgs e) {
// Initialize timer object
timer = new System.Threading.Timer(new TimerCallback(callBack), null, 0, 1500);
}
public void callBackFunction(object state) {
// Call callback function in UI thread
this.BeginInvoke(new MethodInvoker(repeatFunc));
}
public void repeatFunc() {
for (int idx = 0; idx < TEMP_NUM; idx++) {
modbusProtocol.SlaveAddress = tempID[idx];
eCode = modbusProtocol.ReadHoldingRegister(ADDR_PV, 2, out response);
if (eCode == SmartX.SmartModbus.EXCEPTIONCODE.SUCCESS) {
Array.Reverse(response);
current[idx] = Convert.ToDecimal(BitConverter.ToInt32(response, 0)) / (decimal)10.0;
}
eCode = modbusProtocol.ReadHoldingRegister(ADDR_SV, 2, out response);
if (eCode == SmartX.SmartModbus.EXCEPTIONCODE.SUCCESS) {
Array.Reverse(response);
target[idx] = Convert.ToDecimal(BitConverter.ToInt32(response, 0)) / (decimal)10.0;
}
}
}
private void setMotorSpeed(object sender, EventArgs e) {
setSpeed(Int32.Parse(((SmartX.SmartButton)sender).ButtonText));
}
public void setSpeed(int index) {
modbusProtocol.SlaveAddress = ID_MOTOR;
currentRPM = speedTable[index];
modbusProtocol.WriteSingleRegister(ADDR_SET_MOTOR_SPEED, speedTable[index]);
}
=============== 답 변 ===============
안녕하세요...
1. SmartThread에서 WorkThread를 사용할 경우 문제가 안될 듯합니다. 아주 빠른 비 UI코드의 실행을 처리할 수 있습니다. 아마도 WorkThread에서 Interval Time 처리와 관련된 문제일듯 합니다.
2. 만약 System.Threading.Timer를 사용하여 개선되었다고 한다면 이는 싱글 코어(단일CPU)환경에서 CPU의 처리가 많을 경우 기본적으로 System.Threading.Timer은 인터벌이 증가되는 문제가 생깁니다. 아마도 그냥 인터벌 값이 늘어나서 처리되는지도 확인이 필요합니다. 여기서 문제가 안된다 하면 SmartThread에서 WorkThread를 사용하셔도 문제가 없습니다.
3. 버튼 클릭이 충돌되는 경우 우선순위는 변경해서 해결하수는 없으며 다만 이러한 경우 현제 ModBus의 데이터 처리 중 인지 확인할 수 있는 Flag를 만들어 처리하는 것이 가장 간단할 것으로 생각됩니다. 다른 방법으로는 Write 데이터 Queue를 만들어 처리하셔도 됩니다.
- 감사합니다.