ReadHolding register by Arduino uno

Hello Experts,

I am new on Arduino platform, I want to read two holding register starting address 40033.
I have Arduino Uno and RS485 TTL converter. but data cant read.
Below is sketch i am using:

#include <ModbusMaster.h>
#include <SoftwareSerial.h>
//#include <AltSoftSerial.h>
// Construct software serial object for Modbus/PC
#if defined(ARDUINO_AVR_UNO)
const int SSRxPin = 10; // Recieve pin for software serial
const int SSTxPin = 11; // Send pin for software serial
SoftwareSerial SoftSerial(SSRxPin, SSTxPin);
#else
// This is just a assigning another name to the same port, for convienence
// Unless it is unavailable, always prefer hardware serial.
HardwareSerial* SoftSerial = &Serial1;
#endif

#define MAX485_DE 3
#define MAX485_RE_NEG 2

// instantiate ModbusMaster object
ModbusMaster node;

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);

// Turn On Main/Hardware Serial Port
Serial.begin(9600);

// Turn on Soft serial port

#if defined (ARDUINO_AVR_UNO)
SoftSerial.begin(9600);
// NOTE: Software serial only supports 8N1
#else
Serial1.begin(9600, SERIAL_8E1);
#endif

// Start the Modbus instance with Modbus slave ID 10 and Hardware Serial port
node.begin(10, SoftSerial);

// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}

void loop()
{
uint8_t result;
uint16_t data[6];

// Read 02 registers starting at 40033)

result = node.readHoldingRegisters(0x33,2);
if (result == node.ku8MBSuccess)
{
Serial.println("Success");
Serial.println(node.getResponseBuffer(0x00));
Serial.println(node.getResponseBuffer(0x01));

}
else
{
Serial.println(" Failed ");
}
delay(1000);
}

Please help me .

Have you tried 33 decimal as the address, rather that 0x33? I seem to recall that the address, i.e. 40033 is in decimal.

Dear Markd833
Yes I have checked with 40033 and 33 as starting address but no data.

Is your Modbus slave actually residing at address 10 ?

That is not a very common situation. The demo code is also quite confusing with all the different serial port definitions. It would be helpful to provide a link to where you found this code. It would also help if you provided a link to whatever the slave device is, otherwise we can only guess as to what is right and wrong in the code.

As is, we can only see one side of what is a pair of devices. We have no idea of what the slave device hardware actually is and what its modbus behaviors are. The more info you provide increases the likelihood someone can help.

Finally, your code needs to be nested in code tags (the </> icon) so it shows up as:

Your code here

@fpramanik, your topic has been moved to a more suitable location on the forum; this has nothing to do with Avrdude, stk500 or Bootloader.

Please edit your opening post, select all code and click the </> button to apply code tags and next save your post. It makes it easier to read, easier to copy and prevents the forum software from incorrect interpretation of the code.

Please spend some time reading How to get the best out of this forum; it contains useful information ( e.g. about code tags :wink: ).

To which pins on the Uno is the RS485 connected?

@ [WattsThat]
Yes My Modbus Slave Address is 10, 8N1.
I have marge the code which took from two different site and edited. Because I need to send the read data to PC which read by Arduino from slave. As I know Arduino Uno has only one hardware serial, I will use it by USB or pin 0,1.
Thats why I am trying to use soft serial port on Pin10, 11 and DE and RE on Pin 2,3.

Please see my code below:

#include <ModbusMaster.h>
#include <SoftwareSerial.h>
//#include <AltSoftSerial.h>
// Construct software serial object for Modbus/PC
#if defined(ARDUINO_AVR_UNO)
const int SSRxPin = 10; // Recieve pin for software serial 
const int SSTxPin = 11; // Send pin for software serial 
SoftwareSerial SoftSerial(SSRxPin, SSTxPin);
#else
// This is just a assigning another name to the same port, for convienence
// Unless it is unavailable, always prefer hardware serial.
HardwareSerial* SoftSerial = &Serial1;
#endif

#define MAX485_DE      3
#define MAX485_RE_NEG  2

// instantiate ModbusMaster object
ModbusMaster node;

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);

  // Turn On Main/Hardware Serial Port
  Serial.begin(9600);
  
    // Turn on Soft serial port
#if defined (ARDUINO_AVR_UNO)
    SoftSerial.begin(9600);
    // NOTE:  Software serial only supports 8N1
#else
    Serial1.begin(9600, SERIAL_8E1);
#endif
   
  // Start the Modbus instance with Modbus slave ID 10 and Hardware Serial port
  node.begin(10, SoftSerial);
  
  // Callbacks allow us to configure the RS485 transceiver correctly
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop()
{
  uint8_t result;
  uint16_t data[6];
  
  // Read 02 registers starting at 40033)

   result = node.readHoldingRegisters(33,2);
  if (result == node.ku8MBSuccess)
  {
    Serial.println("Success");
    Serial.println(node.getResponseBuffer(0x00));
    Serial.println(node.getResponseBuffer(0x01));
                 
  }
  else
  {
    Serial.println(" Failed ");
}
delay(1000);
}

I am using Pin 10, 11 as RX TX and 3,2 as DE, RE.

Now I Can read Data from slave.
Thank all of you to support.

Great. Can you post your final solution?

Under each reply is a solution checkbox; you can tick the one for the most useful reply (can be your own) to let others know that a solution was provided / your problem was solved.

My final code for reading data from slave:

#include <ModbusMaster.h>
#include <SoftwareSerialParity.h>
// Construct software serial object for Modbus/PC

const int SSRxPin = 10; // Recieve pin for software serial 
const int SSTxPin = 11; // Send pin for software serial 
SoftwareSerialParity SoftSerial(SSRxPin, SSTxPin);
#define MAX485_DE     9
#define MAX485_RE_NEG  8

// instantiate ModbusMaster object
ModbusMaster node;

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);

  // Turn On Main/Hardware Serial Port
  Serial.begin(9600,SERIAL_8N1);
 // Serial1.begin(9600,SERIAL_8E1);
    // Turn on Soft serial port

    SoftSerial.begin(9600,EVEN);
    // NOTE:  SoftwareSerial only supports 8N1
    // NOTE: SoftwareSerialParity library support all parity
 
  // Start the Modbus instance with Modbus slave ID 10 and Soft Serial port
  node.begin(10, SoftSerial);
  
  // Callbacks allow us to configure the RS485 transceiver correctly
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

void loop()
{
 
  uint8_t j, result;
  uint16_t data[2];
  
  // slave: read (2) 16-bit registers starting at register 33 to RX buffer
  result = node.readHoldingRegisters(33, 2);
  
  // do something with data if read is successful
  if (result == node.ku8MBSuccess)
  {
    for (j = 0; j < 2; j++)
    {
      data[j] = node.getResponseBuffer(j);
    }
   Serial.print(data[0]);
  }
 SoftSerial.flush();
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.