Using 485 for QmodbusServer library
-
Hello Everyone,
I am using the QModbusServer library for implementation of slave device. I have tested this library and receive signal from the master device. However there is an issue regarding 485. Since it is a half duplex protocol, we need to switch the mode using GPIO pin.
Using the sample application which is given here . I am using imx6ul series embedded device with a custom Yocto build .
I am receiving correct signal from the master, I am not able to respond because I am not able to switch 485 into transmit mode.
How do I modify this code for 485 communication.
Regards, -
@Chai18 said in Using 485 for QmodbusServer library:
because I am not able to switch 485 into transmit mode
Why not? What happens?
-
@Chai18 said in Using 485 for QmodbusServer library:
where in the code do I switch the GPIO pin?
I would say before you respond
-
@jsulm Ok, let me rephrase it . QMobusRtuSerial is handling low level serial communication. The class is emitting a signal whenever it receives a frame. Is there a way to modify this behaviour.
In a nutshell where exactly in the code do I put my GPIO pin switch code. -
Maybe you can override QModbusServer::processRequest() and do all work there.
-
Hi @Chai18 Did you find any solution ? I have a similar issue but in the client side (QModbusClient) , this is my function to write data to the holding registers , but I'm all the time getting the response timeout, and master is actually handling incoming requests and send appropriate responses automatically.
void Serial::writeData(int start, const QList<quint16> &holdingRegisters) { if (!modbusDevice) return; startAddress = start; numberOfEntries = holdingRegisters.size(); // Switch to Transmit Mode switchGPIO->setValue(true); // enables TX QModbusDataUnit writeUnit = writeRequest(); QModbusDataUnit::RegisterType table = writeUnit.registerType(); for (qsizetype i = 0, total = writeUnit.valueCount(); i < total; ++i) { const auto addr = i + writeUnit.startAddress(); if (table == QModbusDataUnit::Coils) writeUnit.setValue(i, m_coils[addr]); else writeUnit.setValue(i, holdingRegisters[addr]); } if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, serverAddress)) { if (!reply->isFinished()) { QModbusDevice::connect( reply, &QModbusReply::finished, this, [this, reply]() { // Switch back to Receive Mode usleep(1000); // Small delay before switching switchGPIO->setValue(false); // Enable RX mode const auto error = reply->error(); if (error == QModbusDevice::ProtocolError) { qDebug() << "Write response error:" << reply->errorString() << "(Modbus exception:" << reply->rawResult().exceptionCode() << ")"; } else if (error != QModbusDevice::NoError) { qDebug() << "Write response error:" << reply->errorString() << "(code: 0x" << QString::number(error, 16) << ")"; } reply->deleteLater(); }); } else { qDebug() << "Write error: " << reply->errorString(); reply->deleteLater(); } } else { qDebug() << "Write error: " << modbusDevice->errorString(); switchGPIO->setValue(false); // Ensure RX mode is enabled on failure } }
Thanks in advance