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.
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.
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?
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.
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.
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:
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...
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.
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.
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.
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.