Arduino UNO + Modbus RTU RS485 + wind sensor

Hi to all,

I would like to use my Arduino UNO to read data from my wind sensor.
The problem is that the sensor's output is on the RS485 port with Modbus RTU.

Is it possible to read from it by using my Arduino? I think I need to use a RS485 adapter like this one: https://www.amazon.it/gp/product/B07B667STP/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
rs485
Do I need some extra hardware?

I never used this kind of protocol, I tried to read from the user manual and these are some screenshots:



Can you give me some suggestions, please?
is there any specific library to use?

For an UNO You need no level shifters.
I suggest using Software serial and other pins than D0 and D1. They are great to use for debugging via serial monitor.
RS485 is, according to Wikipedia, a pure electrical matter without any high level protocol. Just pure good old fashioned serial communication.

So, I do not need to buy that rs485 adapter?

You do need that adapter.

Your adapter looks like it is intended to be used with a typical 5v UNO, so the "you don't need a level shifter" comment, while true, is superfluous and could be confusing.

  • twisted pair wire
  • termination resistors
  • fail-safe bias resistors, called pullup and pulldown resistors in the MAX13487 datasheet (and required per the datasheet); your adapter may have them built in, but since there is no schematic for it and I don't read Italian, I'm not sure.

Also, there are plenty of example Arduino projects on the web that use RS485 + Modbus RTU. Pick one and give it a go.

1 Like

Thank you!

I connected the Arduino to the RS485 adapter and then to the Wind sensor.
I installed the ModBus Master library from the library manager and by using the included sample code, I set the sensor address = 5 as specified in the sensor manual.

#include <ModbusMaster.h>


// instantiate ModbusMaster object
ModbusMaster node;


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

  // communicate with Modbus slave ID 2 over Serial (port 0)
  node.begin(5, 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);
    }
  }
}

Unfortunately, I cannot understand how do I need to modify the sample code for example to read the wind speed.
In the sensor manual, it says that the wind speed is at register 30001, but how can I get access to this register and how can I read it?

Moreover, in the manual, it says that I should use these parameters for the port:

Baud rate: 19200 Baud
Byte frame: 8E1 (1 start bit, 8 data bits, 1 parity bit (even parity), 1 stop bit)

but I guess that the serial port on Arduino is 8N1, is it correct?

I think there's a few issues here:

You should avoid using the hardware serial port for other things than uploading sketches or serial print debugging.

On an UNO, a software serial port is usually suggested like @Railroader mentions in post #2.

You may struggle to use a software serial port at 19200 baud.

I don't think any of the software serial port implementations have a parity bit so you would struggle with even parity.

Does the user manual mention anything about being able to change the baud rate - maybe to 9600?

Yes, it is possible to change the baud rate as described in the manual:

But I do not know how to do it! If I cannot use Arduino to connect to the device, how can I change the baudrate?

Is there any way to use the adapter rs485 to connect the sensor to the pc and use something like serial monitor to send the commands?
Sorry for the stupid question, but I never use the modbus rtu protocol.

If you are lucky, then the manufacturer/supplier of the wind sensor may have a PC app that you can get hold of that would let you configure baud rate etc.

If you are not so lucky, then what you may be able to do is use one of the free PC modbus apps to communicate with the wind sensor. You would be communicating at the register level so no fancy GUI or scaling of values etc.

There are USB-RS485 adapters around that are very cheap. I use this one:


If you intend to play around with RS485, then one of those is a good investment.

I've not tried it but in theory what you may be able to do is write a simple sketch for your UNO that uses a software serial port (I'd go with AltSoftSerial myself) to interface to your RS485 adapter (as shown in your post #1). Simply monitor the hardware serial port for any incoming bytes and retransmit them over the software serial port (switching the RS485 adapter into Tx mode first). Similarly, any bytes received by the software serial port would be written back to the hardware serial port.

In that configuration, you have used your UNO as a simple USB-RS485 converter and could then use a PC app to change those settings.

The down side to doing it in the raw is that if you mess up the baud rate, then you may end up locked out of your sensor. Unless of course there is some form of hardware reset that puts all the settings back to their default values.

If you can change the baud rate down to 9600, then also change the parity to none.

There is a fork of AltSoftSerial that added parity...

1 Like

Thank you a lot! Even if i think that I won't be able to connect to the sensor by using arduino if I do not change the baudrate first with an external software.

I already have the usb to rs485 adapter, fortunately, but i do not have the official software for the sensor (i do not think it exists).

I've used RS485 over 75 feet of Cat 5 with software serial at 28800 with no problems. So before messing with the baud rate and parity, I'd try using your UNO to read the wind speed from your sensor at its default settings.

Excellent. That's saved me a job. I had recently got my head around how AltSoftSerial worked and was preparing to modify it to support parity.

1 Like

I would try, but I can't understand how to write the function to read the wind speed. I read the manual and theoretically I got it, but i do not know how to implement it with thr Arduino library.

I'm no expert on MODBUS, but I think the answer is in this:

image

The first six (in the orange circle) are transmitted to the sensor and command it to send the instantaneous wind speed. Presumably this is done with setTransmitBuffer and writeMultipleRegisters.

The next five (in the blue circle) are then received from the sensor. The wind speed is in the two yellow bytes (in the red circle). And this is likely done with readHoldingRegisters.

You will also need toggle the RS485 adapter between transmit and receive at the appropriate times.

To implement this, either you will need to do some more self-education, or someone else will have to help you with the details...

In the "retrieve windspeed" example:

0D = slave device address
04 = function code = read input registers
75 \ = register address, in this case 30001 *** <-------
31 /
00 \ = number of words to read
01 /
7A \ = 16-bit CRC16 checksum
C5 /

Switch your RS485 module into transmit mode, write out those bytes, switch back to receive mode and wait for a reply.

The example reply is:

0D = slave device address
04 = function code
02 = number of BYTES of data that follows
00 \ = 16-bit windspeed
1F /
E8 \ = 16-bit CRC16 checksum
F9 /

Have a look at my post #49 here:

There's a byte array called nitro. Change the bytes in that array to the bytes in the manual. Wire up the RS485 module as per the comments. Run the sketch and it should print out the commands and responses.

*** Note: I think this is wrong in the datasheet/manual. 30001 is function code 3, not 4. And the address doesn't include the function code, so 30001 should be function code 03 and address 0000. The checksum will have to be recalculated. I use crccalc.com.

1 Like

Hello,

I downloaded a software named Simply Modbus Master for Windows and then I used the USB-to-RS485 adapter to communicate with the sensor.

I do not know if it is working, this is a screenshot from the software:

I sent:
2023/04/11 18:55:40 >>> 05 04 00 00 00 01 30 4E

and I guess this is the answer I received:

2023/04/11 18:55:41 < 00 80 80 F8 78 78 80 80 78 F8 80 78 78 78 78 78 78 80 80 80 F8 80 80 00 80 80 78 80 80 80 00 78 80 80 78 00 78 00 80 00

I can't understand what I received since I do not know how to translate it into ASCII, however, I wasn't able to replicate the command to retrieve the wind speed.

The received answer is garbage. It should start with the slave ID, in this case 05.

I'm not familiar with Simply Modbus Master, but I wonder if the value in the "minus offset" box should be 30000.

If I insert minus offset = 0, I get the same string reported in the example to read the wind speed, it change just the 0D since the example use a slave address = 13 while my default address should be 5.

However, I think I still get garbage.

You read my mind. I was going to suggest trying to enter the values that would replicate the raw data that the manual is showing.

Looking over the screenshots you have posted, the manual uses addresses 01, 05 & 0D. I wonder what address your sensor is configured as.

What's confusing is the garbage response. If you send out a modbus message that the sensor understands, then it should reply with a sensible response - probably around 8 or 9 bytes when asking for just 1 register.

If the sensor doesn't understand the message, then it should not respond at all.

Go with the sensor ID and baud rate you think is correct. It's a lot easier to discover a sensor address using the PC tool than it is using an Arduino.

What is the make & model no of your sensor? There may be some code out there that works with it already.