Here is the piece of code that I use to read a few VFD modbus holding registers.
I use this library… I have no made any modification to the code: Github user 4-20ma “Modbus Master”
see the modbus master files inside src folder, notice I copy crc16.h and word.h to the same folder.
#include <ModbusMaster.h>
/*!
We're using a MAX485-compatible RS485 Transceiver.
Rx/Tx is hooked up to the hardware serial port at 'Serial'.
The Data Enable and Receiver Enable pins are hooked up as follows:
*/
#define MAX485_DE A3
#define MAX485_RE_NEG A2
#define CT_VFD(m,n) (m *100+ n-1) // formula to acces VFD registers (not used in this example)
// Comment this out if you don't want serial output
#define DEBUGON 1
// Transmission delay between modbus calls
#define XMITDELAY 2000
// 0 for 0-based, 1 for 1-based numbering
#define BASED_NUMBERING 1
/*********
* Retreives holding register data while handling device sleeping conditions
**********/
// instantiate ModbusMaster object
ModbusMaster node;
#define reg_qty 11 (not used in this example)
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
void setup()
{
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
// Modbus communication runs at 115200 baud
Serial.begin(19200);
Serial1.begin(19200);
// Modbus slave ID 1, Serial1 on the Particle Photon
node.begin(1, Serial1);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
bool state = true; // (not used in this example)
void loop()
{
uint16_t data[6];
getHoldingRegisterData( 407, 1, data); //symetrical current limit in % 0.1 dec place
delay(1000);
getHoldingRegisterData( 506, 1, data); //motor rated frecuency in hz 0.1 dec place
}
bool getHoldingRegisterData(uint16_t registerAddress, uint16_t regSize, uint16_t* data){
uint8_t j, result;
if(DEBUGON){
Serial.print(F("Reading register: "));
Serial.print(registerAddress);
Serial.print(F(" regSize: "));
Serial.print(regSize);
Serial.print(F(" sizeof(data): "));
Serial.print(sizeof(&data));
Serial.print(F(" XMITDELAY: "));
Serial.println(XMITDELAY);
Serial.println("");
}
// Delay and get register data.
result = node.readHoldingRegisters(registerAddress-BASED_NUMBERING, regSize);
delay(XMITDELAY);
// LT is sleeping, ping it a couple more times.
if(result ==node.ku8MBResponseTimedOut){
if(DEBUGON){
Serial.println(F("LT: Response timed out. Trying again. "));
}
int i =0;
while(i < 2){
result = node.readHoldingRegisters(registerAddress-BASED_NUMBERING, regSize);
delay(XMITDELAY);
if(DEBUGON){
Serial.printlnf("LT: Timeout iteration# %d. ", i);
}
if(result == node.ku8MBResponseTimedOut){
if(DEBUGON) Serial.println(F("LT: Failed. Response timed out. Adjust the XMITDELAY and/or ku8MBResponseTimeout? "));
}
else break;
i++;
}
}
if (result == node.ku8MBSuccess) {
if(DEBUGON){
Serial.print(F("LT: Success, Received data: "));
}
for (j = 0; j < regSize; j++) {
data[j] = node.getResponseBuffer(j);
if(DEBUGON){
Serial.print(data[j], DEC);
Serial.print(F(" "));
}
}
if(DEBUGON){
Serial.println("");
}
node.clearResponseBuffer();
node.clearTransmitBuffer();
return true;
}
else{
if(DEBUGON){
Serial.print(F("Failed, Response Code: "));
Serial.println(result, HEX);
}
}
node.clearResponseBuffer();
node.clearTransmitBuffer();
return false;
}