Page 1 of 1

ESP32 + Anemometer on reed switch

Posted: Tue Feb 14, 2023 2:44 pm
by Dantey
Hello everyone.

I have a weather station project with wind measurement to complete. I got two wind speed sensors for it, one of them is WH-SP-WS01 and the other is PCE-WS P from PCE instruments.

For the first one with two wires that are serial to Reed Swtich, I builted simple program with interrupts to check when state is RISING with added 10ms debbounce time:
  1. #include <Arduino.h>
  2.  
  3. #define Pin GPIO_NUM_33
  4.  
  5. volatile uint16_t speedCnt;
  6. uint32_t timer1;
  7. volatile uint16_t debbTimer;
  8.  
  9.  
  10. void IRAM_ATTR isr()
  11. {
  12.   if (millis() - debbTimer > 10)
  13.   {
  14.     debbTimer = millis();
  15.     speedCnt++;
  16.     }
  17.   // speedCnt++;
  18. }
  19.  
  20. void setup()
  21. {
  22.   Serial.begin(9600);
  23.   pinMode(Pin, INPUT_PULLUP);
  24.   attachInterrupt(Pin, isr, RISING);
  25.  
  26.   timer1 = millis();
  27. }
  28.  
  29. void loop()
  30. {
  31.   if (millis() - timer1 > 1000)
  32.   {
  33.     Serial.println(speedCnt);
  34.     speedCnt = 0;
  35.     timer1 = millis();
  36.   }
  37. }

The problems is when I read pulses on first one, there are lot of them. I added RC filter to first one, and it goes even worse. Most of edges were round and long. So I moved to the second more "professional" instrument and changed code a little bit to read HIGH state only when previous was LOW on Pull_Down resistor.
  1. #include <Arduino.h>
  2.  
  3. #define Pin GPIO_NUM_33
  4.  
  5. volatile uint16_t speedCnt;
  6. volatile bool state;
  7. uint32_t timer1;
  8. volatile uint16_t debbTimer;
  9.  
  10.  
  11. void IRAM_ATTR isr()
  12. {
  13.   if (millis() - debbTimer > 10 && state != digitalRead(Pin))
  14.   {
  15.     debbTimer = millis();
  16.     state = digitalRead(Pin);
  17.     speedCnt++;
  18.     }
  19. }
  20.  
  21. void setup()
  22. {
  23.   Serial.begin(9600);
  24.   pinMode(Pin, INPUT_PULLDOWN);
  25.   attachInterrupt(Pin, isr, HIGH);
  26.  
  27.   timer1 = millis();
  28.   state = digitalRead(Pin);
  29. }
  30.  
  31. void loop()
  32. {
  33.   if (millis() - timer1 > 1000)
  34.   {
  35.     Serial.println(speedCnt);
  36.     speedCnt = 0;
  37.     timer1 = millis();
  38.   }
  39. }


According to documentation it has already filter and third wire to give pulses:

Pic1.jpg
Pic1.jpg (26.65 KiB) Viewed 1510 times

But problem still occure. I look on my small osciloscope to check how signals goes in 1 second and it look like this:

IMG_000.jpg
IMG_000.jpg (48.54 KiB) Viewed 1510 times

Rising edges are pretty sharp so I don't know why EPS printed me on console values 13-17 but when I see there are no 13 Rising edges in one second.

I added addictional filter according to documentantion...

Pic2.jpg
Filter in input
Pic2.jpg (47.72 KiB) Viewed 1510 times

it changes falling edges to more smoother ones, but it changes nothing. I tried to measue Pulse Hz with osciloscope and my hair dryer for repeatable result, but on osciloscope was 30 HZ on counter there was about 140-170. Even if osciloscope have constant value, values on ESP hesitated between 140-170.



I don't know how to fix that problem. I read about Schmitt triggers, that can solve problem of values of pulses but,
PCE-WS was pretty expensive( about 140euros) and I don't know how they can work on PLC but not on ESP? Did PLC have some other stuff that can works well?

Have anyone have any idea how to solve that problem? I don't rule out that my oscilloscope is bad, but most of time values can be high even if Fan is rotates very slow.

This is how I connected to LOLIN32 Lite. Test was also on esp32 doit devkit v1 with the same result. DC connector was for power supply and White wire was to Yellow on Anemometer. Capacitor are 100nF and resistor is 1k

Image

Regards,
Lucas