Modbus communication with a Automation Direct GS2 VFD

I am using a Arduino nano to control a constant pressure system. A PID controller is on the nano and I am trying to get the output sent to my VFD via RS485 Modbus. I keep getting an error on the VFD that the data value received in the message is incorrect.

This is the VFD manual GS2 Series Drives User Manual

I am using the ModbusMaster.h library

I copied my modbus code from this website: RS-485 MODBUS Serial Communication with Arduino as Master

as I thought I just need to send a simple 4 digit number representing the frequency. Example 1255 - the drive adds an implied decimal point, 125.5HZ.

my code

node.writeSingleRegister(0x91A,550); //Writes the frequency to the drive

0x91a being the address on the VFD and 550 being 55.0Hz

I also tried changing the 550 to hexadecimal, but that didn't work either.

Before I was using 42331 as the address, which is the Modbus decimal address, but then I got the error "incorrect address" so I switched to "0x91a", now I get the error incorrect data value.

I am thinking I need to processes the "550" before sending it but I am not sure how.

In the future I also want to read data from the drive, once I get this modbus thing figured out.

I am new to programing, I can do basic code for the arduino, this is getting a little deeper and I need some help.

First: post your complete code! (don't forget the code tags, that's the </> button in the editor)

According to the manual the register 0x09A1 holds the "Serial Comm Speed Reference", are you trying to change that parameter or something else?

The Modbus register addressing is sometimes quite special if the manual is written for PLCs. As these are not freely programmable the have introduced a special register numbering. the range above 40000 is used for holding registers but to actually address the register you have to subtract 40001 from the register number. The octal representation hints in the same direction. Try to use 2330 as the register number.

Ok I got it figured out, the problem was in the VFD. I had to have the "source of operation command" and "source of frequency command" set, to run from RS485 commands.

Here is the code I have. Maybe somebody else will find it useful.

/********************************************************
 * PID control for constant pressure system

 ********************************************************/
#include <ModbusMaster.h>
#include <PID_v1.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);

#define MAX485_DE      3
#define MAX485_RE_NEG  2

const int pressureinput = A2;  // Pressure sensor

float frequency = 0.0;
int rawpress = 0;
int pressure = 0;
int fff = 0;
int df = 0x0;

ModbusMaster node;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
 
double Kp=5, Ki=5, Kd=0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);


void setup()
{ 
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  
  
  pinMode(A2, INPUT); // pressure sensor
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  Serial.begin(9600, SERIAL_8O1);

  node.begin(1, Serial);            //Slave ID as 1
  
  node.preTransmission(preTransmission);         //Callback for configuring RS-485 Transreceiver correctly
  node.postTransmission(postTransmission);

  lcd.init();  //initialize the lcd
  lcd.backlight();  //open the backlight 

  lcd.setCursor ( 0, 0 );            
  lcd.print("Pressure    lbs");
  lcd.setCursor ( 0, 2 );            
  lcd.print("Frequency     Hz");

/***************/

  //initialize the variables we're linked to

  

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
 
 

  Setpoint = 55;                            //Lbs of pressure

  
  pressure= map(analogRead(pressureinput), 0, 1023, 0, 100 ); 

  Input = pressure;
  {
  myPID.Compute();
  //analogWrite(PIN_OUTPUT, Output);
  

   df = map(Output, 0, 255, 0x0, 0x258);

  //delay(100);
  
  
   node.writeSingleRegister(0x091a, df);        //Writes the frequency to the drive
 
 // node.writeSingleRegister(0x091c,00);        //Sets the drive to forwards

   if (pressure < 50 ){
   node.writeSingleRegister(0x091B, 0x1);        //Turns the drive on
  }

   if (pressure > 60 ){
   node.writeSingleRegister(0x091B, 0x0);        //Turns the drive 0ff
  }


  fff =map(Output, 0, 255, 0, 600 );

 float frequency = fff / 10.0;

  lcd.setCursor ( 9, 0 );            
  lcd.print(pressure);
  lcd.setCursor ( 10, 2 );            
  lcd.print(frequency,1);
}
}