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!
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
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.
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);
}
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);
}
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!
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:
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?
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?
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.