Closed zekageri closed 4 years ago
Isn't the response 8 bytes long? slaveAddress (1) + functionCode (1) + address (2) + data (2) + CRC (2)
size_t ModbusRequest06::responseLength() {
return 8;
}
Oh, and I would drop the s and the end of writeSingleHoldingRegisters
.
Am I autistic?
Oh, and I would drop the s and the end of
writeSingleHoldingRegisters
.Am I autistic?
Thats true. It's just one register. :'D But can it work? Oh and whats up with the multi registers? I tought that i have to write the low and the high bytes to the data. Like this:
// multireg addr funkc regH regL regDH regDL byD adatH adatL CRCH CRCL */
byte message[] = {0x0A, 0x10, 0x40, 0x32, 0x00, 0x01, 0x02, 0xFF, 0xFF, 0x91, 0x06};
I have a modbus io expander, and if i use the multi register like this:
uint8_t Slave_Address = 0xA;
uint16_t Start_Reg_Address = 0x4032;
uint16_t Reg_Count = 0x0001;
uint8_t Data_to_Write = 0x00;
modbus.writeMultHoldingRegisters(Slave_Address,Start_Reg_Address,Reg_Count,&Data_to_Write);
I want to write a 255 to all the output pins in a register but if i use it like this, i get half of the outputs on. How i supposed to write a low and a high byte with multi regs?
You're writing 1 register. One register is 2 bytes wide. So your Data_to_Write
should be 2 bytes long.
Try this:
uint8_t Slave_Address = 0xA;
uint16_t Start_Reg_Address = 0x4032;
uint16_t Reg_Count = 0x0001;
uint8_t Data_to_Write[2] = {0x00, 0x00};
modbus.writeMultHoldingRegisters(Slave_Address,Start_Reg_Address,Reg_Count,Data_to_Write);
So your data is an array of bytes (uint8_t). The array length has to be the number of bytes you're going to write. (number of bytes = number of registers x 2)
ModbusMessage.h
// write single holding registers
class ModbusRequest06 : public ModbusRequest {
public:
explicit ModbusRequest06(uint8_t slaveAddress, uint16_t address, uint16_t data);
size_t responseLength();
};
ModbusMessage.cpp
ModbusRequest06::ModbusRequest06(uint8_t slaveAddress, uint16_t address, uint16_t data) :
ModbusRequest(8) {
_slaveAddress = slaveAddress;
_functionCode = esp32Modbus::WRITE_HOLD_REGISTER;
_address = address;
_byteCount = 2; // 1 register is 2 bytes wide
add(_slaveAddress);
add(_functionCode);
add(high(_address));
add(low(_address));
add(high(data));
add(low(data));
uint16_t CRC = CRC16(_buffer, 6);
add(low(CRC));
add(high(CRC));
}
size_t ModbusRequest06::responseLength() {
return 8;
}
esp32ModbusRTU.h ...add declaration...
esp32ModbusRTU.cpp
bool esp32ModbusRTU::writeSingleHoldingRegister(uint8_t slaveAddress, uint16_t address, uint16_t data) {
ModbusRequest* request = new ModbusRequest06(slaveAddress, address, data);
return _addToQueue(request);
}
Usage
uint8_t Slave_Address = 0xA;
uint16_t Start_Reg_Address = 0x4032;
uint16_t Reg_Count = 0x0001;
uint8_t Data_to_Write[2] = {0x00, 0x00};
modbus.writeMultHoldingRegisters(Slave_Address,Start_Reg_Address,Reg_Count,Data_to_Write);
If it works, feel free to create a PR.
The multi reg write is working properly like this. Thank you for the suggestion. I don't tried the single register yet.
Oh, I mixed up multi and single. Should work both.
Can this be done just like this?
In ModbusMessage.cpp :
In ModbusMessage.h :
In esp32ModbusRTU.cpp :