commit
7c13e58ee6
@ -0,0 +1,141 @@
|
||||
#define VANE_PIN A0
|
||||
#define VANE_VOLTAGE 5.0
|
||||
#define VANE_POWER_PIN 7
|
||||
#define VANE_REFER 10000
|
||||
#define VANE_MEASURE_ITERATIONS 3
|
||||
|
||||
#define ANEMOMERTER_PIN 2
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
pinMode(VANE_PIN, INPUT);
|
||||
pinMode(VANE_POWER_PIN, OUTPUT);
|
||||
|
||||
pinMode(ANEMOMERTER_PIN, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(ANEMOMERTER_PIN), anemometerTick, CHANGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wind direction (vane)
|
||||
*
|
||||
* The measurements are made with an R10k as R1 in the voltage divider (VANE_REFER constant).
|
||||
*
|
||||
* List of corrections as in `documentation => measured value`.
|
||||
* 0.32 => 0.37
|
||||
*/
|
||||
static const float vaneValue[16] {0.37,0.41,0.45,0.62,0.90,1.19,1.40,1.98,2.25,2.93,3.08,3.43,3.84,4.04,4.33,4.62};
|
||||
static const float vaneDirection[16] {112.5,67.5,90,157.5,135,202.5,180,22.5,45,247.5,225,337.5,0,292.5,315,270};
|
||||
|
||||
float getWindVane()
|
||||
{
|
||||
double vin = 0;
|
||||
|
||||
digitalWrite(VANE_POWER_PIN, HIGH);
|
||||
/* Measure voltage several times for greater accuracy */
|
||||
for (int i = 0; i < VANE_MEASURE_ITERATIONS; i++) {
|
||||
vin = vin + analogRead(A0);
|
||||
}
|
||||
digitalWrite(VANE_POWER_PIN, LOW);
|
||||
|
||||
vin = vin / VANE_MEASURE_ITERATIONS;
|
||||
vin = vin * (VANE_VOLTAGE / 1023.0);
|
||||
|
||||
/* Find the closest value from voltage array */
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (vin - vaneValue[i] <= 0) {
|
||||
/* Check for the first */
|
||||
if (i == 0)
|
||||
return vaneDirection[i];
|
||||
|
||||
/*
|
||||
* Check if the new value is in the negative.
|
||||
* This prefers the lower value (4 from 4.5 etc).
|
||||
*/
|
||||
if (-(vin - vaneValue[i]) < vin - vaneValue[i-1])
|
||||
return vaneDirection[i];
|
||||
|
||||
return vaneDirection[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In case a negative value is never reached, return the last value in the array.
|
||||
*/
|
||||
return vaneDirection[15];
|
||||
}
|
||||
|
||||
|
||||
/* Wind speed */
|
||||
|
||||
#define WIND_FACTOR 2.4
|
||||
#define TEST_PAUSE 60000
|
||||
|
||||
volatile unsigned long anem_count = 0;
|
||||
volatile unsigned long anem_last = 0;
|
||||
volatile unsigned long anem_min = 0xffffffff;
|
||||
|
||||
double getUnitWind()
|
||||
{
|
||||
unsigned long reading = anem_count;
|
||||
anem_count = 0;
|
||||
return(WIND_FACTOR * reading) / (TEST_PAUSE / 1000);
|
||||
}
|
||||
|
||||
double getGust()
|
||||
{
|
||||
unsigned long reading = anem_min;
|
||||
anem_min = 0xffffffff;
|
||||
double time = reading / 1000000.0;
|
||||
|
||||
return(1 / (reading / 1000000.0)) * WIND_FACTOR;
|
||||
}
|
||||
|
||||
void anemometerTick()
|
||||
{
|
||||
long thisTime = micros() - anem_last;
|
||||
anem_last = micros();
|
||||
|
||||
if (thisTime > 500) {
|
||||
anem_count++;
|
||||
if (thisTime < anem_min)
|
||||
anem_min = thisTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Rain gauge */
|
||||
|
||||
#define RAIN_FACTOR 0.2794
|
||||
|
||||
volatile unsigned long rain_count = 0;
|
||||
volatile unsigned long rain_last = 0;
|
||||
|
||||
double getUnitRain()
|
||||
{
|
||||
|
||||
unsigned long reading = rain_count;
|
||||
rain_count = 0;
|
||||
double unit_rain = reading * RAIN_FACTOR;
|
||||
|
||||
return unit_rain;
|
||||
}
|
||||
|
||||
void rainTick()
|
||||
{
|
||||
long thisTime = micros() - rain_last;
|
||||
rain_last = micros();
|
||||
|
||||
if(thisTime > 500)
|
||||
rain_count++;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(getWindVane());
|
||||
Serial.println("°");
|
||||
|
||||
Serial.println(getUnitWind());
|
||||
Serial.println(getGust());
|
||||
|
||||
delay(1000);
|
||||
}
|
Loading…
Reference in New Issue