RS485 anemometer connected to an ESP32

Hello, I'm trying to use a ZTS-3000-FSJT-N01 anemometer which uses RS485 protocol. I've connected the black and brown cables to a 15V power supply that's working fine. The yellow cable to the A+ and the blue to the B- of a RS485-TTL converter. The GND cable to the GND on the ESP; the RXD to pin 22; the TXD to pin 21; the VCC to pin 3v3.

I'm using esphome but I'm completely unable to make esp32 read the values. Mind to hand me any help?

Google does not find that type of anemometer. A link to the documentation, Please!

Rs485 is not protocol, it's standard. You need to know your protocol, modbus maybe?
Find your protocol sheet and post it here together with info about your esp board, rs485 converter and wiring.

It's this one
https://a.aliexpress.com/_EHXlZJV


The converter
https://a.aliexpress.com/_Evg6yCj

The board:

https://a.aliexpress.com/_EHjYaXv

Thanks for your help!

Does esphome know about the modbus protocol that is likely used with your product?

Do you have the full user manual for your anemometer?

Can you draw out how you have connected the parts together.

Ok, it's modbus like expected, but we need some protocol info. At least register addresses (and baud rate and slave address). Any idea..?

You could go "fishing" the data, but it's not beginner task for pleasure :slight_smile:

I agree with kmin, you will have to check the MODBUS protocol. I had a different sensor also using 485, but they have documented the MODBUS commands.

For example, I wrote something like this to parse the commands:

void parseCommand(const char* command) {
    // Variables to store parsed values
    char commandName[6];
    uint8_t address;
    uint8_t functionCode;
    uint8_t startAddressHigh;
    uint8_t startAddressLow;
    uint8_t numRegistersHigh;
    uint8_t numRegistersLow;
    uint8_t crcHigh;
    uint8_t crcLow;

    uint8_t hexArray[MAX_COMMANDSIZE] = {};

// MODBUS 0x01 0x03 0x00 0x00 0x00 0x0A
// MODBUS 0x01 0x03 0x00 0x27 0x00 0x01 GET Sensor Resistance 
  if (strncmp(command, "MODBUS", 6) == 0) {
    // Use sscanf to parse the command string
    int result = sscanf(command, "%s 0x%2hhx 0x%2hhx 0x%2hhx 0x%2hhx 0x%2hhx 0x%2hhx",
                        &commandName, 
                        &hexArray[0], &hexArray[1], &hexArray[2], &hexArray[3], 
                        &hexArray[4], &hexArray[5]);

I asked the seller about the info, will post if he answer. Meanwhile, this evening I will try to use the code to read the info.

I bought 1kW power supply from cinese seller, published with "serial modbus rtu protocol". They were not able to have the protocol and decided to refund. I reversed that protocol and I'm happy with my free PSU.

1 Like

Since you seem to have rs485 converter with automatic direction, you could wire it to Usb-ttl serial converter and scan your device with pc software. It's much easier to start with.
Do you have one?

Yes, I do, bit don't know how to use it to scan my device

Hi @mvasco ,

Welcome to the forum..

Got yourself a modbus device??
I don't know diddly about the esphome and quick look, seems like you'll have to make a component out of your device, so won't be much help there, sorry..

More than happy to help get your device talking thou..

What code if any are you using??

Looks like your device should be at address 1, either 4800 or 9600 baud..
You should be reading register 1..

Is your 485 adapter compatible with your esp32, 3.3v??

good luck.. ~q

Have you been using your usb-ttl on you computer (so already working)?

I'm trying to understand what's the easiest way for you to get your modbus talking to you, but I don't know how familiar you are with different things.
We have options to try with esphome, with arduino modbusmaster or with pc software.

Edit:
Try with @qubits-us code first!

here's something to try..

#include <HardwareSerial.h>

#define BUF_SIZE 20
#define TIMEOUT  100
#define USE_CAST true

#define WIND   0
#define REG_2  1
#define REG_3  2
#define REG_4  3
#define REG_5  4
#define REG_6  5
#define REG_7  6



#define RXD2 22 //16
#define TXD2 21 //17
HardwareSerial mod(1);



//all together.. 7 in 1, first 7 registers from device address 1..
const byte dataMod[7][8]={
 {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A},//wind speed
 {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA},//reg 2
 {0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, 0xCA},//reg 3
 {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A},//reg 4
 {0x01, 0x03, 0x00, 0x04, 0x00, 0x01, 0xc5, 0xcb},//reg 5
 {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0b},//reg 6
 {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0b}};//reg 7

//same but address 255 (broadcast) any connected sensor
//should respond, the sensor will replace the 255 with their
//currently configured address, change USE_CAST to true to use
const byte dataMod_B[7][8]={
 {0xFF, 0x03, 0x00, 0x00, 0x00, 0x01, 0x91, 0xD4},//wind speed
 {0xFF, 0x03, 0x00, 0x01, 0x00, 0x01, 0xC0, 0x14},//reg 2
 {0xFF, 0x03, 0x00, 0x02, 0x00, 0x01, 0x30, 0x14},//reg 3
 {0xFF, 0x03, 0x00, 0x03, 0x00, 0x01, 0x61, 0xD4},//reg 4
 {0xFF, 0x03, 0x00, 0x04, 0x00, 0x01, 0xD0, 0x15},//reg 5
 {0xFF, 0x03, 0x00, 0x05, 0x00, 0x01, 0x81, 0xD5},//reg 6
 {0xFF, 0x03, 0x00, 0x06, 0x00, 0x01, 0x71, 0xD5}};//reg 7

//incoming buffer
byte buf[BUF_SIZE];

void setup() {
  Serial.begin(9600);
  //check different bauds could be 4800
  mod.begin(9600,SERIAL_8N1,RXD2,TXD2);
  Serial.println("Ready..");
}

void loop() {
 uint16_t val;

  Serial.println("Wind Speed: ");
  val = GetModVal(WIND);
  float Val1 = val * 0.1;
  Serial.print(Val1);
  Serial.println(" %");
  Serial.println("-----");
  delay(5000);

  }

uint16_t GetModVal(byte val) {
  uint32_t startTime = 0;
  uint8_t  byteCount = 0;
  memset(buf,0,sizeof(buf));//empty incoming..
//send request..
  delay(10);
  if (USE_CAST)
    mod.write(dataMod_B[val], sizeof(dataMod_B[val])); else
      mod.write(dataMod[val], sizeof(dataMod[val]));
  mod.flush();//wait for outgoing to be sent..
//recv response until timeout expires..
Serial.print("Response in HEX: ");
  startTime = millis();
  while (millis() - startTime <= TIMEOUT) {
    if (mod.available() && byteCount < sizeof(buf)) {
      buf[byteCount++] = mod.read();
      printHexByte(buf[byteCount - 1]);
    }
  }
  Serial.println();
  //combine 2 byte into word..
  return (uint16_t)(buf[3] << 8 | buf[4]);
}

void printHexByte(byte b)
{
  Serial.print(b , HEX);
  Serial.print(':');
}

should read your wind speed..
try different bauds, I got the sketch using modbus broadcast so any device should respond..
can maybe use this to test sensor anyways..

good luck.. ~q

1 Like

Well, as I'm not really skilled in anything related, I've tried the following:

Connected the anemometer to the rs485-ttl converter, and then the ttl converter to the ttl-usb, and now started arduino ide but I get:

/home/manuel/Arduino/PruebaAnemometro/PruebaAnemometro.ino:19:21: error: no matching function for call to 'HardwareSerial::HardwareSerial(int)'
 HardwareSerial mod(1);
                     ^
In file included from /home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/Arduino.h:233:0,
                 from /home/manuel/.var/app/cc.arduino.IDE2/cache/arduino/sketches/29D54972AE05433785AE9537137AA7C0/sketch/PruebaAnemometro.ino.cpp:1:
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:117:12: note: candidate: HardwareSerial::HardwareSerial(volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*, volatile uint8_t*)
     inline HardwareSerial(
            ^~~~~~~~~~~~~~
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:117:12: note:   candidate expects 6 arguments, 1 provided
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:93:7: note: candidate: constexpr HardwareSerial::HardwareSerial(const HardwareSerial&)
 class HardwareSerial : public Stream
       ^~~~~~~~~~~~~~
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:93:7: note:   no known conversion for argument 1 from 'int' to 'const HardwareSerial&'
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:93:7: note: candidate: constexpr HardwareSerial::HardwareSerial(HardwareSerial&&)
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:93:7: note:   no known conversion for argument 1 from 'int' to 'HardwareSerial&&'
/home/manuel/Arduino/PruebaAnemometro/PruebaAnemometro.ino: In function 'void setup()':
/home/manuel/Arduino/PruebaAnemometro/PruebaAnemometro.ino:51:38: error: no matching function for call to 'HardwareSerial::begin(int, int, int, int)'
   mod.begin(9600,SERIAL_8N1,RXD2,TXD2);
                                      ^
In file included from /home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/Arduino.h:233:0,
                 from /home/manuel/.var/app/cc.arduino.IDE2/cache/arduino/sketches/29D54972AE05433785AE9537137AA7C0/sketch/PruebaAnemometro.ino.cpp:1:
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:121:10: note: candidate: void HardwareSerial::begin(long unsigned int)
     void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
          ^~~~~
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:121:10: note:   candidate expects 1 argument, 4 provided
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:122:10: note: candidate: void HardwareSerial::begin(long unsigned int, uint8_t)
     void begin(unsigned long, uint8_t);
          ^~~~~
/home/manuel/.arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h:122:10: note:   candidate expects 2 arguments, 4 provided

exit status 1

Compilation error: no matching function for call to 'HardwareSerial::HardwareSerial(int)'

It may be because I had to select a board and chose arduino uno (just to try) and now I don't know how to unselect it.

Oh s..t
If you want to try that sketch above, you connect your Rs485 to Esp32 and Esp32 to computer.

Only in case you want to use pc software you can try with usb-ttl without Esp

Yep, using the wrong core..
I can do an uno version using software serial if you'd prefer??

~q

I did make sure it compiled for esp32..

https://wokwi.com/projects/398955697385175041

~q

He was using usb-ttl...

i'm confused.. :upside_down_face:
~q