Davis 6410 Anemometer

Davis 6410 Anemometer

Application

The Davis anemometer is currently used in a simple weather station to measure wind direction and speed.

Configuration

The detailed information provided by cactus.io was used to develop the present configuration. The use of different processors and general hardware configuration did, however, necessitate some modifications to that set-up, as outlined below.

Hardware

The anemometer, together with the rain collector, is currently configured in conjunction with the Heltec CubeCell Dev-Board Plus and the 10068-BHCP power management and 100768-WS weather station sensor interface PCBs.

Langlo Anemometer and Rain Collector installation

Langlo 'Weather Station'

The 'Weather Station' Node is currently powered by a 900mAh 14500 (AA) Li-Ion battery, supported by an 80 x 35 5.5V 70mA solar panel. The CubeCell architecture includes onboard solar panel support and battery charge management hardware, so the only additional component required in the power circuit is a reverse current protection diode on the solar panel (refer to the 10068-BHCP hardware description for details).

10068-WS + 10068-BHCP + 10068-PDS

In this configuration, the battery has retained full charge throughout the summer months here in Australia, but has yet to be tested through an extended period of overcast weather. In some of my early experiments, I did notice that once batteries were depleted to a certain level, they were never subsequently fully recharged, with the result that, over time, they ultimately ran flat. It's not yet clear whether this is a general problem, common to all processor configurations, or a 'feature' of the CubeCell [Plus] battery management system.

I'll make an appropriate note here when I've completed more extensive tests on some of the other processor configurations.

Configuration

The essential operational mechanism and configuration of the present Davis 6410 Anemometer—CubeCell Dev-Board Plus implementation is as illustrated below.

Davis 6410 Anemometer Hardware Configuration

Davis Anemometer Electrical Circuit
Pin Configuration
CubeCell Plus Davis 6410
GND GND
Ve VCC
ADC3 Direction
GPIO8 Speed

Note that the above is a simplified version of the circuit, intended to illustrate the internal configuration of the Davis sensor and it's logical connection to the CubeCell Dev-Board Plus. The 10068-WS board used in the present implementation incorporates additional line protection circuitry, which includes, for example, 10kΩ pull-up resistors, on all digital lines (see 10068-WS Board Schematic). A voltage divider (provided on the ">10068-BHCP board) is also required on the Wind Direction circuit to bring the input voltage down below the 2.4V maximum supported by the CubeCell architecture.

Weather Station Stack (Bottom) Weather Station Stack (Top)
Weather Station Node Board Stack

The anemometer is physically connected via an RJ11 socket on the 10068-WS board. The configurations of the anemometer cable and socket are illustrated below.

Davis 6410 Anemometer Cable Configuration

Davis Anemometer Cable Configuration

Software

The sketch for collecting data from the anemometer is currently specific to the Heltec CubeCell Dev-Board Plus, primarily in relation to both the interrupt mechanism and the control of power to the sensor. I have tested the application of the general principles involved with other processors (Arduino Pro Mini, ESP-12 and ESP32), but the CubeCell Plus turned out to be the easiest module to program for this application so it became the first to actually be used.

System Functions
Sleep Mode

Sleep modes and their characteristics vary between the different processor families.

In the present application, there are two considerations in relation to sleeping the processor:

  • Saving the state
  • Minimising power usage of both the processor and peripherals.

For details on the implementation of sleep modes on the CubeCell platform, refer to the section on CubeCell software.

Interrupts

The measurement of both wind speed and rainfall employ processor interrupts, the mechanism for which differs slightly for the different processor families.

For details on the implementation of interrups on the CubeCell platform, refer to the ">section on CubeCell software.

Measuring Wind Direction

As noted earlier, the present work is based on that described by cactus.io. One particular difference in the results is that I report my wind direction relative to true north, rather than magnetic north. The fundamental issues that need to be addressed in the code are no different, it's just a question of the reference point used.

Another consideration was the fact that the CubeCell Plus ADCs are 12 bits wide, so the range that can be mapped onto the 360° of the compass is 0..4095. To further complicate matters, the CubeCell Plus ADC input voltage is limited to 2.4V, necessitating the inclusion of a voltage divider, to bring the maximum input voltage back from 3.3V, in the input circuit.

On the basis that many inbuilt ADCs deviate from linearity near the top end of their scale, I made the decision to limit the input voltage a little further. Accordingly, using a 100kΩ/220kΩ voltage divider provides a maximum input voltage of around 2.27V, which mapped (by direct measurement, and for the purpose of calibration) to an ADC value of 3806. This value defines the upper limit of the range used in the function that maps the ADC output to the compass bearing.

According to the Australian Bureau of Meteorology, wind direction measurements are generally averaged over a 2-10 minute period. This wouldn't really be practical for my [battery-powered] application as, depending on the sampling period, it would require my node to be more or less permanently active. So my compromise is to sample the wind direction five times, at one second intervals, and report the average of those readings. The present solar/battery powered configuration reports every 60 seconds (without any decline in battery performance) and longer period averages can be calculated from this data.

Measuring Wind Speed

In the present application, wind speed and direction measurements are carried out concurrently, so the speed is reported as the average over the period used to measure the wind direction (about 5 seconds). Wind speed is derived from the number of 360° revolutions of the anemometer cups during this period, each revolution triggering an interrupt that, in turn, increments a counter.

In a 1 kph wind, the Davis 6410 anemometer cups rotate [through 360°] 1000 times per hour, so the wind speed can be calculated from the number of rotations recorded over a given time interval using the following equation (see Technical Specifications):

S=( 3600000 / K )× ( R / T )
=3600× ( R / T )

where

  • S = Wind speed (in kilometres per hour)
  • K = Rotations per hour per kph = 1000
  • R = Rotations recorded in time T
  • T = Sample period (in milliseconds)
  • 3600000 = milliseconds in 1 hour

In line with the comments on debouncing in relation to the Davis rain collector, I have not made any effort, in either hardware or software, to allow for chattering.

Testing the Configuration

The following sketch, which runs on the CubeCell Dev-Board Plus, in conjunction with the 10068-BHCP power management and 10068-WS weather station sensor interface boards, incorporates the above and can be used to verify the CubeCell Dev-Board Plus/Davis 6410 anemometer configuration.

Davis Anemometer Test Sketch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
210
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include "CubeCellPlusPins.h"// CubeCell Plus pin definitions
// Includes:
//#define windDirectionPinADC3
//#define windSpeedPinGPIO8

const uint16_t reportingPeriod = 10000;// In milliseconds, but keep it low while testing

uint16_t windCounter = 0;

void setup () {
pinMode(Vext,OUTPUT);
digitalWrite(Vext,LOW);// Turn on power to connected devices

Serial.begin(115200);
delay(200);
Serial.println("[setup] Davis Anemometer");

// Define the interrupt pin

PINMODE_INPUT_PULLUP(windSpeedPin);
}

void loop () {
measureWind();
delay(reportingPeriod);
}

void initialiseWindCount() {
windCounter = 0;
}

void incrementWindCount() {
windCounter++;
}

void measureWind() {
uint32_t startTime, endTime;
uint16_t rotations = 0;
uint16_t windSpeed = 0;
uint16_t windBearing = 0;
uint16_t totalWindBearing = 0;
//uint16_t bearingCalibrationOffset = 0;// See comment below
uint8_t averageCount = 5; // Number of direction readings to take and average

/*
For the Davis 6410 anemometer, 1000 revolutions per hour = 1 kilometre per hour
Our time interval is measured in milliseconds

calibrationSpeed= 1// kilometres per hour
calibrationRotations= 1000// rotations per hour
timeUnits= 3600000// milliseconds per hour

For wind speed calculations:

scalingFactor = calibrationSpeed * timeUnits / calibrationRotations
*/


int scalingFactor = 3600;

initialiseWindCount();
Serial.println("[measureWind] Begin wind sampling...");
attachInterrupt(windSpeedPin,incrementWindCount,FALLING);
startTime = millis();

for (int i = 0; i < averageCount; i++) {
totalWindBearing = totalWindBearing + readWindBearing();
delay(1000);
}
windBearing = totalWindBearing / averageCount;

/*
If the anemometer arm cannot be set pointing true north
(see User Manual), a wind bearing calibration offset
must be set according to the direction it does point and
the above line of code replaced by the following lines:

windBearing = bearingCalibrationOffset + totalWindBearing / averageCount;
if (windBearing > 360) {
windBearing = windBearing - 360;
} else if (windBearing < 0) {
windBearing = windBearing + 360;
}
*/


detachInterrupt(windSpeedPin);
endTime = millis();
Serial.println("[measureWind] End wind sampling");

rotations = windCounter;
windSpeed = (int) (scalingFactor * rotations / (endTime - startTime));

Serial.print("[measureWind] Rotations : ");
Serial.println(rotations);
Serial.print("scalingFactor : ");
Serial.println(scalingFactor);
Serial.print("startTime : ");
Serial.println(startTime);
Serial.print("endTime : ");
Serial.println(endTime);
Serial.print("Wind Speed : ");
Serial.print(windSpeed);
Serial.println(" kph");

Serial.print("[measureWind] Bearing : ");
Serial.print(windBearing);
Serial.println(" °");

compassDirection(windBearing);
}

uint16_t readWindBearing() {
//return adc level 0-4095; Need to calibrate to find max value for configuration
uint16_t windReading = analogRead(ADC3);
// Serial.print("[readWindBearing] Wind Reading ");
// Serial.println( windReading );
uint16_t windBearing = myMap(windReading, 0, 3806, 0, 359);
return windBearing;
}

uint16_t myMap(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) {
if ((in_max - in_min) > (out_max - out_min)) {
return (x - in_min) * (out_max - out_min+1) / (in_max - in_min + 1) + out_min;
} else {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
}

void compassDirection( uint16_t windBearing ) {
Serial.print("[compassDirection] ");
if (windBearing > 169) {
if (windBearing > 259) {
if (windBearing > 304) {
if (windBearing > 326) {
if (windBearing > 349) {
Serial.print("N");
} else { // 326 < windBearing <= 349
Serial.print("NNW");
}
} else { // 304 < windBearing <= 326
Serial.print("NW");
}
} else { //windBearing <= 304
if ( windBearing > 281) {
Serial.print("WNW");
} else { // 259 < windBearing <= 281
Serial.print("W");
}
}
} else { // windBearing <= 259
if ( windBearing > 214) {
if ( windBearing > 236) {
Serial.print("WSW");
} else { // 214 < windBearing <= 236
Serial.print("SW");
}
} else { // windBearing <= ?
if ( windBearing > 191) {
Serial.print("SSW");
} else { // 169 < windBearing <= 191
Serial.print("S");
}
}
}
} else { // windBearing <= 169
if ( windBearing > 79 ) {
if ( windBearing > 124) {
if ( windBearing > 146) {
Serial.print("SSE");
} else { // 124 < windBearing <= 146
Serial.print("SE");
}
} else { // 101 < windBearing <= 124
if ( windBearing > 101) {
Serial.print("ESE");
} else { // 79 < windBearing <= 101
Serial.print("E");
}
}
} else { // windBearing <=79
if ( windBearing > 34) {
if ( windBearing > 56) {
Serial.print("ENE");
} else { // 34 < windBearing <= 56
Serial.print("NE");
}
} else { // windBearing <= 34
if ( windBearing > 11) {
Serial.print("NNE");
} else { // 349 < windBearing <= 11
Serial.print("N");
}
}
}
}
Serial.println();
}
Weather Station Application

The Weather Station application sketch can be downloaded by clicking on the following link. The EEPROMHandler and PacketHandler libraries can be downloaded from their respective downloads pages and the CubeCell Plus pin definition file from the CubeCell Platform page. I'll provide a complete description of what's going on at some point, but for the time being you'll need to look at the descriptions under each of the relevant sensors to see what's happening in each case.

The reader may also need to refer to the section on LoRa configuration.

Place the Weather Node sketch folder in the Arduino IDE root folder (Arduino). If running on a Heltec CubeCell Plus module, as is currently configured, this sketch also requires the latest version of the Heltec [CubeCell] hardware support libraries.

ZIP Weather Node [v2.3.2] 31-Aug-2024 [8 KB]

Update: 30 Nov 2022 I only recently discovered that the above will probably not be entirely compatible with the version of the gateway software that is provided elsewhere on this site. The following is a version that uses the PacketHandler library. Once the PacketHandler and the relevant support files are installed, the following sketch should compile and run on the V1 & V2 Heltec WiFi LoRa 32 boards or the ESP32-WROOM-32 board, also described elsewhere on this site.

h WiFi LoRa V2 Gateway [v2.2.2] 17-Nov-2023 [9 KB]

Documentation

PDF Davis 6410 Technical Specifications [279 KB]
PDF Davis 6410 User Manual [795 KB]
10-12-2024