Modbus RS485 how to send command

Hello, I'd like to send modbus command with this library, but I don't know how to do it: GitHub - emelianov/modbus-esp8266: Most complete Modbus library for Arduino. A library that allows
I'd like to send (MASTER - esp8266 nodemcu, SLAVE - board with relays -> SLAVE_ID = 2) this command: 0x0100 to this 0x0001 accumulator. I use max485 module.
I'd like to do it with these libriaes, but they don't work with esp8266 only with arduino.

<ArduinoRS485.h> 
<ArduinoModbus.h>

this is example command to turn on the relay 1 with using these libraies above (slave id = 2):

ModbusRTUClient.holdingRegisterWrite(2,0x0001,0x0100);
//slave id: 2
//relay number one: 0x0001 
//turn on relay: 0x0100 (256) 

Would you help me how to send it with modbus-esp8266 library? I haven't found any tutotrial on youtube how to do it ;/

My code:

#include <ModbusRTU.h>
ModbusRTU mb;
#include <SoftwareSerial.h>
int DE_RE = 4; //D4  (02) For MAX485 chip
int TX = 15; // D7 (13), D8 (15)      RX, TX 
int RX = 13;
#define SLAVE_ID 2
SoftwareSerial S(RX, TX); // (RX , TX)

bool cbWrite(Modbus::ResultCode event, uint16_t transactionId, void* data) {
  Serial.printf_P("Request result: 0x%02X, Mem: %d\n", event, ESP.getFreeHeap());
  return true;
}

void setup() {
  Serial.begin(115200);
  S.begin(9600, SWSERIAL_8N1);
  mb.begin(&S, DE_RE); //Assing Software serial port to Modbus instance for MAX485 chip having DI,DE,RE,RO Pin at TTL side
  mb.master(); //Assing Modbus function as master

}

void loop() {
  if (!mb.slave()) {
    mb.readHreg(SLAVE_ID, 0x0001, 0x0100, 1 , cbWrite);  //(SlaevID,Address,Buffer,Range of data,Modus call)
    
  }
  mb.task();
  delay(1000);
  yield();
}

Have you tried any of the examples that are part of that library? A quick look on github shows that there is a modbus RTU master example that checks for an ESP8266.

I dont really understand what this do (what arguments should be there and what function to send command to the slave.)

#include <ModbusRTU.h>
#define SLAVE_ID 2
#if defined(ESP8266)
 #include <SoftwareSerial.h>
 // SoftwareSerial S(D1, D2, false, 256);

 // receivePin, transmitPin, inverse_logic, bufSize, isrBufSize
 // connect RX to D2 (GPIO4, Arduino pin 4), TX to D1 (GPIO5, Arduino pin 4)
 SoftwareSerial S(13, 15);
#endif

int DE_RE = 4; //D4  (02) For MAX485 chip
ModbusRTU mb;

bool cbWrite(Modbus::ResultCode event, uint16_t transactionId, void* data) {
#ifdef ESP8266
  Serial.printf_P("Request result: 0x%02X, Mem: %d\n", event, ESP.getFreeHeap());
#else
  Serial.print("Request result: 0x");
  Serial.print(event, HEX);
#endif
  return true;
}

void setup() {
  Serial.begin(115200);
 #if defined(ESP8266)
  S.begin(9600, SWSERIAL_8N1);
  mb.begin(&S, DE_RE);
  mb.master();
#endif
}


void loop() {
  if (!mb.slave()) {
    mb.writeHreg(SLAVE_ID, 0x0001 ,0x0100 , cbWrite);
  }
  mb.task();
  yield();
}

MAX485 is a 5v device.
Are you using a level shifter?

Can you test with some UNOs or NANOs?

I followed this tutorial: ESP8266 Modbus RTU communication with Energy meter EM6400NG - YouTube and this guy power the max485 module with 3,3V and he uses pins from the esp8266. Soon I;; upload my schematic to this and gonna try with nano.

That video has both ends powered at 3v3

He says if one end needs 5v you have to use some sort of level shifter if you want to use 3v3 on another point.

I guess there is a question if your problem is hardware or software.

1 Like

I got it wired like this.
edit: So I got to power max485 from esp's 3v3 pin when I power the esp8266 through VIN pin with 5V?
NEW SCHEMATIC 3V3 POWER MAX485 CHIP:


edit: I suppose that I can power the esp8266 with 5V with VIN pin, but i see that it requires 7-12V or 5V from USB, so I can't power it with 5V from 5V converter? Weird.