Stuck! Wind Direction Sensor

Hi, I bought an wind direction sensor but am stuck trying to figure out how to connect it to an RS485 module and the code to make it work. There are some threads on this forum but they all dead-end with incomplete solutions.

Can someone please help me connect the dots? Help me Only One Cannoli, you're my only hope!

The Wind Direction Sensor: https://www.amazon.com/dp/B09CGV115Q?psc=1&ref=ppx_yo2ov_dt_b_product_details

RS485 module for Arduino: https://www.amazon.com/dp/B07R52KJYZ?psc=1&ref=ppx_yo2ov_dt_b_product_details .

Please post the wiring directions found in the wind gauge user manual.

2 Likes

This is the RS485 model...

Sorry this link is one wire, analog.
How to Use Wind Direction Sensor with Arduino - miliohm.com

1 Like

what host microcontroller are planning to use?
to make interfacing simpler I would recommend one with hardware serial ports such as the Arduino Mega or ESP32
the first thing would be to connect the TTL-RS485 module and make sure it is working

A generic "RS485" connection diagram:

Here are pictures of the pages from the user manual for the Wind Direction sensor:

Very nice diagram. I was looking for a wiring diagram for connecting the Max485 to the Arduino and I think this gets me there. It also shows the "A+" and "B-" connections on the Max which I can match up to the A and B wires on the sensor.

I'll need to look at the code I downloaded to see if it matches up to the pinouts on the diagram. If so, maybe I've got a shot at being unstuck. Thanks for your help.

Dan

RS485 module for Arduino: https://www.amazon.com/dp/B07R52KJYZ?psc=1&ref=ppx_yo2ov_dt_b_product_details .

Looking at the C++ code I downloaded, I do not understand how the code matches up with the pinouts on your diagram. The code defines RX as Arduino pin "10" for example, but the wiring diagram shows it should be D2. Maybe this is not the right code for this particular hardware?

Here's what I downloaded:
#define RX 10 //Serial Receive pin which connects to RO on RS485 module
#define TX 11 //Serial Transmit pin which connects to DI on RS485 module
#define RTS_pin 8 //RS485 Direction control
#define RS485Transmit HIGH
#define RS485Receive LOW
SoftwareSerial RS485Serial(RX, TX);
void setup() {
pinMode(RTS_pin, OUTPUT);
Serial.begin(9600);
Serial.println("Anemometer");
// Start the Modbus serial Port, for anemometer
RS485Serial.begin(9600);
delay(1000);
}
void loop() {
digitalWrite(RTS_pin, RS485Transmit); // init Transmit
byte Anemometer_request[] = {0x02, 0x03, 0x00, 0x01, 0x00, 0x02, 0x95, 0xf8}; // inquiry frame
RS485Serial.write(Anemometer_request, sizeof(Anemometer_request));
RS485Serial.flush();
digitalWrite(RTS_pin, RS485Receive); // Init Receive
byte Anemometer_buf[8];
RS485Serial.readBytes(Anemometer_buf, 8);
Serial.print("wind speed : ");
for( byte i=0; i<7; i++ ) {
Serial.print(Anemometer_buf[i],HEX);
Serial.print(" ");
}
Serial.print(" ==> ");
Serial.print(Anemometer_buf[4]);
Serial.print(" m/s");
Serial.println();
delay(1000);
}

@lightda - Your instructions in PDF...

And... format your code with the < CODE > button in the message box...

#define RX 10 //Serial Receive pin which connects to RO on RS485 module
#define TX 11 //Serial Transmit pin which connects to DI on RS485 module
#define RTS_pin 8 //RS485 Direction control
#define RS485Transmit HIGH
#define RS485Receive LOW

SoftwareSerial RS485Serial(RX, TX);

void setup() {
  pinMode(RTS_pin, OUTPUT);
  Serial.begin(9600);
  Serial.println("Anemometer");
  // Start the Modbus serial Port, for anemometer
  RS485Serial.begin(9600);
  delay(1000);
}

void loop() {
  digitalWrite(RTS_pin, RS485Transmit); // init Transmit
  byte Anemometer_request[] = {0x02, 0x03, 0x00, 0x01, 0x00, 0x02, 0x95, 0xf8}; // inquiry frame
  RS485Serial.write(Anemometer_request, sizeof(Anemometer_request));
  RS485Serial.flush();
  digitalWrite(RTS_pin, RS485Receive); // Init Receive
  byte Anemometer_buf[8];
  RS485Serial.readBytes(Anemometer_buf, 8);
  Serial.print("wind speed : ");
  for ( byte i = 0; i < 7; i++ ) {
    Serial.print(Anemometer_buf[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" ==> ");
  Serial.print(Anemometer_buf[4]);
  Serial.print(" m/s");
  Serial.println();
  delay(1000);
}

It's great that you found a PDF version of the owner's manual as it's easier to read than the pictures I posted of the hardcopy. I don't see how that helps me however.

You don't see how others not needing to reference blurry photos of crumpled papers that aren't totally accessible unless you click into the server, and reading ill-formatted code helps others help you? Wow. I do not exist.

The pins used don't really matter. Usually I would change the code to match the actual connections. You haven't told us how you have connected, I assume you haven't made any connections yet.

The code you have doesn't match the RS485 hardware you have. Again I would change the code. It appears you have found some code for an anemometer, which is a different device to a wind direction sensor.

I have modified your sketch accordingly, I don't guarantee it is correct.

#include "SoftwareSerial.h"

#define RX 2 // Serial Receive pin which connects to RO on RS485 module
#define TX 3 // Serial Transmit pin which connects to DI on RS485 module
// RS485 Direction control
#define TX_ENABLE   4 //  connect to DE
#define RX_ENABLE_N 5 //  connect to RE

#define RS485Transmit HIGH
#define RS485Receive LOW

SoftwareSerial RS485Serial(RX, TX);

void setup() {
  pinMode (TX_ENABLE, OUTPUT);
  pinMode (RX_ENABLE_N, OUTPUT);

  Serial.begin(9600);
  Serial.println("Wind direction");
  // Start the Modbus serial Port, for Wind direction
  RS485Serial.begin(9600);
  delay(1000);
}

void loop() {
  // init Transmit
  digitalWrite (TX_ENABLE, 1);
  digitalWrite (RX_ENABLE_N, 1);

  byte Direction_request[] = {0x02, 0x03, 0x00, 0x17, 0x00, 0x01, 0x34, 0x0E}; // inquiry frame
  RS485Serial.write(Direction_request, sizeof(Direction_request));
  RS485Serial.flush();

  // Init Receive
  digitalWrite (TX_ENABLE, 0);
  digitalWrite (RX_ENABLE_N, 0);

  byte Direction_buf[8];
  RS485Serial.readBytes(Direction_buf, 8);
  Serial.print("wind direction : ");
  for ( byte i = 0; i < 7; i++ ) {
    Serial.print(Direction_buf[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" ==> ");
  Serial.print(Direction_buf[4]);
  Serial.println();
  delay(1000);
}

Duplicate post 10 January 2024.

Yikes, put down the meat cleaver please. I'm doing the best I can. I don't how you found the PDF of the owner's manual but it is way better than my crumpled papers. Merely having a more legible copy of the manual didn't help me but it may help someone on this forum.

I didn't format the code using the button because the program is so short I didn't think it was necessary.

Many thanks. Blush you are right, the code I posted is for an anemometer not wind direction. Ironically, I actually have an anemometer working and modified the code so it displays on a TM1637 digital display. I've never worked with RS485 before and got completely lost in trying to figure out which controller to use and how to wire it let alone which code to use in order for Arduino to talk through it to the direction sensor. Your diagram and code are super helpful. Let me now give it a try!

image

Hi Bob, I wired up the RS485 controller to the wind direction sensor and to the Arduino per the diagram you provided and per the code that you sent. I'm very grateful for your help. The program runs!! but always returns the same value of 69 no matter what position the sensor is in.

I measured15VDC at the WD sensor and 5VDC for at the RS485 board. Triple checked the wiring to make sure it matches the code. I also increased the dealy to 5000 (i.e.5 seconds) because the WD sensor's specs say it can take that long to give a response.

On a second run, it returned 199 but as before, it never varies even though I've moved the WD sensor to different positions:
image

Any ideas on troubleshooting steps I can put into the code to see whether it is in fact, polling the WD sensor anew each time and getting a response?

Thanks,

Dan

A couple of more thoughts. I disconnected power to the WD sensor but the program kept on getting the same values/response from the RS485 module. Also, I wonder if the "FF" at the beginning of the reply frame is a failure code of some sort?

Don't you just love user manuals ....

Your canned modbus message appears to be using device address 02 as per the example message in section 3.3.1. However para 3.2 says that the default device address is 01 and the opening sentence of para 3.3.1 refers to device address 01 before promptly using device address 02 in the example message.

I would assume a device address of 01 and change the first byte in your canned message to 01.

I'll do a quick calculation for you to work out the CRC16 checksum. Back in a min.

What a crap user manual!

Your sensor would never respond to that example as the CRC16 checksum is wrong for the message content.

The 02 in that message must be a typo because using 01 instead results in a valid modbus message with the same checksum as the example.

So, change the initial 02 in your message to 01 and give it a go.

It may be a -1 which is what Seria.read() returns if there is no data to read. You could/should check the return value from Serial.readBytes to determine how many bytes were actually received.

Hi and thanks muchly for taking a look at this. I changed the 02 to 01 as suggested, compiled, uploaded, and ran it:

void loop() {
  // init Transmit
  digitalWrite (TX_ENABLE, 1);
  digitalWrite (RX_ENABLE_N, 1);

  byte Direction_request[] = {0x01, 0x03, 0x00, 0x17, 0x00, 0x01, 0x34, 0x0E}; // inquiry frame
  RS485Serial.write(Direction_request, sizeof(Direction_request));
  RS485Serial.flush

But the results are unchanged:
image

I wish there was some sort of verbose mode that could display whether the RS485 module is in fact, responding to the request for info?