RS485 communication

I am currently struggling with setting up the communication with my DFRobot sensor (DFRobot/SEN0438 - EN.pdf at master · May-DFRobot/DFRobot · GitHub)
and my ESP32 with the library ModbusMaster (GitHub - 4-20ma/ModbusMaster: Enlighten your Arduino to be a Modbus master). I think I already found one problem with the library and thats it that the sensor is using 8bit registers and the library 16bit registers. But I could be wrong because I am not the best.
Maybe someone can tell me how I can solve the problem?

Your ESP32 is 3.3v..
What adapter are you using and how is it wired??
Are you just getting, no response??

all modbus regs are 16 bits..
it's something else..

good luck.. ~q

And you determined that because the data sends a register value as a high byte and a low byte. How does that indicate 8bit registers? Looks like 16 bit registers to me.

As I said I am not that great in programming. Its just a hobby and I tought I will build a little weather station.

My thought about that came from the information of the temp sensor saying it returns 4 registery with 4 bytes. Also english is not my native language.

I am using this one https://www.dfrobot.com/product-2392.html

I would say it works. But as you can see I get wierd ascii signs. I would say the messages that I get there are hex numbers and the serial prints it as a sign then.
image

As the timestamp is readable, you have set the correct baud rate for the serial monitor. Random garbage printout like that sometimes suggests you are using the same serial port for the IDE serial monitor and binary comms to another device.

Can you post the code you are using and a drawing of how you have connected the various modules together (hand drawn and photographed is fine).

Thats the code that is currently running on my ESP32-S3. Its just the example with a slower baud rate because of the sensor. I cant really tell if the baud rate in the serial is the baud rate that is used to read the sensor values in my sensor but I would say yes.

#include <ModbusMaster.h>


// instantiate ModbusMaster object
ModbusMaster node;


void setup()
{
  // use Serial (port 0); initialize Modbus communication baud rate
  Serial.begin(9600);

  // communicate with Modbus slave ID 2 over Serial (port 0)
  node.begin(2, Serial);
}


void loop()
{
  static uint32_t i;
  uint8_t j, result;
  uint16_t data[6];
  
  i++;
  
  // set word 0 of TX buffer to least-significant word of counter (bits 15..0)
  node.setTransmitBuffer(0, lowWord(i));
  
  // set word 1 of TX buffer to most-significant word of counter (bits 31..16)
  node.setTransmitBuffer(1, highWord(i));
  
  // slave: write TX buffer to (2) 16-bit registers starting at register 0
  result = node.writeMultipleRegisters(0, 2);
  
  // slave: read (6) 16-bit registers starting at register 2 to RX buffer
  result = node.readHoldingRegisters(2, 6);
  
  // do something with data if read is successful
  if (result == node.ku8MBSuccess)
  {
    for (j = 0; j < 6; j++)
    {
      data[j] = node.getResponseBuffer(j);
    }
  }
}

Curious, how did you get this output??
Your code has no serial prints..

You should switch the adapter to Serial1 i believe it's RX 18, TX 17 on the S3..
Or you can use any pins and re-assign them..

Then you can add some serial prints to see what is happening..

~q

Your code shows that you are using the same serial port for the IDE serial monitor and the Modbus communication. The IDE serial monitor is trying to display the modbus binary data as printable characters which is why you are seeing all those strange symbols.

I've little to no experience with an ESP32 device. Does it have another hardware serial port. A quick search suggests that there might be a Serial2?

Your RS485 module is an isolated device. There's these 2 diagrams on the DFRobot web page which should help you (although the first one shows what looks like an UNO using the hardware serial port!):


Note that there are 2 sets of 12V connections. The 2 contacts next to the 12V-IN label are where you need to apply 12V DC from a power source. The 12V and GND connections next to the RS485 label can be used to power your sensor - assuming it needs a 12VDC power source to operate.

It's not clear from your drawing where the power for your sensor is coming from.

I know its on the 12V and GND connection that is in the RS485 box. The board already has an little boost converter on it to deliver 12V to the sensors but not much current. So if you use sensor or multiple sensor you need to ad a external power source.

A quick look at the schematic for the RS485 module shows that it is using a B0512M-2WR2 DC/DC converter to generate the 12V output. The datasheet for the B0512M-2WR2 shows that it requires a nominal 5V (4.5V to 5.5V) input in order to generate the 12V. Your drawing shows only 3V (3.3V?), which is outside the spec.

You also have the MT3608 on it (a 2A step up converter that can work from 2V up to 24V) that produces 5V1 for the TD541S485H.
9810c322218d9643776c845e0c95d0d2.pdf (214.5 KB)

So after a little bit of googling I found out that my sensor need a different variant of the modbus, in this case its the modbus RTU version. So this is my new code:

#include <ModbusRTU.h>
#include <SoftwareSerial.h>

#define SLAVE_ID 2
#define FIRST_REG 0
#define REG_COUNT 2

SoftwareSerial S(38, 39);
ModbusRTU mb;

bool cb(Modbus::ResultCode event, uint16_t transactionId, void* data) { // Callback to monitor errors
  if (event != Modbus::EX_SUCCESS) {
    Serial.print("Request result: 0x");
    Serial.print(event, HEX);
  }
  return true;
}

void setup() {
  Serial.begin(115200);
  S.begin(9600, SWSERIAL_8N1);
  mb.begin(&S);
  mb.master();
}

void loop() {
  uint16_t res[REG_COUNT];
  if (!mb.slave()) {    // Check if no transaction in progress
    mb.readHreg(SLAVE_ID, FIRST_REG, res, REG_COUNT, cb); // Send Read Hreg from Modbus Server
    while(mb.slave()) { // Check if transaction is active
      mb.task();
      delay(10);
    }
    Serial.println(res[0]);
    Serial.println(res[1]);
  }
  delay(1000);
}

And this is what I get as serial:

Its almost working.

look at sketch..
to see how to construct a HardwareSerial instead of software..

good luck.. ~q

Ah, I see that now! I should have zoomed in on the schematic some more!

Thats to high for me :sweat_smile:

I am a noob in programming. Its very difficult to understand complicated code.

Your previous library (modbusmaster) is ok with modbus rtu.

Try with that, but with hardware serial on pins 18 and 17:

Serial1.begin(9600, SERIAL_8N1, 18, 17)
node.begin(2, Serial1);

also, did you set slave address to 2 on your sensor dip switch??

The timestamp comes from the PC, not from the Arduino :wink:

Dammit - that's another neuron that's failed! Not many left now!

1 Like