#!/usr/bin/python # # $ Anemoneter # $ Beta 6: Revision 004e $ # $ Author: WhimickRH $ # $ US - UK $ # $ Date: 2017-10-28 $ # $ Wind_Rain $ # $ For GrovePi Weather Station $ # $ Raspberry Pi Wind Vane $ # $ # --------------------------------IMPORT DEPENDENCIES----------------------------------------- from __future__ import with_statement import os import os.path import sys import time import threading import multiprocessing import numpy as np import cPickle import pprint import logging import traceback # --------------------------------GROVEPI----------------------------------------------------- import smbus import RPi.GPIO as GPIO import grovepi from grovepi import * import Adafruit_ADS1x15 # --------------------------------PATH AND MODULES-------------------------------------------- # sys.path.append('/home/pi/Weather_Sensors') # import SDL_DS3231 # --------------------------------GROVEPI BOARD & SENSOR SET UP------------------------------- rev = GPIO.RPI_REVISION if rev == 2 or rev == 3: bus = smbus.SMBus(1) else: bus = smbus.SMBus(0) GPIO.setwarnings(False) # GROVE SENSORS anemometer = 5 # Pin 5 is D5 Port. ----- Anemometer rain_tipper = 6 # Pin 6 is D6 Port. ----- Rain_Tipper grovepi.pinMode(anemometer, "INPUT") # Anemometer grovepi.pinMode(rain_tipper, "INPUT") # Rain Tipper # 12C SENSORS adc = Adafruit_ADS1x15.ADS1115() # ADC ADS1115 GAIN = 1 # 5volts # --------SETUP LEDS-------------- red_led = 3 digitalWrite(red_led, 0) # -------------------------------ERROR LOGGING----------------------------------------------- logging.basicConfig(filename='/home/pi/WxRam/Wind_Sensors_Error.txt', filemode='a', level=logging.ERROR, format='%(asctime)s %(levelname)s %(name)s %(message)s') logger=logging.getLogger(__name__) # --------------------------------WIND VANE------------------------------------------------- speed_list = [] vane_record_no = 0 class WeatherVane(object): # Common base class for all WindRain def __init__(self): self.starttime = time.time() self.Software_Version = "Wind_Rain6_beta_004e" self.vane_record_no = vane_record_no # self.spin_distance = 0 # self.wind_trigger = 0 self.elapsed = 0 self.adc_value = 0 self.rain = 0 self.mps = 0 self.mph = 0 self.mph_list = speed_list self.mps_a = 0 self.mps_m = 0 self.av_mph = 0 self.av_kph = 0 self.mx_mph = 0 self.mx_kph = 0 self.pulse = 0 self.degrees = 0 self.bearing = "" self.wr_list = [] # -------------------------------READ SENSORS------------------------------------------------- def GetWindRain(self): print("Wind Loop Running") while True: self.adc_value = 0 # self.mps = 0 pulse = 0 wind_trigger = 0 spin_distance = 0 rain = 0 start_time = time.time() max_time = start_time + 5 radius_cm = 9.0 # Radius of the anemometer adjustment = 1.18 # Adjustment for weight of cups rain_trigger = 0 # print("New_Loop", self.vane_record_no) while time.time() <= max_time: if grovepi.digitalRead(anemometer) == 1 and wind_trigger == 0: wind_trigger = 1 spin_distance += 0.282743 pulse +=1 # print("Pulse Detected", self.pulse, "trigger", wind_trigger) digitalWrite(red_led, 1) self.adc_value = adc.read_adc(1, gain=GAIN, data_rate=250) if grovepi.digitalRead(rain_tipper) == 1 and rain_trigger == 0: rain_trigger = 1 rain = 1 if grovepi.digitalRead(rain_tipper) == 0 and rain_trigger == 1: rain_trigger = 0 if grovepi.digitalRead(anemometer) == 0 and wind_trigger == 1: wind_trigger = 0 digitalWrite(red_led, 0) self.elapsed = round(time.time() - start_time, 4) self.mps = round((spin_distance / self.elapsed) * adjustment, 4) self.rain = rain # print("MPS", self.mps) # print("ADC", self.adc_value) # print("Rain",self.rain) # --------------------------------WIND VANE CALULATIONS--------------------------------------- def calculations(self): # print("values", self.mps, self.adc_value, self.rain) self.beaufort_description = "Calm" self.mph = round(self.mps * 2.2369, 2) self.kph = round(self.mps * 3.6, 2) self.kts = round(self.mps * 1.9438444924574, 2) self.bf = int((self.mph + 6) / 6) self.mph_list.insert(0, self.mph) self.mph_av = round(np.mean(self.mph_list),2) self.mph_mx = round(np.nanmax(self.mph_list),2) self.kph_av = round((self.mph_av * 1.609344),2) self.kph_mx = round((self.mph_mx * 1.609344),2) if len(self.mph_list) == 6: self.mph_list.pop() beaufort_number = ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) description = (["Calm", "Light air", "Light breeze", "Gentle breeze", "Moderate breeze", "Fresh breeze", "Strong breeze ", "Moderate gale,", "Gale", "Strong gale", "Storm", "Violent storm", "Hurricane"]) eof_bf = int(len(beaufort_number)) for b in range(0, eof_bf): if self.bf == beaufort_number[b]: self.beaufort_description = description[b] if self.bf < 1: self.beaufort_description = 0 if self.bf > beaufort_number[b]: self.beaufort_description = 12 # self.kph_av = round(np.mean(self.kph_list), 4) # self.kph_mx = round(np.nanmax(self.kph_list), 4) self.voltageValue = round((self.adc_value * 0.1875) / 1000, 2) adcv = ([3.84, 1.98, 2.25, 0.41, 0.45, 0.32, 0.90, 0.62, 1.40, 1.19, 3.08, 2.93, 4.62, 4.04, 4.34, 3.43]) angle = ([0.0, 22.5, 45, 67.5, 90.0, 112.5, 135.0, 157.5, 180.0, 202.5, 225, 247.5, 270.0, 292.5, 315.0, 337.0]) nsew = (["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "N"]) eof_l = len(adcv) for d in range(0, eof_l): if self.voltageValue >= adcv[d] - 0.05 and self.voltageValue <= adcv[d] + 0.05: self.degrees = angle[d] self.bearing = nsew[d] self.rain_in = round(self.rain * 0.011, 2) self.rain_mm = round(self.rain * 0.2794, 2) #print("Calculation Vane","mph", self.mph, "bf", self.bf, "degrees", self.degrees) #print("Calculation Vane", "Average MPS:", self.mph_av, "Max MPS:", self.mph_mx, self.voltageValue) # --------------------------------WIND VANE DISPLAY--------------------------------------- """ print print("----------------------------------------------------------------------") print("Record No:", self.vane_record_no, time.strftime("%Y %m %d - %H:%M:%S"), "Wind Vane Version:", self.Software_Version) # print(time.strftime("%Y %m %d - %H:%M:%S")) print("-----------------------------------------") print("Wind speed mp/s:", self.mps, "MPH:", self.mph, "KPH:", self.kph, "KTS:", self.kts) print("Lists", self.mph_list) print("-----------------------------------------") print("Average mph:", self.mph_av, "Maximum mph:", self.mph_mx, "Average kph:", self.kph_av, "Maximum kph:", self.kph_mx) print("-----------------------------------------") print("Beaufort_description:", self.beaufort_description, "Beaufort_number", self.bf) print("-----------------------------------------") print("ADC voltage volts:", self.voltageValue, "Wind direction degrees:", self.degrees, "Wind bearing:", self.bearing) print("-----------------------------------------") """ # --------------------------------cPickle File----------------------------------------------- wind_list = ([self.mps, self.mph, self.kph, self.kts, self.bf, self.beaufort_description, self.mph_av, self.mph_mx,]) wind_list.extend([self.kph_av, self.kph_mx, self.voltageValue, self.degrees, self.bearing, self.rain_in, self.rain_mm]) # print(wind_list) wl = open("/home/pi/WxRam/wind_list.txt", 'w') cPickle.dump(wind_list, wl) wl.close() return # --------------------------------WIND VANE TIMER LOOP---------------------------------------- def timing(self): # thread_no = 0 # thread_thread_no = threading.Thread(name='Windloop', target=self.calculations) # thread_A.daemon = True # thread_thread_no.setDaemon(True) # thread_thread_no.start() while True: DoSums = multiprocessing.Process(target=self.calculations) DoSums.start() # self.calculations() time.sleep(5.0 - ((time.time() - self.starttime) % 5.0)) self.vane_record_no += 1 # thread_no += 1 # print("thread_no", thread_no) # --------------------------------MAIN--------------------------------------------------------- def main(): print("Wind Vane Starting up") Vane = WeatherVane() Read_Vane = threading.Thread(name='Read_Vane', target=Vane.GetWindRain) Read_Vane.setDaemon(True) Read_Vane.start() Vane.timing() return if __name__ == '__main__': try: main() except Exception as e: digitalWrite(red_led, 0) logging.exception(str(e)) print(logging.exception(str(e))) GPIO.cleanup() sys.exit() # --------------------------------INFORMATION------------------------------------------------- """ 3 Cup Anemomenter r = 9 cm 1 Pulse = 28.274333882308 cm or .28274333882308 meter C = 56.548667764616 cm or 2 pulses .56548667764616 meter A = 254.46900494077 cm2 TO TRAVEL X METERS IS Y PULSES 1m = 3.5 Pulses 10m = 35.36 pulses 100m = 353.6 pulses RAIN TIPPER Rain_ins = tip * 0.011 Rain_mm = tip * 0.2794 1 Second = 1000000 microseconds thread_wind_loop = 0 thread_stopper = threading.Event() # create a thread object which will run Wind loop and Wind gust on start thread_wind_loop = threading.Thread(target=self.vane_calculations) thread_wind_loop.daemon = True thread_wind_loop.start() self.record_no = 0 while thread_stopper.is_set() is False: thread_wind_loop.start() print("thread_wind_loop not running") #thread_wind_loop.start() # self.readSensors() # self.vane_calculations() # self.display_on_screen() # time.sleep(5) self.record_no +=1 thread_wind_loop +=1 """