pimoroni / enviro

MIT License
101 stars 79 forks source link

Enviro Weather only gives 8 wind directions, not the 16 that the vane can output. #114

Open MrDrem opened 1 year ago

MrDrem commented 1 year ago

Looking at the code on the weather enviro, I note that the code only picks up 8 directions, not the 16 that are given in the data sheet for it: https://www.maxoberberger.net/media/data/projects/arduino-weatherstation/weather-sensor-assembly.pdf

See https://www.maxoberberger.net/projects/arduino-weatherstation.html for more details.

ZodiusInfuser commented 1 year ago

Thanks for raising this. This may well have been our misunderstanding when interpreting the datasheet for our sensor (datasheet here: https://cdn.shopify.com/s/files/1/0174/1800/files/windandrainsensors.pdf?v=1622723515)

I'll look into it once things are more stable

ZodiusInfuser commented 1 year ago

@MrDrem If you get chance, could you give this code a test? It adds in the inbetween angles but I think due to the mechanics of the sensor their trigger range is rather small (perhaps too small to be useful?)

It also rotates the results by 180 degrees from what it used to, so it now matches the angles in the datasheet.

import time, math, os
from pimoroni import Analog

wind_direction_pin = Analog(26)

def wind_direction():
  # adc reading voltage to cardinal direction taken from our python
  # library - each array index represents a 22.5 degree step around
  # the compass (index 0 == 0, 1 == 22.5, 2 == 45, etc.)
  # we find the closest matching value in the array and use the index
  # to determine the heading
  ADC_TO_DEGREES = (2.533, 1.308, 1.487, 0.270, 0.300, 0.212, 0.595, 0.408,
                    0.926, 0.789, 2.031, 1.932, 3.046, 2.667, 2.859, 2.265)

  closest_index = -1
  last_index = None

  # ensure we have two readings that match in a row as otherwise if
  # you read during transition between two values it can glitch
  # fixes https://github.com/pimoroni/enviro/issues/20
  voltage = 0.0
  while True:
    value = wind_direction_pin.read_voltage()

    closest_index = -1
    closest_value = float('inf')

    for i in range(16):
      distance = abs(ADC_TO_DEGREES[i] - value)
      if distance < closest_value:
        closest_value = distance
        closest_index = i

    if last_index == closest_index:
      voltage = value
      break

    last_index = closest_index

  resistance = (voltage * 10000) / (3.3 - voltage)
  return closest_index * 22.5, voltage, resistance

while True:
    print(wind_direction())
    time.sleep(1)
MrDrem commented 1 year ago

Thanks! I've loaded it onto the weather board, and should have added logging to give the voltage and resistance values, but I didn't. It's now back outside and we'll see what I get (might need to whistle a bit for the wind though, dead calms here).

I note that the current code waits for two readings in a row, due to the intermediate readings messing things up, I do now wonder if that can be dropped. I might need to add those logging lines to work that out though!

ZodiusInfuser commented 1 year ago

@MrDrem How did this perform for you?

MrDrem commented 1 year ago

I've now seen all of the values except 67.5 I believe. I need to get better at writing my own InfluxDB queries, so I can get the data back easier than trying to do it via bad Grafana dashboards.

I am going to try and spend a little time understanding how the double count code works, and seeing if getting rid of that still causes issues.

ZodiusInfuser commented 1 year ago

@MrDrem did you find out if getting rid of the double count caused issues? I don't see there being any real detriment to keeping it in, unless there was a specific scenario you had in mind?

ZodiusInfuser commented 1 year ago

@MrDrem Any update on this?

MrDrem commented 1 year ago

Sorry, I've been tied up with other work.

I've not managed to get rid of the double count, the main reason for thinking that getting rid of it may be beneficial is that extends the reading time if the wind direction is unsettled, and that the standard wind vanes are notoriously jittery.

sjefferson99 commented 1 year ago

@ZodiusInfuser I have put the above code into a branch off main and adding some logging and sent the direction values to influxdb.

Below is a table of possible values and if I have seen them in the overnight test. It's looking good as @MrDrem also observed.

Issue #20 is not too clear on what is off, but inferring from the phrasing and the design of the resistor network and how it was previously obtaining wind, I think it was picking up specific values between the known values, that were simply throwing incorrect reults in.

I am going to remove the loop and return the first value, with all the calculation values returned to the log and will assess the values seen in influxdb and how they compare over time to my data collected using the loop and see how it looks and post back here.

From last night's data with the loop:

Possible Seen
0 Y
22.5 Y
45 Y
67.5 N
90 Y
112.5 Y
135 Y
157.5 N
180 Y
202.5 Y
225 Y
247.5 Y
270 Y
292.5 N
315 Y
337.5 Y
360 N
sjefferson99 commented 1 year ago

After a night running without the loop code I got a nearly full set of values.

The wind data isn't perfect, but there is a clear bias towards a westerly wind which was the prevailing during the sample period. The other errors are consistent with me observing the direction indicator spinning in vortices (I don't have the perfect location away from other structures).

I would suggest this code is working as expected.

image

Value Observed
0 Y
22.5 Y
45 Y
67.5 N
90 Y
112.5 Y
135 Y
157.5 Y
180 Y
202.5 Y
225 Y
247.5 Y
270 Y
292.5 Y
315 Y
337.5 N