modbus slow write
-
Hi
I have a Delta DT320 controller which I want to communicate with it using modbus protocol.I have prepared a program using qml (Qt 5.12.2) to read and write the registers.
I have no problem with reading. However, after some time, writing the set point register happens with some delays which is commulative. I am sure the writeUnit is changed with the new set point in real time. But the controller set point changes with a large delay.
The problem is not with the device, because when I reset the controller or unplugged/re-plugged the ch341 RS485 to USB converter without closing the program the problem is still there. But when I re-run the program the delay resets to zero and writing is done in real time. Thus, There should be some problems with sending the commands!
It is important to say, I have a Run/Stop switch in qml, when I turn it on and off again the delay increases. This switch aims to turn on and off some other switches in the program. For example after 5 times toggling the switch the delay is about 30 seconds. But there is no data loss in serial sending.
The picture of program interface is attached. The mentioned switch is on top left corner. pic.png
My guess is that there should be a problem with serial buffer sending!
In this line of the code:if (auto *reply =mymodbusdevice.sendWriteRequest(writeUnit,1)){ ...}
But I'm not sure
Any help is greatly appreciated.
Please find below the codes.
the switch in qml:Switch{ id:runStop_switch //text: qsTr("Switch") x:3//temp_box.x y: -5//temp_box.y checked: false signal mytoggle //onMytoggle: indicator: Rectangle { implicitWidth: 40 implicitHeight: 20 x:runStop_switch.leftPadding y:parent.height / 2 - height / 2+2 radius: 13 opacity: 0.9 color: runStop_switch.checked ? "yellow" : "#ffffff" border.color: runStop_switch.checked ? "#17a81a" : "#cccccc" Rectangle { x: runStop_switch.checked ? parent.width - width : 0 y:0 width: 20 height: 20 radius: 23 color: runStop_switch.down ? "#cccccc" : "#ffffff" border.color: runStop_switch.checked ? (runStop_switch.down ? "#17a81a" : "#21be2b") : "#999999" } } contentItem: Text { text: runStop_switch.text font: runStop_switch.font opacity: enabled ? 1.0 : 0.3 color: runStop_switch.down ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter leftPadding: runStop_switch.indicator.width + runStop_switch.spacing } //onToggled: { onCheckedChanged: { if (runStop_switch.checked==true){ modbus_connection.Device_connect(); rusStop_label.text="Run" modbus_connection.Read(); temp_switch.checked=false temp_switch.toggle() //runStop_switch.toggle.connect(temp_switch.toggle) motor0_switch.checked=false motor0_switch.toggle() motor1_switch.checked=false motor1_switch.toggle() motor2_switch.checked=false motor2_switch.toggle() motor3_switch.checked=false motor3_switch.toggle() motor4_switch.checked=false motor4_switch.toggle() motor5_switch.checked=false motor5_switch.toggle() motor6_switch.checked=false motor6_switch.toggle() if(motor0_switch.checked==true){ motor0.value=motor0.mymotor0_val modbus_connection.setCell0(motor0.value) //rdioBut_pump.checked=false } if(motor1_switch.checked==true){ motor1.value=motor1.mymotor1_val modbus_connection.setCell1(motor1.value) // rdioBut_pump.checked=false } if(motor2_switch.checked==true){ motor2.value=motor2.mymotor2_val modbus_connection.setCell2(motor2.value) // rdioBut_pump.checked=false } if(motor3_switch.checked==true){ motor3.value=motor3.mymotor3_val modbus_connection.setDuall_cell(motor3.value) // rdioBut_pump.checked=false } if(motor4_switch.checked==true){ motor4.value=motor4.mymotor4_val modbus_connection.setCell4(motor4.value) // rdioBut_pump.checked=false } if(motor5_switch.checked==true){ motor5.value=motor5.mymotor5_val modbus_connection.setCell5(motor5.value) // rdioBut_pump.checked=false } if(motor6_switch.checked==true){ motor6.value=motor6.mymotor6_val modbus_connection.setCell6(motor6.value) // rdioBut_pump.checked=false } pump_switch.checked=false pump_switch.toggle() if(pump_switch.checked==true){ if (pump.mypump_val<150) pump.value=150 else pump.value=pump.mypump_val modbus_connection.setPump(pump.value) // rdioBut_pump.checked=false } status_timer.stop() modbus_connection.setStatus("System is running") status_bar_text.counter=3 status_timer.start() modbus_connection.setStatus(" ") //textField_setPnt.value=modbus_connection.stPnt*100; // console.log("Run ") } else{ // modbus_connection.setStatus(" ") modbus_connection.Disconect(); temp_switch.checked=true temp_switch.toggle() motor0_switch.checked=true motor0_switch.toggle() if(motor0_switch.checked==false){ motor0.value=0 // rdioBut_pump.checked=false } motor1_switch.checked=true motor1_switch.toggle() if(motor1_switch.checked==false){ motor1.value=0 // rdioBut_pump.checked=false } motor2_switch.checked=true motor2_switch.toggle() if(motor2_switch.checked==false){ motor2.value=0 // rdioBut_pump.checked=false } motor3_switch.checked=true motor3_switch.toggle() if(motor3_switch.checked==false){ motor3.value=0 // rdioBut_pump.checked=false } motor4_switch.checked=true motor4_switch.toggle() if(motor4_switch.checked==false){ motor4.value=0 // rdioBut_pump.checked=false } motor5_switch.checked=true motor5_switch.toggle() if(motor5_switch.checked==false){ motor5.value=0 // rdioBut_pump.checked=false } motor6_switch.checked=true motor6_switch.toggle() if(motor6_switch.checked==false){ motor6.value=0 // rdioBut_pump.checked=false } pump_switch.checked=true pump_switch.toggle() if(pump_switch.checked==false){ pump.value=0 // rdioBut_pump.checked=false } status_bar_text.counter=3 status_timer.start() rusStop_label.text="Stop" status_timer.stop() modbus_connection.setStatus("System has been stopped") status_timer.stop() // console.log("Stop") } } Component.onCompleted: { // runStop_switch.toggle.connect(pump_switch.toggle) } }
The function in cpp:
void Modbus::setStPnt(QString value) { set_pnt_update_flag=0; QString mysetpoint=value; qDebug()<<"mysetpoint=:"<< mysetpoint; // delay(0.2); QString new_set=mysetpoint; float SP=new_set.toFloat()*10; int16_t sp2=int16_t(SP); QModbusDataUnit writeUnit = writeRequest(); // qDebug()<<"writeRequest=:"<< writeUnit; QModbusDataUnit::RegisterType table = writeUnit.registerType(); for (uint i = 0; i < writeUnit.valueCount(); i++) { writeUnit.setValue(i,sp2); if (auto *reply =mymodbusdevice.sendWriteRequest(writeUnit,1)) { if (!reply->isFinished()) { connect(reply, &QModbusReply::finished, this, [this, reply]() { if (reply->error() == QModbusDevice::ProtocolError) { mystatus=tr("Write response error: %1 (Mobus exception: 0x%2)") .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16); } else if (reply->error() != QModbusDevice::NoError) { mystatus=tr("Write response error: %1 (code: 0x%2)"). arg(reply->errorString()).arg(reply->error(), -1, 16); } reply->deleteLater(); }); } else { // broadcast replies return immediately // reply->deleteLater(); delete reply; } } else { mystatus=tr("Write error: ") + mymodbusdevice.errorString(); } }
}```
-
@imhs
I figured it out!
The problem was in the read function function where I call it every time toggling the run switch.
Inside that function there is a timer which aims to read the registers and update the UI. Every time I call that function a new timer was generated. Therefore after sometime many timers was running in parallel which caused the problem.
Take care about timers!