DFRobot wind sensor on Z-Uno (RS485)

I am trying to set up this sensor, but the z-uno doesn’t support SoftwareSerial. So how do I do this then?

Sorry for the quirky links, but I am not allowed to set more than two links in a topic (new user)...

z-uno.z-wave. me

I am adapting this sketch:
create.arduino.cc/projecthub/philippedc/arduino-esp8266-rs485-modbus-anemometer-45f1d8

Hardware
Wind Sensor (SEN0483) using the RS485 to RS232 (DFR0845)
github. com/DFRobotdl/RS485_Wind_Speed_Transmitter

Arduino Example for communication (NOT z-uno)

Example for Raspberry Pi

Here is what I have.

Code

// V3.0

ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_FREQUENTLY_AWAKE);

ZUNO_SETUP_CHANNELS(
  ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY, SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterWind),
  ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY, SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterGust)
);



#include <SoftwareSerial.h>  // https://github.com/PaulStoffregen/SoftwareSerial

#define RX        10    //Serial Receive pin
#define TX        11    //Serial Transmit pin
#define RTS_pin    9    //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW

SoftwareSerial RS485Serial(RX, TX);

long counter = 0;
long endCounter = 600; //seconds for report interval
float lastValue = 0;
float currentValue = 0;
float sumWind = 0;
float meanWind = 0;
float gust = 0;

void setup() {

  pinMode(RTS_pin, OUTPUT);  
  
  // Start the built-in serial port, for Serial Monitor
  Serial.begin(9600);

  // Start the Modbus serial Port, for anemometer
  RS485Serial.begin(9600);   
  delay(1000);
}

void loop() {

  digitalWrite(RTS_pin, RS485Transmit);     // init Transmit
  byte Anemometer_request[] = {0x01, 0x03, 0x00, 0x16, 0x00, 0x01, 0x65, 0xCE}; // 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);


 //just for reference, has to be set as currentValue below
  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();   

  if (counter < endCounter) {
    currentValue = 10; // Set here value from serial device

    // Gust higher or not?
    if (currentValue > lastValue) {
      lastValue = currentValue;
    }

    sumWind = sumWind + currentValue;
    counter = counter + 1;

    gust = lastValue; //m/s
    
    delay(100);
  }
  else {
    //Calculate new wind values
    meanWind = sumWind / endCounter;

    zunoSendReport(2);
    zunoSendReport(1);

    lastValue = 0;
    sumWind = 0;
    counter = 0;
    delay(100);
  }
}

long getterWind(void) {
  return meanWind;
}

long getterGust(void) {
  return gust;
}

I know nothing of the Zuno, but I found this page on the serial ports.

Use the begin() function to choose the pins, baud and other parameters for the port.

The Zuno language reference.

Sounds good. But I am not sure how to convert the above code. I have zero experience with RS485.

Do you have the RS485 converter? You need one to convert the 0-5V serial output of the Zuno to the RS485 signal. Then get rid of the SoftwareSerial library.

Here is example code that I found.

I will be using this one:

Gravity_Active_Isolated_RS485_to_UART_Signal_Converter_SKU_DFR0845

But I guess the code is the same.

I can’t test it yet, but I think I am on the right track.

However I only have two data wires coming from the sensor. The other ones are 12V + and GND. The sketch includes a pin_direction_RX_TX = 10, though.
Also in the wiki there are addresses mentioned that I haven’t used in the code below.

RS485 Wind Speed Meter/Sensor/Transmitter Wiki - DFRobot

// V3.0
 
ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_FREQUENTLY_AWAKE);
 
ZUNO_SETUP_CHANNELS(
  ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY, SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterWind),
  ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY, SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterGust)
);
 
// pin for send/get rs485
int pin_direction_RX_TX = 10;
 
long counter = 0;
long endCounter = 600; // for report interval 600*0.1s
float lastValue = 0;
float currentValue = 0;
float sumWind = 0;
float meanWind = 0;
float gust = 0;
 
void setup() {
  Serial.begin();
  Serial0.begin(9600);
  pinMode(pin_direction_RX_TX, OUTPUT);
  // to get data RS485
  digitalWrite(pin_direction_RX_TX, LOW);
}
 
void loop() {
 
  if(Serial0.available() > 0) {
    char currentValue = Serial0.read(); 
    Serial.print(currentValue,HEX);
  }
    if (counter < endCounter) {
    // Gust higher or not?
    if (currentValue > lastValue) {
      lastValue = currentValue;
    }
 
    sumWind = sumWind + currentValue;
    counter = counter + 1;
 
    gust = lastValue; //m/s
   
    delay(100);
  }
  else {
    //Calculate new wind values
    meanWind = sumWind / endCounter;
 
    zunoSendReport(2);
    zunoSendReport(1);
 
    lastValue = 0;
    sumWind = 0;
    counter = 0;
  }
}
 
long getterWind(void) {
  return meanWind;
}
 
long getterGust(void) {
  return gust;
}

I try to sum things up:

The wiring is clear. There is only RX and TX connected. Four wires go to the sensor and the power supply is done externally with 12V.

This sample code tells me I have to send HEX code to get the data. But how do I do this?

void setup() {
//Communicate with PC through USB to UART, use Serial to call
Serial.begin(9600);
//Use Serial1 to call the serial UART of TXD and RXD marked on the development board
Serial1.begin(9600);
}

void loop() {
  if (Serial.available()) 
    Serial1.write(Serial.read());
  if (Serial1.available())
    Serial.write(Serial1.read());
}

After I that I can adapt to Z-Uno, but first I have to get this right.

So far I have this:

// V3.0

ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_FREQUENTLY_AWAKE);

ZUNO_SETUP_CHANNELS(
  ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY, SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterWind),
  ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VELOCITY, SENSOR_MULTILEVEL_SCALE_METERS_PER_SECOND, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getterGust)
);

long counter = 0;
long endCounter = 600; //seconds for report interval
float lastValue = 0;
float currentValue = 0;
float sumWind = 0;
float meanWind = 0;
float gust = 0;

void setup() {

  Serial.begin();
  Serial0.begin(9600);
  delay(1000);
}

void loop() {

  //this part should be converted to return currentValue below
  byte Anemometer_request[] = {0x01, 0x03, 0x00, 0x16, 0x00, 0x01, 0x65, 0xCE}; // inquiry frame
  RS485Serial.write(Anemometer_request, sizeof(Anemometer_request));
  RS485Serial.flush();
  byte Anemometer_buf[8];
  RS485Serial.readBytes(Anemometer_buf, 8);
  currentValue = (Anemometer_buf[4]);

  // get data from slave device
  if(Serial0.available() > 0) {
    char c = Serial0.read();  
    Serial.print(c,HEX);
    currentValue = 9999; // Set here value from above
}

  if (counter < endCounter) {

    // Gust higher or not?
    if (currentValue > lastValue) {
      lastValue = currentValue;
    }

    sumWind = sumWind + currentValue;
    counter = counter + 1;

    gust = lastValue; //m/s
    
    delay(100);
  }
  
  else {

    //Calculate new wind values
    meanWind = sumWind / endCounter;

    zunoSendReport(2);
    zunoSendReport(1);

    lastValue = 0;
    sumWind = 0;
    counter = 0;
  }
}

long getterWind(void) {
  return meanWind;
}

long getterGust(void) {
  return gust;
}

But how would I change this:

  byte Anemometer_request[] = {0x01, 0x03, 0x00, 0x16, 0x00, 0x01, 0x65, 0xCE}; // inquiry frame
  RS485Serial.write(Anemometer_request, sizeof(Anemometer_request));
  RS485Serial.flush();
  byte Anemometer_buf[8];
  RS485Serial.readBytes(Anemometer_buf, 8);
  currentValue = (Anemometer_buf[4]);

to this:

  if(Serial0.available() > 0) {
    char c = Serial0.read();  
    Serial.print(c,HEX);
    currentValue = 9999; // Set here value from above
}

Found a solution.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.