Awkward wind MQTT data sensor

Hello!

I'm trying to program a DIY weather station on a ESP-WROOM-32 (38 pins) with different sensors, who sends MQTT data:

  • Wind sensor
  • LDR sensor
  • BME280 sensor

The code is this one:

#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "settings.h"

#define PIN_SENSOR_VIENTO 36 // Wind sensor pin
#define PIN_SENSOR_LDR 33

unsigned long temp1 = 0;

unsigned int WindSpeed = 0;
unsigned int LDRValue = 0;

Adafruit_BME280 bme;

WiFiClient espClient;
PubSubClient clientMqtt(espClient);

void setup() {
  Serial.begin(9600);
  setupWifi();
  clientMqtt.setServer(mqttServer, mqttPort);
  clientMqtt.setCallback(callback);

  if (!bme.begin(0x76)) {
    Serial.println("[ERROR] No se pudo inicializar el sensor BME280. Compruebe la conexión.");
    while (1);
  }
}

void setupWifi() {
  delay(10);
  Serial.println();
  Serial.print("[WIFI] Conectando a ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("[WIFI] WiFi conectada");
  Serial.print("[WIFI] IP: ");
  Serial.print(WiFi.localIP());
  Serial.println("");
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("[MQTT] Mensaje recibido (");
  Serial.print(topic);
  Serial.print(") ");
  String mqttcommand = "";
  for (int i = 0; i < length; i++) {
    mqttcommand += (char)payload[i];
  }
  Serial.print(mqttcommand);
  Serial.println();
  if (mqttcommand == "comando") {
    Serial.println("comando");
  }  
}

void reconnect() {
  Serial.print("[MQTT] Intentando conectar a servidor MQTT... ");
  while (!clientMqtt.connected()) {
    Serial.print(".");
    if (clientMqtt.connect(mqttId, mqttUser, mqttPassword)) {
      Serial.println("");
      Serial.println("[MQTT] Conectado al servidor MQTT");
      clientMqtt.publish(mqttSubTopicHealthcheck, "starting");
      clientMqtt.subscribe(mqttSubTopicOperation);
    } else {
      Serial.print("[MQTT] Error, rc=");
      Serial.print(clientMqtt.state());
      Serial.println("[MQTT] Intentando conexión en 5 segundos");
      delay(5000);
    }
  }
}

void loop() {
  if (!clientMqtt.connected()) {
    reconnect();
  }
  clientMqtt.loop();
    
  if (millis() - temp1 > updateTimeSensors) {
    temp1 = millis();
    
    WindSpeed = 6 * analogRead(PIN_SENSOR_VIENTO) * (5.0 / 1023.0); // Lectura del sensor de velocidad del viento
    LDRValue = analogRead(PIN_SENSOR_LDR); // Lectura del sensor LDR

    float temperature = bme.readTemperature();
    float humidity = bme.readHumidity();
    float pressure = bme.readPressure() / 100.0;

    publishData(mqttPubTopicWindSpeed, String(WindSpeed, 2));
    publishData(mqttPubTopicTemperature, String(temperature, 2));
    publishData(mqttPubTopicHumidity, String(humidity, 2));
    publishData(mqttPubTopicPressure, String(pressure, 2));
    publishData(mqttPubTopicLDR, String(LDRValue));

    delay(1000);
  }
}

void publishData(const char* topic, const String& data) {
  Serial.print("[MQTT] Enviando ");
  Serial.print(topic);
  Serial.print(": ");
  Serial.println(data);
  clientMqtt.publish(topic, data.c_str());
}

When I connect all the sensor except the wind sensor, the first mqtt message shows "0", that it's correct, but after the second message and the others, random data shows on wind sensor (remember, nothing plug in in the gpio 36!):

First message:
screen-1

Following message
screen-2

screen-3

I couldn't connect yet with the wind sensor (missing a part), should the data show "0"?
What's happening?
It's a problem with the gpio? Should I try others?

Thanks in advance!

What do you expect the result of an analog read on a floating input to be?

Thank you for your reply gfvalvo,

The gpio should read the voltage from the wind sensor (0-5v). and send it.
It's not correct the code? Fairly new :face_exhaling:

Yes, but you said the wind sensor was not yet connect, right? Until you connect it, that input is floating. analogRead() will likely return a random value. Try grounding it until you get the wind sensor connected.

1 Like

Really? So totally dumb question :melting_face:
Thank you for your time!

NP. Report back if grounding that pin doesn't fix it.

1 Like

Hello again!

Today I have time and I've installed the anemometer to the final place.

and I'm still having strange data with the sensor :roll_eyes:

I check several time with the multimeter the ground and the esp32, and I've good connection between the negative from the power supply and the ground from esp32 (the multimeter sound "beeep" perfectly with the gnd pin at the esp and the negative on the power supply), sorry by the inaccurate term.

The anemometer that I have, is this one model ZTS-3000-FSJT-V05, and the specs (I bought the 0-5v version):


Wire colors of the anemometer:
Brown: Positive Power Supply
Black: Negative Power Supply
Blue: Positive Output
Yellow: Negative Output

The power supply works good, giving 12,25v to the anemometer:

And when I measure the pin signal from the anemometer, without wind shows 0.03v, with quite a lot wind, the signal shows between 1.13/0.88 (looks quite low! Maybe is not 0-5v?)

If is no wind, the mqtt data show "0", good, but if some wind, the data could be 100 m/s, or 110 m/s or 1001, 110001m/s etc… (always some number with 1 and 0, never other numbers).

What's wrong? Maybe the code is calculating wrong?

How can I test if the code or the anemometer is good or wrong?

Thank you for your help!

ESP-WROOM-32 Analog input pins are max 3.3V and the default is 12bit conversion.
So assuming you have no input shaping/ protection circuit and that the wind is not more than 19.8m/s = 3.3V output.
the code should be

    WindSpeed = 6 * analogRead(PIN_SENSOR_VIENTO) * (3.3 / 4095); // Lectura del sensor de velocidad del viento
    
1 Like

Thanks for your advice @HardShovel.

I change the code to use only the anemometer:

#include <WiFi.h>
#include <PubSubClient.h>
#include "settings.h"

#define PIN_SENSOR_VIENTO 36 // Pin analógico A2 en el ESP32 (pin GPIO 36)

unsigned long temp1 = 0;
unsigned int WindSpeed = 0;

WiFiClient espClient;
PubSubClient clientMqtt(espClient);

void setup() {
  Serial.begin(9600);
  setupWifi();
  clientMqtt.setServer(mqttServer, mqttPort);
}

void setupWifi() {
  delay(10);
  Serial.println();
  Serial.print("[WIFI] Conectando a ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("[WIFI] WiFi conectada");
  Serial.print("[WIFI] IP: ");
  Serial.print(WiFi.localIP());
  Serial.println("");
}

void reconnect() {
  Serial.print("[MQTT] Intentando conectar a servidor MQTT... ");
  while (!clientMqtt.connected()) {
    Serial.print(".");
    if (clientMqtt.connect(mqttId, mqttUser, mqttPassword)) {
      Serial.println("");
      Serial.println("[MQTT] Conectado al servidor MQTT");
    } else {
      Serial.print("[MQTT] Error, rc=");
      Serial.print(clientMqtt.state());
      Serial.println("[MQTT] Intentando conexión en 5 segundos");
      delay(5000);
    }
  }
}

void loop() {
  if (!clientMqtt.connected()) {
    reconnect();
  }
  clientMqtt.loop();
    
  if (millis() - temp1 > updateTimeSensors) {
    temp1 = millis();
    
    WindSpeed = analogRead(PIN_SENSOR_VIENTO) * (3.3 / 4095) *  1.6532 ; // Lectura del sensor de velocidad del viento

    publishData(mqttPubTopicWindSpeed, String(WindSpeed, 2));

    delay(1000);
  }
}

void publishData(const char* topic, const String& data) {
  Serial.print("[MQTT] Enviando ");
  Serial.print(topic);
  Serial.print(": ");
  Serial.println(data);
  clientMqtt.publish(topic, data.c_str());
}

Settings.h:

// WiFi Configuration
const char* ssid = "Wifi-name";
const char* password = "Wifi-pass";

// MQTT Configuration
const char* mqttServer = "IPmqttserver";
const int mqttPort = 1883;
const char* mqttUser = "User";
const char* mqttPassword = "passw";
const char* mqttId = "anemometer_esp32";
const char* mqttSubTopicHealthcheck = "/home/meteo/healthcheck";
const char* mqttPubTopicWindSpeed = "/home/meteo/wind_speed";
const char* mqttSubTopicOperation = "/home/meteo/operation";

// Other params
const unsigned long updateTimeSensors = 7500; // milliseconds

I change the calculation for 3.3v:

WindSpeed = analogRead(PIN_SENSOR_VIENTO) * (3.3 / 4095) *  1.6532

Some findings: If I connect the yellow wire I have reading with the multimeter (before I had to put the negative with the power supply). So I ground the esp32 with the yellow wire and the signal with the blue wire:

I made a video with the multimeter readings:

The reading with the anemometer stopped (no wind) start minimum with 0.006v, and with some wind 0.184v (at 26sec. at the video).

Looks quite low, because at minimum wind should be 1v, but not those values.

With this changes, always, no matter how much wind, the mqtt value is "0"

The multiplier 1.6532 should be 6.0

WindVoltage = analogRead(PIN_SENSOR_VIENTO) * (3.3 / 4095)
WindSpeed   = WindVoltage * 6       // 1 volt = 6M/s    5V=30m/s

so code should be

 WindSpeed = 6 * analogRead(PIN_SENSOR_VIENTO) * (3.3 / 4095);  // for wind speed up to 3.3V  19.8m/s

reading of 0.184V = wind speed of 1.104m/s with the multiplier *6 using your value of 1.6532 it will be below 1.

try the following
change the WindSpeed variable to float value.

float WindSpeed = 0;
    WindSpeed = 6.0 * analogRead(PIN_SENSOR_VIENTO) * (3.3 / 4095.0)  ; // Lectura del sensor de velocidad del viento

    publishData(mqttPubTopicWindSpeed, String(WindSpeed, 3));    // change to 3 decimals to see changes

to test input calculation you could also disconnect the signal from anemometer from pin 36 and put a jumper from the 3,3V pin to pin 36, the reading should then be about 19.8m/s

1 Like

Thanks @HardShovel.

I modified the code with yours and the mqtt message looks as you said (19.800)

What should I change now?

Thanks in advance!!

Well that good, at least the code works as expected.
Remove the 3.3V to Pin 36 jumper and replace the sensor signal back on pin 36, and try the readings, if possible spin the cups faster to see if the values increase.
Do not try to go above 3.3V or 19.8m/s or you may damage the ESP32

1 Like

I change the jumper as you said (anemometer positive signal to 36 and anemometer negative to gnd) and now the mqtt shows only “0” and I also have spin the cups several time :face_with_raised_eyebrow:

I tried several things:

  • If I connect the negative from the anemometer power supply to gnd in esp32, the mqtt shows 19.800 all time, moving or not moving the cups.
  • If I disconnect the ground from esp32 (only attached the pin 36, the mqtt shows random numbers, moving or not moving the cups.

The ESP code seems to be correct.
0v or low voltage input = 0ms
3.3v = 19.8ms
no connection or floating input = random readings
all the above are correct.

For the ESP it needs a voltage into pin 38 with reference to the GND pin from the sensor.

So it might be a problem with the following
1 Check all connections are secure and tight
1 12V Power Supply
2 Connections from power supply to anemometer, recheck voltage at the anemometer
3 the code is set to take a reading every 7.5 seconds, which is a long time while manually spinning so change the following

// Other params
const unsigned long updateTimeSensors = 500; // milliseconds  1000 or 500 for testing, 7500 for running normally

Recheck with the following wiring schemes
1 Blue - pin 36 Yellow - esp-gnd, manually spin a various speeds
2 measure voltage with between Blue and 12V power supply ground (black), is it above 3.3V
do not try the Blue - pin 36, 12V PSU black to esp-gnd

1 Like

Thank you again @HardShovel !!

Finally seems it’s working fine!!

I check the connections and the positive from the power supply had bad contact :sleepy:

Now, if I stop the cups manually, the mqtt shows “0 m/s” and if I spin fast I can reach 3m/s :+1:

Thanks thanks and thanks a lot @HardShovel !!

To recap, I use the follow code (so somebody can use it for other project):

#include <WiFi.h>
#include <PubSubClient.h>
#include "settings.h"

#define PIN_SENSOR_VIENTO 36 // Pin analógico A2 en el ESP32 (pin GPIO 36)

unsigned long temp1 = 0;
float WindSpeed = 0;

WiFiClient espClient;
PubSubClient clientMqtt(espClient);

void setup() {
  Serial.begin(9600);
  setupWifi();
  clientMqtt.setServer(mqttServer, mqttPort);
}

void setupWifi() {
  delay(10);
  Serial.println();
  Serial.print("[WIFI] Conectando a ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("[WIFI] WiFi conectada");
  Serial.print("[WIFI] IP: ");
  Serial.print(WiFi.localIP());
  Serial.println("");
}

void reconnect() {
  Serial.print("[MQTT] Intentando conectar a servidor MQTT... ");
  while (!clientMqtt.connected()) {
    Serial.print(".");
    if (clientMqtt.connect(mqttId, mqttUser, mqttPassword)) {
      Serial.println("");
      Serial.println("[MQTT] Conectado al servidor MQTT");
    } else {
      Serial.print("[MQTT] Error, rc=");
      Serial.print(clientMqtt.state());
      Serial.println("[MQTT] Intentando conexión en 5 segundos");
      delay(5000);
    }
  }
}

void loop() {
  if (!clientMqtt.connected()) {
    reconnect();
  }
  clientMqtt.loop();
    
  if (millis() - temp1 > updateTimeSensors) {
    temp1 = millis();
    
     WindSpeed = 3.599997 * 6.0 * analogRead(PIN_SENSOR_VIENTO) * (3.3 / 4095.0)  ; // in km/h

    publishData(mqttPubTopicWindSpeed, String(WindSpeed, 3));

    delay(1000);
  }
}

void publishData(const char* topic, const String& data) {
  Serial.print("[MQTT] Enviando ");
  Serial.print(topic);
  Serial.print(": ");
  Serial.println(data);
  clientMqtt.publish(topic, data.c_str());
}

Settings.h:

// WiFi Configuration
const char* ssid = "WifiSSID";
const char* password = "WifiPassword";

// MQTT Configuration
const char* mqttServer = "IPmqttserver";
const int mqttPort = 1883;
const char* mqttUser = "mqttUserId";
const char* mqttPassword = "mqttUserPassword";
const char* mqttId = "anemometer_esp32";
const char* mqttSubTopicHealthcheck = "/home/meteo/healthcheck";
const char* mqttPubTopicWindSpeed = "/home/meteo/wind_speed";
const char* mqttSubTopicOperation = "/home/meteo/operation";

// Other params
const unsigned long updateTimeSensors = 5000; // milliseconds

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