MAX 485 & ModbusMaster - Basic Guide

This is like my 5th post or something, but I wanted to give back. I didn't see a "guides" section and this doesn't really meet many standards in way of a guide, but I thought it could really help someone get started, especially REALLY new people.

Youtube video showing physical hookup:

Excellent post with schematic:

Modbus Master Library:
http://www.arduino.cc/playground/Code/ModbusMaster

Code:

#include <ModbusMaster.h>


// instantiate ModbusMaster object as slave ID 2
// This is how to set the serial port, 3 is serial # and 2 is the SLAVE ID of the node
ModbusMaster node(3,2);
const int txRxPin = 4;
int txState = LOW;


void setup()
{
  // initialize Modbus communication baud rate
  node.begin(19200);
  pinMode(txRxPin, OUTPUT);
}


void loop()
{
//creating a counter that transmits "i" 
 static uint32_t i;
  uint8_t j, result;
  uint16_t data[6];
  
  i++;

  txState = HIGH;
  digitalWrite(txRxPin, txState);
  // slave: write TX buffer to (2) 16-bit registers starting at register 0
  result = node.writeMultipleRegisters(0, 2);
  
  

}

Essentially this code shows you how to transmit over modbus a 32bit int

Looks pretty simple, better than I would have thought for Modbus but I guess all the clever stiff is in the library.


Rob

EDIT : The below could be false... checking...

To add receive capability to MAX485 use this link to modify your modbusmaster.cpp file (file attached)

    // code edited to work with MAX485:
  // transmit request
  UCSR0A=UCSR0A |(1 << TXC0);  
  Serial.flush();
  digitalWrite(3, HIGH);

  for (i = 0; i < u8ModbusADUSize; i++)
  {
#if defined(ARDUINO) && ARDUINO >= 100
    MBSerial.write(u8ModbusADU[i]);
#else
    MBSerial.print(u8ModbusADU[i], BYTE);
#endif
  }
  while (!(UCSR0A & (1 << TXC0)));
  digitalWrite(3, LOW);
  // --

  u8ModbusADUSize = 0;

ModbusMaster.cpp (25.3 KB)

Hi

I am newbie in arduino. I read this topic but still I do not know how to use a 0x05 - Write Single Coil function. Could anyone please explain, how to send (for example 01 05 00 00 FF 00 8C 3A) the commands using the ModbusMaster library after the condition in the program?

Zabaat good job. Have known tons of info from you .Thanks

Hey, i must send to PowerMeter a command in modbus, but i can't use ModbusMaster Library.

This is the command:
Device Addr : 0x01
Function : 0x03
MSB 1 Word Addr : 0x03
LSB 1 Word Addr : 0x25
Words number MSB: 0x00
Words number LSB: 0x04
CRC 16 MSB: 0x55
CRC 16 LSB: 0x86

Thank you.

Hello There,

I'm having a difficulty on reading the Input Register values from SELEC MFM384-C Energy meter which uses Modbus protocol and RS-485 communication standard. I used your library for this.

Arduino compatible MAX485 chip built in RS-485 module was used to establish the RS-485 connection.

To check the input from the energy meter, I tried to get the input of V1N. (I've attached the datasheet of Energy meter with this post)

Here is the code I tried to get the 16 bit reading from register address starting from 30000 with the length of 2.

#include <ModbusMaster.h>

//ID = 0
//Serial1 (Tx1, Rx1)
ModbusMaster node(1, 0);


void setup()
{
  node.begin(9600);
  Serial.begin(9600);
}


void loop()
{
  static uint32_t i;
  uint8_t j, result;
  uint16_t data[6];

  i++;


  result = node.readHoldingRegisters(30000, 2);

  // do something with data if read is successful
  if (result == node.ku8MBSuccess)
  {
    for (j = 0; j < 6; j++)
    {
      data[j] = node.getResponseBuffer(j);
      Serial.print(data[j]);
    }
    Serial.println();
  }

}

I've used Serial1 for Modbus and Serial0 for Serial monitor.
PIN configuration:
Tx to DI
Rx to RO
DE & RE are interconnected with a jumper and and connected to PIN 3

I'm net getting any serial monitor outputs.

I checked the source code from the library, and couldn't find a trigger on how this works. Please kindly help me to solve this.

Thanking you in advance :slight_smile:

OP_MFM384_MFM384-C_OP347-V05.pdf (851 KB)