-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathweathervane.py
executable file
·126 lines (104 loc) · 3.93 KB
/
weathervane.py
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
120
121
122
123
124
125
126
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim: set expandtab tabstop=4 shiftwidth=4 :
# weathervane.py - A module that that gets readings from a standard multiple
# switches-and-resisters weather vane (wind vane) connected to GPIO pin 6
# (RasPi header pin 31). After
# https://projects.raspberrypi.org/en/projects/build-your-own-weather-station/7
# By: The Doctor <drwho at virtadpt dot net>
# License: GPLv3
# v1.1 - Reworked the weather vane signal interpretation code because my unit
# isn't stable. I still hate hardcoding magick numbers but this way
# actually makes the 'vane usable.
# v1.0 - Initial release.
# TO-DO:
# - Make the channel of the ADC chip configurable.
# - Use real logger code rather than a bunch of print()s.
# - The table of values-to-directions should probably be configurable, but I'm
# not sure yet how to do that.
# - Add a utility that helps a user calculate their own table of direction/
# values?
# Load modules.
import gpiozero
import logging
import sys
import time
import globals
# Constants.
# Channel (pin) of the ADC the weather vane is connected to.
channel = 0
# Value of the reference voltage the ADC is receiving on pin 15. The circuit
# I'm using (and hardwired) draws power from pin 1 on the RasPi (3.3 VDC).
reference_voltage = 3.3
# Global variables.
# I originally used this research code to generate the values for my weather
# vane (and you should, too, just to be safe), but I found that even then the
# values aren't necessarily stable. There's a noticeable variation in the
# signal even though it's coming from a static resistor. So, I hardcoded a
# heuristic (+/- 0.1) in the core code to make it work somewhat more reliably.
# I need to make the values and the heuristics configurable so that more folks
# can use this code without having to hand-hack my code.
#
# import gpiozero
# import time
# adc = gpiozero.MCP3008(channel=0)
# values = []
# while True:
# wind = round(adc.value * 3.3, 1)
# if not wind in values:
# values.append(wind)
# print("Got new value: %s" % wind)
# print()
# time.sleep(5)
#
# Core code...
# get_direction(): The function that does everything by calling everything
# else. Here so that it can be called from Weather Station Bot's central
# module, as well as __main__ for testing. Returns a hash table containing
# the sample data.
def get_direction():
# Voltage from the weather vane.
value = 0.0
# Set up the GPIO object.
if not globals.weathervane:
globals.weathervane = gpiozero.MCP3008(channel=channel)
# Get a sample from the weather vane.
value = round(globals.weathervane.value * reference_voltage, 1)
logging.debug("Value from the weather vane: %s" % value)
# Interpret the value from the weather vane.
if (value >= 2.0) and (value <= 2.2):
return("north")
if (value >= 1.7) and (value <= 1.9):
return("northeast")
if (value >= 2.9) and (value <= 3.1):
return("east")
if (value >= 2.6) and (value <= 2.8):
return("southeast")
if (value >= 2.3) and (value <= 2.5):
return("south")
if (value >= 1.2) and (value <= 1.4):
return("southwest")
if (value >= 0.1) and (value <= 0.3):
return("west")
if (value >= 0.9) and (value <= 1.1):
return("northwest")
# No match.
return None
# Exercise my code.
if __name__ == "__main__":
# Configure the logger. DEBUG for interactive testing.
logging.basicConfig(level=10, format="%(levelname)s: %(message)s")
logger = logging.getLogger(__name__)
print("Starting test run.")
sensor = gpiozero.MCP3008(channel=channel)
for i in range(10):
temp = None
temp = get_direction()
if temp:
print("The weather vane is pointing %s." % temp)
else:
print("The weather vane returned a spurious value. I saw: %s" % temp)
time.sleep(5)
print("End of test run.")
sys.exit(0)
# Fin.