Station weather WH65LP. How to read data using esp32?

Hi everyone

I ordered a weather station WH65LP.

I don't have it yet, I'm looking for information

https://a.aliexpress.com/_EvGyEdO

Ecowitt Weather Quick Start.

I'd like to read the data using an ESP32.

I can't find any information. Do I need to add a converter?
https://a.aliexpress.com/_Ev83PMo

Could someone please help? What would an example code for reading data ?

Regards

Did you not notice this

Attention:

Before order, please ensure you know how to develop the software to collect the data. What we can support only is to provide the communication protocol to you.

First of all, the forum is not a design shop or a coding shop. You are expected to make a swerious effort and when yiou get stuck a helper will give you a hint.

You should try to return the kit and instead order one that is complete. Here is one I found that appears to be the same sensors but much more complete.
[https://www.aliexpress.com/item/1005009363906252.html](https://www.aliexpress.com/item/1005009363906252.html

the WH65L appears to have a RS485 interface therefore you require a TTL-RS485 converter as in the link - it can be powered from 3.3V therefore should interface to the ESP32 3.3V logic OK
if working with RS485 I find it useful to have a USB-RS485 module so a PC can be used to test the RS485 bus and monitor data flow

simple ESP32 test program to communicate with TTL-RS485 module

// ESP32 Serial1 to RS485 bus
//
// see https://microcontrollerslab.com/rs485-serial-communication-arduino-tutorial/

#define RS485Serial Serial1  // hardware serial port on ESP32

// RS485 VCC ESP32 to to 3.3V
#define RXD2 16  //  ESP32 Serial1 Receive  pin 16 to RS485 RO  (Receiver Output) /RXD
#define TXD2 17  //  ESP32 Serial1 Transmit pin 17 to RS485 DI  (Driver Input) /TXD

// some RS485 modules automatically switch between transmit and receive DE/RE not defined
// RS485 DE (Driver Enable set HIGH to enable)  and RE (Receiver Enable set LOW to enable) to ESP32 pins 18 and 19
//#define DE   //RS485 Direction control pin
//#define RE   //RS485 Direction control pin

#define RS485Transmit HIGH
#define RS485Receive LOW

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("\n\nESP32 connect to RS485 bus - enter/receive text");
#ifdef DE  // if DE and RE are defined
  pinMode(DE, OUTPUT);
  pinMode(RE, OUTPUT);
  digitalWrite(DE, RS485Receive);  // Disable RS485 Transmit
  digitalWrite(RE, RS485Receive);  // Disable RS485 Transmit
#endif
  RS485Serial.begin(9600, SERIAL_8N1, RXD2, TXD2);  // set the RS485 data rate
}

// loop sending data to RS485 and receiving data
void loop() {
  if (Serial.available()) {           // Arduino Serial data avaliable?
#ifdef DE                             // if DE and RE are defined
    digitalWrite(DE, RS485Transmit);  // Enable RS485 Transmit
    digitalWrite(RE, RS485Transmit);  // Enable RS485 Transmit
#endif
    RS485Serial.write(Serial.read());  // Send byte to Remote RS485
    RS485Serial.flush();               // wait for byte to be transmitted
#ifdef DE                              // if DE and RE are defined
    digitalWrite(DE, RS485Receive);    // Disable RS485 Transmit
    digitalWrite(RE, RS485Receive);    // Disable RS485 Transmit
#endif
  }

  if (RS485Serial.available())         // RS485 serial data available?
    Serial.write(RS485Serial.read());  // read character and display it
}

some TTL-RS485 modules have RE and DE pins to enable/disable the transmit and receive circuits when switching the bus between transmit and receive (RS485 is simplex)
the TTL-485 module in your link switches automatically and does not have RE/DE pins therefore you can ignore them

1 Like
Yes, I used this converter to read water levels; it used the Modbus protocol.
If I want to read data from the weather station, do I need to use it again?
Could you take a look at the schematic?
I'll try your code when I receive the station.


do you have a user manual? it should state what protocol is used- could even be plain ASCII text

looks ok except the B to D- connection is missing

WH65LP-Weather-Station-with-RS485-Port states it comes with a USB-RS485 module to connect to PC (baud rate:9600, parity: NONE, bits:8, stop:1)

1 Like

looks ok except the B to D- connection is missing

the yellow line in the diagram.

RS485 -UART protocool.

Seller sent

my monitor does not show yellow on white very well

looks simple - read 25bytes every 16seconds - decode, check checksum, etc
initially update code of post 3 to display decimal or hex values, e.g.

  if (RS485Serial.available())         // RS485 serial data available?
    Serial.printf("%02x", (RS485Serial.read());  // read byte and display HEX

using a calculator you can calculate values to see if they make sense
then change the program to read 25 byte frames etc

1 Like

Thank you. I will try.

I made a sample program.

Do you think it has a chance of working?

I'll test it once I have the station.

#define RXD2 16   
#define TXD2 17  

const int bufferSize = 25;
byte receivedData[bufferSize];
int dataIndex = 0;

void setup() {
  Serial.begin(9600); // debug
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2); // RS485
}

void loop() {
  if (Serial2.available() > 0) {
  
    byte incomingByte = Serial2.read();

    if (dataIndex < bufferSize) {
      receivedData[dataIndex] = incomingByte;
      dataIndex++;
    }

    if (dataIndex == bufferSize) {
      processFrame(receivedData);

      dataIndex = 0;
    }
  }
}

void processFrame(byte data[]) {
  
  Serial.println("receive frame:");
  for (int i = 0; i < bufferSize; i++) {
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

looping reading single bytes until you get 25 fails if you start reading in the middle of a frame

probably simpler to attempt to read a frame of 25 bytes using Serial.readBytes(buffer, length) which returns the number of bytes read (or 0 if timeout)
if you start the program reading in the middle of a frame it will return the wrong count which you can ignore

e.g. this reads a frame of 10 bytes

// ESP32  Serial1 test - read array of 10 bytes

#define RXD1 16  // can map Serial1 and Serial2 to many ESP32 GPIO pins
#define TXD1 17  // check pin usage https://randomnerdtutorials.com/esp32-pinout-reference-gpios/

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  Serial1.begin(9600, SERIAL_8N1, RXD1, TXD1);
  Serial.printf("\n\nESP32 serial1  test RXD1 pin %d TXD1 pin %d\n", RXD1, TXD1);
  Serial.printf(" loopback test connect pin %d to pin %d\n", RXD1, TXD1);
}

void loop() {
  // read from Serial1, send to Serial
  if (Serial1.available()) {
    byte data[50] = { 0 }, count = 0;
    // attempt to read 10 bytes - will timeout  after 1 second returning 0
    // Serial.readBytes(buffer, length)
    if ((count = Serial.readBytes(data, 10)) == 10) {
      // 10 bytes read display
      Serial.printf("Read text %s\n", data);
      for (int i = 0; i < 10; i++)
        Serial.printf(" 0x%02x", data[i]);
      Serial.println();
    } else            // if not 10 bytes read error
      if (count > 0)  // ignor timeout
        Serial.printf("ERROR readBytes read %d bytes\n", count);
  }
  // read from Serial, send to Serial1
  while (Serial.available()) {
    int inByte = Serial.read();
    //Serial.write(inByte);     // local echo if required
    Serial1.write(inByte);
  }
}

entering frames of various length serial monitor displays

ESP32 serial1  test RXD1 pin 16 TXD1 pin 17
 loopback test connect pin 16 to pin 17
ERROR readBytes read 2 bytes
Read text 1234567890
 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x30
ERROR readBytes read 2 bytes
ERROR readBytes read 1 bytes
Read text abcdefghio
 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6f
ERROR readBytes read 4 bytes

change the frame size to 25 and see if it works

1 Like

Thank you for your help. I'll let you know when I get the weather station

horace I've connected the station and received a byte frame. I don't know how to decode the byte frame. I'd like to start by reading the first value.
Do I understand correctly that the first value is the wind direction, and the third byte?

wind direction - value in hex range 0° - 359°

#include <SoftwareSerial.h>

const byte rxPin = 5;
const byte txPin = 4;

SoftwareSerial mySerial(rxPin, txPin);

const byte bufferSize = 25;
byte data[50] = {0};
byte count = 0;


void setup()
{
    Serial.begin(115200);
    mySerial.begin(9600);
}

void loop()
{
    if (mySerial.available())
    {
        // attempt to read 25 bytes - will timeout  after 1 second returning 0
        // Serial.readBytes(buffer, length)
        if ((count = mySerial.readBytes(data, bufferSize)) == bufferSize)
        {
            // 25 bytes read display
            Serial.printf("Read bytes \n");

            for (int i = 0; i < bufferSize; i++)
            {
                Serial.printf(" 0x%02x", data[i]);
            }

            Serial.println("\n");
            Serial.printf("Received %d bytes", count);
        }
        else // if not 25 bytes read error
        {
            if (count > 0)
            {
                Serial.printf("ERROR readBytes read %d bytes\n", count);
            }
        }
    }
}
Read bytes 
 0x24 0x8f 0xd5 0x02 0x57 0x3e 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x46 0x30 0x95 0x01 0x87 0x0e 0x96 0x00 0x29 0x5d 0xdc

Received 25 bytes

the family code 0x24 is correct
you can calculate the checksum (8 bit sum of bytes 0 to 15)
then temperature say
e.g.

void setup() {
  Serial.begin(115200);
  delay(2000);
  byte chksum = 0;
  byte d[] = { 0x24, 0x8f, 0xd5, 0x02, 0x57, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x30, 0x95, 0x01, 0x87, 0x0e, 0x96, 0x00, 0x29, 0x5d, 0xdc };
  for (int i = 0; i < 16; i++)
    chksum += d[i];
  Serial.printf("byte17 0x%x chksum 0x%x\n", d[16], chksum);
  float temperature = float(((d[3] & 0x7) << 8 | d[4]) - 400.0) / 10.0;
  Serial.printf("temperature %f\n", temperature);
}

void loop() {
}

serial monitor displays

byte17 0x95 chksum 0x95
temperature 19.900000

checksum 0x95 is correct and temperature looks reasonable

gives you some idea how to calculate the other values

1 Like

Thank you so much for your help. I'm very grateful.

@brendy32530 i would like to buy the same kit. Did you find a way to read data via RS485 -UART protocool? Thanks

Yes, the example Horace gave was very helpful. You need to calculate the remaining values ​​based on this, summing the remaining bytes according to the documentation.

1 Like