Author Topic: Homemade Weather Station using a Raspberry Pi  (Read 48682 times)

0 Members and 1 Guest are viewing this topic.

Offline weathernick

  • Senior Member
  • **
  • Posts: 89
Re: Homemade Weather Station using a Raspberry Pi
« Reply #50 on: March 07, 2015, 11:46:45 PM »
Yea those sensors are sealed... I just broke the seal when mounting it. The only description I have is via this forum.

As for the heat. Turns out the Rasp Pi can take a lot of heat and does perfectly fine in the summer out here. I had to get a better wifi usb adapter because of the heat but that might have been a power issue that I resolved by getting a 2amp powered hub. As long as you keep the RPi out of direct sunlight you should be fine.

Nick
PWS: Custom built with Raspberry Pi collecting the data from the sensors.
CWOP: EW5462
Wunderground: KAZYUMA27
Personal WX page: http://mccolls.weewx.s3-website-us-east-1.amazonaws.com/

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #51 on: March 08, 2015, 03:04:53 PM »
I guess the Rasp PIs are pretty rugged. I was going to try to run mine off a 12v battery hooked to a trickle charger or possible solar setup, I worry about power going out and corrupting the SD card. I got a couple of 12v regulated adjustable (1-12v) power supplies off ebay.  I also bought 4 of the latest Pi 2s to experiment with.  I'm going to use one to display the weather data inside with a small HDMI display.

I might have missed it in the forum, I'm wondering how you did the wind speed and the rain bucket. The Inspeed E-VANE2 can use a A/D converter but how did you manage to query the pulses from the anemometer? I see they have one that gives 8 pulses per rotation:

http://www.inspeed.com/anemometers/8-Pulse%20Anemometer.asp

I installed Weewx to see how everything works. It's really nice, gives you lots of flexibility. I mounted a network drive to store the data and web pages to save writes to the card.

Thanks again, I hope you don't mind all the questions.

Offline geofb13

  • Contributor
  • ***
  • Posts: 131
Re: Homemade Weather Station using a Raspberry Pi
« Reply #52 on: March 08, 2015, 06:55:23 PM »
Some updates:

My station has been running for over 9 months now and here are the list of events that have occurred:

....

Thanks for the update Nick! I'm glad to see everything is still running well for the most part.

I guess the Rasp PIs are pretty rugged. I was going to try to run mine off a 12v battery hooked to a trickle charger or possible solar setup, I worry about power going out and corrupting the SD card. I got a couple of 12v regulated adjustable (1-12v) power supplies off ebay.  I also bought 4 of the latest Pi 2s to experiment with.  I'm going to use one to display the weather data inside with a small HDMI display.

I might have missed it in the forum, I'm wondering how you did the wind speed and the rain bucket. The Inspeed E-VANE2 can use a A/D converter but how did you manage to query the pulses from the anemometer? I see they have one that gives 8 pulses per rotation:

http://www.inspeed.com/anemometers/8-Pulse%20Anemometer.asp

Thorn I have a couple raspberry pi & arduino based stations running off a 12v battery/solar set up. Generally the only problem that I've come across with using the Pi it which is probably in the coding I got, is that I have it set to restart the pi every few days. For whatever reason it was having a hiccup and recorded the data coming from the sensors but wasn't sending it out anymore. Other then that, I think the other big issue this one related to the battery connection was one of the batteries did run dry and shorted something. That's now been fixed with some extra code on our side to get the voltage sent over along with the sensor data. That way hopefully that won't happen again, but I've got at least 1-3 extra SD cards with the same coding already loaded on it so I can just pop in  and go for the most part in the event of another similar issue.

Hope that helps give you some more ideas!


Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #53 on: March 08, 2015, 07:46:56 PM »


Thorn I have a couple raspberry pi & arduino based stations running off a 12v battery/solar set up. Generally the only problem that I've come across with using the Pi it which is probably in the coding I got, is that I have it set to restart the pi every few days. For whatever reason it was having a hiccup and recorded the data coming from the sensors but wasn't sending it out anymore. Other then that, I think the other big issue this one related to the battery connection was one of the batteries did run dry and shorted something. That's now been fixed with some extra code on our side to get the voltage sent over along with the sensor data. That way hopefully that won't happen again, but I've got at least 1-3 extra SD cards with the same coding already loaded on it so I can just pop in  and go for the most part in the event of another similar issue.

Hope that helps give you some more ideas!

I have a Rasp Pi running a VOIP application and it's been running since April on the grid with a UPS, I have not had to replace a  SD card in it yet.  It doesn't do as much as one that would be collecting data. I also have a couple PIs running motion for security cameras 24/7. I lost 2 cards because I unplugged them by accident. The were cheaper cards.

How do you monitor battery voltage? I would guess a sensor.  :-)

Thanks, Greg

Offline geofb13

  • Contributor
  • ***
  • Posts: 131
Re: Homemade Weather Station using a Raspberry Pi
« Reply #54 on: March 08, 2015, 10:26:42 PM »
I have a Rasp Pi running a VOIP application and it's been running since April on the grid with a UPS, I have not had to replace a  SD card in it yet.  It doesn't do as much as one that would be collecting data. I also have a couple PIs running motion for security cameras 24/7. I lost 2 cards because I unplugged them by accident. The were cheaper cards.

How do you monitor battery voltage? I would guess a sensor.  :-)

Thanks, Greg

There's two seperate ways that I monitor it depending on if the Pi is out in the field or for one that is close enough to use WiFi but is still running off a battery.

Most of it is just using an Analog to Digital Converter and two voltage dividers  and connect it to a GPIO pin if I'm remembering correctly. Here's an example of one that was just running on a LiPo battery and needed to shut off before the power got too low. The idea is similar if you're using a non-LiPo battery, or something connected to a solar panel with a charge controller. The only difference would be how you'd connect the dividers to the battery and what the dividers are rated at.

The other way I monitor it is with one that's connected to a Xbee transmitter. You can ping the pin that the Xbee has connected to the power. They are basically the same idea as the Xbee already has the ADC in it so if it's connected to something like that you can remove a piece. With that said you'd probably have an ADC for the Pi anyway for some of the sensors.

Afterwards it would just be the code to have the Pi to shut off, send an email or add a message with the data sent to notify you.

Offline Bushman

  • Forecaster
  • *****
  • Posts: 6679
    • Eagle Bay Weather
Re: Homemade Weather Station using a Raspberry Pi
« Reply #55 on: March 08, 2015, 10:45:03 PM »
I would caution anyone that  EACH cell in a lipo needs to be monitored for LVC.  It is possible to have say, a 3S (three cells) where one discharges past LVC and then you gots probs!

Offline weathernick

  • Senior Member
  • **
  • Posts: 89
Re: Homemade Weather Station using a Raspberry Pi
« Reply #56 on: March 09, 2015, 03:37:52 PM »
I might have missed it in the forum, I'm wondering how you did the wind speed and the rain bucket. The Inspeed E-VANE2 can use a A/D converter but how did you manage to query the pulses from the anemometer? I see they have one that gives 8 pulses per rotation:

http://www.inspeed.com/anemometers/8-Pulse%20Anemometer.asp

Pulses from the anemometer and the precip sensor are taken care of via the GPIO pins on the RPi. You can think of pulses as digital inputs. The wind sensor will produce 8 pulse per rotation. So in the code you listen to the wind sensor and count the pulses. I do per second but you can do any time period. At the end of the time period just count the pulses and apply some math to get it to mph. The precip sensor creates pulses everytime the tipping bucket empties, so 0.01" for each pulse.

You will need to remember to use a basic RC filter if you want to rid your self of noises on the GPIO. Otherwise lightning will induce all kinds of errors. You won't see it much in the wind data but you will see it in the precip. :)

The wind sensor was the easiest and fastest sensor to code for in this project.

Nickolas
PWS: Custom built with Raspberry Pi collecting the data from the sensors.
CWOP: EW5462
Wunderground: KAZYUMA27
Personal WX page: http://mccolls.weewx.s3-website-us-east-1.amazonaws.com/

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #57 on: March 10, 2015, 01:00:34 PM »
I might have missed it in the forum, I'm wondering how you did the wind speed and the rain bucket. The Inspeed E-VANE2 can use a A/D converter but how did you manage to query the pulses from the anemometer? I see they have one that gives 8 pulses per rotation:

http://www.inspeed.com/anemometers/8-Pulse%20Anemometer.asp

Pulses from the anemometer and the precip sensor are taken care of via the GPIO pins on the RPi. You can think of pulses as digital inputs. The wind sensor will produce 8 pulse per rotation. So in the code you listen to the wind sensor and count the pulses. I do per second but you can do any time period. At the end of the time period just count the pulses and apply some math to get it to mph. The precip sensor creates pulses everytime the tipping bucket empties, so 0.01" for each pulse.

You will need to remember to use a basic RC filter if you want to rid your self of noises on the GPIO. Otherwise lightning will induce all kinds of errors. You won't see it much in the wind data but you will see it in the precip. :)

The wind sensor was the easiest and fastest sensor to code for in this project.

Nickolas


Thanks, I'll have to read up some more on how the GPIOs work. I built a Geiger counter from a kit and I'm reading it through the USB for now. I saw some info on how to wire it directly to the Pi. I also got a UV sensor that should work through the I2C, I have the baro/temp and humidty working through the I2C.

But the rain sensor signal/pulse could come at any time. Do you have to have a interrupt of some sort to keep an eye on it?  The wind you can just sample every sec. or so.

Thanks!
Greg

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #58 on: March 10, 2015, 01:07:50 PM »


There's two seperate ways that I monitor it depending on if the Pi is out in the field or for one that is close enough to use WiFi but is still running off a battery.

Most of it is just using an Analog to Digital Converter and two voltage dividers  and connect it to a GPIO pin if I'm remembering correctly. Here's an example of one that was just running on a LiPo battery and needed to shut off before the power got too low. The idea is similar if you're using a non-LiPo battery, or something connected to a solar panel with a charge controller. The only difference would be how you'd connect the dividers to the battery and what the dividers are rated at.

The other way I monitor it is with one that's connected to a Xbee transmitter. You can ping the pin that the Xbee has connected to the power. They are basically the same idea as the Xbee already has the ADC in it so if it's connected to something like that you can remove a piece. With that said you'd probably have an ADC for the Pi anyway for some of the sensors.

Afterwards it would just be the code to have the Pi to shut off, send an email or add a message with the data sent to notify you.

That's neat. I have a couple of those adjustable power supplies that I see in the one photo. They were only $2. The battery would make a good UPS on other Pi projects I have. I have a large sealed spare 12v battery that I plan  to use and it would be nice to have the Pi shutdown nicely.

Greg

Offline DaleReid

  • Forecaster
  • *****
  • Posts: 1201
    • Weather at Eau Claire, WI
Re: Homemade Weather Station using a Raspberry Pi
« Reply #59 on: March 10, 2015, 04:44:02 PM »
As far as monitoring to count pulses, I've got the same question that Greg (thorn) does on how to do this.

Do you go to a set routine that counts for exactly one second, and then returns to doing other stuff?  No sense in monitoring the temperature or barometric pressure too often, but wind and wind gusts are likely the most variable and could 'hijack' the system entirely for a second to count pulses every now and then and do OK.

Just curious as to what solution you worked out.
Dale
ECWx.info
&
ECWx.info/t/index.php

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #60 on: March 10, 2015, 05:56:36 PM »
As far as monitoring to count pulses, I've got the same question that Greg (thorn) does on how to do this.

Do you go to a set routine that counts for exactly one second, and then returns to doing other stuff?  No sense in monitoring the temperature or barometric pressure too often, but wind and wind gusts are likely the most variable and could 'hijack' the system entirely for a second to count pulses every now and then and do OK.

Just curious as to what solution you worked out.
Dale


Here's something about it: http://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/

http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-3

I have used interrupts in C using threads before.

With the rainfall you would need to accumulate the values if it is already raining or it would be a new rain event so one would have keep track of it. Or does weewx keep track of it?

Greg

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #61 on: April 03, 2015, 10:50:26 PM »
I have been working on my wx station and have some of it ready to mount in the waterproof case I got.  Now I need to do some of the programming to save the data to a text file.

Here's a photo of it:

« Last Edit: December 16, 2016, 10:35:15 AM by thorn »

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #62 on: April 13, 2015, 01:25:04 PM »


I put my DIY weather station outside temporarily, I have temp, hum, baro, light, wind speed and dir. I have been trying to get the wind speed to work. Yesterday there were light winds and everything seem to be working, Today it's around 10mph (according to my older Davis station) but it's only recording 1-2 mph even though it's spinning like crazy. I guess it must be missing pulses on the GPIO.  I Googled but did not find much. I thought it might be related to bounce but I guess that's false extra sensing. 

Does anyone have some code posted somewhere so I can see how you guys have done it? I tried both the "add_event_detect" as a thread and "wait_for_edge" with the same results. I guess the Pi 2 should be able to count pretty fast. I have the 8 pulse/revolution anemometer from Inspeed (0.31 factor to convert to Mph). 

I just have Python scripts for now to get it working. I may try to put the code calling the sensors directly into the driver.

Thanks, Greg

Offline weathernick

  • Senior Member
  • **
  • Posts: 89
Re: Homemade Weather Station using a Raspberry Pi
« Reply #63 on: June 10, 2015, 12:57:12 PM »
Sorry I was gone for a little bit. Here is my code that uses Python to interface into the 8 pulse wind sensor. I basically setup an GPIO.add_event_detect to count the pulses from the wind sensor. Then every "second" I sum the count and apply the correct multipliers. I time stamp every "second" as that tends to drift based on the load on the system. I than take the correct time interval (normally 1 second but can be as long as 1.7 seconds) to correct my value. Here is the code.
Code: [Select]
import math
import spidev
import RPi.GPIO as GPIO
import time
from time import strftime, localtime

# Global variables
wind_start_time = time.time()
wind_pulse_cnt = 0
peak_3s_wind = []
wind_dir_adc_min = float(.15)  # Zero degree wind dir is around .1 volts
wind_dir_adc_max = float(3.05)  # 360 degree wind dir is around 3 volts

# ------------------CONFIGURATION--------------------------
# Wind speed
wind_10m_multiplier = float(4.02336) / float(8)  # km/h
wind_10m_GPIO_port = 22

# Wind Direction
wind_dir_channel = 0
wind_dir_offset = 171  # Degrees to rotate CC to equal actual direction.
# ------------------END OF CONFIGURATION --------------------

# Configure the GPIO for the RPi
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

# Open spi port to ADC
spi = spidev.SpiDev()
spi.open(0, 0)  # 12bit ADC MCP3208
spi.max_speed_hz = (500000)

# Function that counts pulses from 10m wind sensor
def callback_windsp_10m(channel):
    global wind_pulse_cnt
    wind_pulse_cnt += 1

# monitor GPIO for pulses from wind sensor
GPIO.add_event_detect(wind_10m_GPIO_port,
                      GPIO.FALLING,
                      callback=callback_windsp_10m,
                      bouncetime=1)

# Function to get data from Wind Speed Sensor
# Wind speed sends 8 pulses per revolution. Time is need to complete
# calculations. Normally this is one second but delays in program
# run time can change that. We use wind_end_time and wind_start_time
# to correctly get the time inverval between obs.
def get_10m_wind_speed():
    global wind_pulse_cnt
    global wind_start_time
    global peak_3s_wind
    wind_end_time = time.time()
    wind_speed = ((wind_pulse_cnt * wind_10m_multiplier) /
                  (wind_end_time - wind_start_time))
    wind_pulse_cnt = 0  # reset counter
    wind_start_time = wind_end_time  # Reset timer for winds
    peak_3s_wind.insert(0, wind_speed)
    if len(peak_3s_wind) == 4:
        peak_3s_wind.pop()
    avg_peak_wind = 0
    for peak_wind in peak_3s_wind:
        avg_peak_wind = avg_peak_wind + peak_wind
    avg_peak_wind = float(avg_peak_wind / len(peak_3s_wind))
    return wind_speed, avg_peak_wind


# Function to get data from Wind Vane Sensor
def get_10m_wind_dir():
    global wind_dir_adc_min, wind_dir_adc_max
    # single-ended measurement see mcp3208_test for differental code
    r1 = spi.xfer2([6 + (wind_dir_channel >> 2),
                   (wind_dir_channel & 3) << 6,
                   0])
    adcout1 = float(((r1[1] & 15) << 8) + r1[2]) / float(4095) * 3.3

    # This dynamically changes the range of the sensor since it might change.
    f = open('/home/weewx/bin/wind_adjustment.txt', 'a')
    datetime = strftime("%Y-%m-%d %H:%M:%S", localtime())
    if adcout1 < wind_dir_adc_min:
        wind_dir_adc_min = adcout1
        data = "%s Wind adc min changed to : %.2f\n" % (datetime, adcout1)
        f.write(data)
    if adcout1 > wind_dir_adc_max:
        wind_dir_adc_max = adcout1
        data = "%s Wind adc max changed to : %.2f\n" % (datetime, adcout1)
        f.write(data)
    f.close()
    wind_dir = round(float((adcout1 - wind_dir_adc_min) /
                     float(wind_dir_adc_max - wind_dir_adc_min)) *
                     float(360), 0)

    # Apply offset
    wind_dir = wind_dir + wind_dir_offset
    if wind_dir > 360:
        wind_dir = wind_dir - 360

    return wind_dir

# Main Program. Sample all the sensors and created data file.
# This data file can then be picked up by ingester (WEEWX)
while True:
    # Get time
    start_time = time.time()
    datetime = strftime("%Y-%m-%d %H:%M:%S", localtime())

    # Get Wind Direction
    winddir_10m = get_10m_wind_dir()
    # Get wind speed and three second peak. (WMO standard)
    windspd_10m, windspd_peak_10m = get_10m_wind_speed()
    if windspd_10m < 0.01:  # Wind speed is zero
        winddir_10m = None

    # Get End Times and calculate program pause to next collection
    end_time = time.time()
    proc_time = round(end_time - start_time, 4)
    if (proc_time > 1) or (math.ceil(end_time) > math.ceil(start_time)):
        sleep_time = 0 
    else:
        sleep_time = math.ceil(end_time) - end_time
    time.sleep(sleep_time)  # Sleep until beginning of next second


My full code is here for anyone who uses similar sensors.

Code: [Select]
#!/usr/bin/python
# This datalogger script is responsible for collecting meteorological
# information from the following sensors and  creating a named pipe that
# streams that information over to the weewx driver.
# Installed sensors:
#  SHT25 (Temperature/Humidity sensor) [i2c]
#  BMP180 (Pressure) [i2c]
#  Pyronometer (homemade) [ADC]
#  AS3935 (Lightning sensor) [i2c]
#  wxunderweatherstation Wind direction (inspeed) [ADC]
#  wxunderweatherstation Wind sensor (Inspeed) [GPIO, pulse]
#  Rainwise RAINEW 111 Tipping Bucket Rain Gauge [pulse]

# Last updated: 2015-04-28
# Created by Nickolas McColl


import math
import spidev
import RPi.GPIO as GPIO
import time
from time import strftime, localtime
from Adafruit_BMP085 import BMP085
import sht21
from RPi_AS3935 import RPi_AS3935  # Lightning Sensor

# Global variables
wind_start_time = time.time()
wind_pulse_cnt = 0
peak_3s_wind = []
precip_pulse_cnt = 0
lightning_cnt = 0
distance_sum = 0
wind_dir_adc_min = float(.15)  # Zero degree wind dir is around .1 volts
wind_dir_adc_max = float(3.05)  # 360 degree wind dir is around 3 volts
current_time = time.time()
temp = None
rh = None
precip_pulse_start_time = 0
precip_pulse_stop_time = 0

# ------------------CONFIGURATION--------------------------
# pressure
pres_mode = 1  # (0 ultralow power, 1 std, 2 high res, 3 ultrahigh res)
bmp = BMP085(0x77, pres_mode)  # BMP085 and BMP180 are identical

# Solar
solar_channel = 4
solar_multi = 5113  # taken from calibration at work

# Wind speed
wind_10m_multiplier = float(4.02336) / float(8)  # km/h
wind_10m_GPIO_port = 22

# Wind Direction
wind_dir_channel = 0
wind_dir_offset = 171  # Degrees to rotate CC to equal actual direction.

# Lightning Sensor
GPIO.setmode(GPIO.BCM)
sensor = RPi_AS3935(address=0x03, bus=1)
sensor.calibrate(tun_cap=0x0F)
sensor.set_indoors(False)
sensor.set_noise_floor(0)
lightning_port = 23   #   

# Precipitation
precip_port = 27
precip_multi = 0.0254  # Centimeters per tip

# ------------------END OF CONFIGURATION --------------------

# Configure the GPIO for the RPi
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(17, GPIO.OUT)  # Rain activity (Blue)
GPIO.setup(18, GPIO.OUT)  # Status activity (green)
GPIO.setup(wind_10m_GPIO_port, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(lightning_port, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(precip_port, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# Open spi port to ADC
spi = spidev.SpiDev()
spi.open(0, 0)  # 12bit ADC MCP3208
spi.max_speed_hz = (500000)


# Function that counts pulses from 10m wind sensor
def callback_windsp_10m(channel):
    global wind_pulse_cnt
    wind_pulse_cnt += 1


# Function that counts rain
def callback_precip(channel):

    global precip_pulse_cnt
    #precip_pulse_cnt = precip_pulse_cnt + 1  # each tip 1/100 inch
    f = open('/home/weewx/bin/rain.log', 'a')
    datetime = strftime("%Y-%m-%d %H:%M:%S ", localtime())
    f.write(datetime + ' Precip detected 0.01 \n')
    f.close()

    # turn off precip until error fixed. Make sure to turn it on below as well
    precip_pulse_cnt = 0

# Function that counts lightning strikes
def handle_interrupt(channel):
    time.sleep(0.003)
    global sensor
    reason = sensor.get_interrupt()
    f = open('/home/weewx/bin/lightning', 'a')
    datetime = strftime("%Y-%m-%d %H:%M:%S", localtime())
    if reason == 0x01:
        f.write(datetime + ': Noise level too high - adjusting \n')
        sensor.raise_noise_floor()  # Too much noise adjust
    elif reason == 0x04:
        f.write(datetime + ': Masking disturber\n')
        sensor.set_mask_disturber(True)  # Masking disturber
    elif reason == 0x08:
        f.write(
            datetime + ': Storm is ' +
            sensor.get_distance() + ' miles away!\n')
        global lightning_cnt, distance_sum
        GPIO.output(17, True)
        distance_sum = distance_sum + sensor.get_distance()
        lightning_cnt = lightning_cnt + 1
        GPIO.output(17, False)
    else:
        f.write(datetime + 'Called but nothing to do\n')
    f.close()

# monitor GPIO for pulses from wind sensor
GPIO.add_event_detect(wind_10m_GPIO_port,
                      GPIO.FALLING,
                      callback=callback_windsp_10m,
                      bouncetime=1)

# Monitor GPIO for lightning
GPIO.add_event_detect(lightning_port,
                      GPIO.FALLING,
                      callback=handle_interrupt)

# Monitor GPIO for Rain
GPIO.add_event_detect(precip_port,
                      GPIO.FALLING,
                      callback=callback_precip,
                      bouncetime=300)


# function to get data from SHT25.
def get_sfc_temprh():
    # Sample temp/rh ever 2 seconds. Alternate measurements.
    global temp, rh
    if (math.floor(time.time()) % 2) == 0:
        temp = sht21.SHT21(1).read_temperature()
    else:
        rh = sht21.SHT21(1).read_humidity()
        if (rh > 100):
            rh = 100

    return temp, rh


# Function to get data from Pressure sensor
def get_sfc_pres():
    global bmp
    if bmp:
        pres = bmp.readPressure()
        pres = (pres / float(100))  # Converts to hPa
    else:
        pres = None
    return pres


# Function to get data from Solar Sensor
def get_solar():
    # Single ended measurement
    samples = 100
    value_sum = 0
    for i in range(0, samples):
        r2 = spi.xfer2([6 + (solar_channel >> 2), (solar_channel & 3) << 6, 0])
        adcout2 = ((r2[1] & 15) << 8) + r2[2]
        value_sum = adcout2 + value_sum
    value_avg = float(float(value_sum / samples))
    solar = round(float(value_avg) / (4095) * float(3.3) *
                  float(solar_multi), 1)
    if solar < 5:
        solar = 0

    return solar


# Function to get data from Rain Gauge
def get_precip():
    global precip_pulse_cnt
#    precip = precip_pulse_cnt * precip_multi
#    precip_pulse_cnt = 0
    precip = None   
    return precip


# Function to get data from Wind Speed Sensor
# Wind speed sends 8 pulses per revolution. Time is need to complete
# calculations. Normally this is one second but delays in program
# run time can change that. We use wind_end_time and wind_start_time
# to correctly get the time inverval between obs.
def get_10m_wind_speed():
    global wind_pulse_cnt
    global wind_start_time
    global peak_3s_wind
    wind_end_time = time.time()
    wind_speed = ((wind_pulse_cnt * wind_10m_multiplier) /
                  (wind_end_time - wind_start_time))
    wind_pulse_cnt = 0  # reset counter
    wind_start_time = wind_end_time  # Reset timer for winds
    peak_3s_wind.insert(0, wind_speed)
    if len(peak_3s_wind) == 4:
        peak_3s_wind.pop()
    avg_peak_wind = 0
    for peak_wind in peak_3s_wind:
        avg_peak_wind = avg_peak_wind + peak_wind
    avg_peak_wind = float(avg_peak_wind / len(peak_3s_wind))
    return wind_speed, avg_peak_wind


# Function to get data from Wind Vane Sensor
def get_10m_wind_dir():
    global wind_dir_adc_min, wind_dir_adc_max
    # single-ended measurement see mcp3208_test for differental code
    r1 = spi.xfer2([6 + (wind_dir_channel >> 2),
                   (wind_dir_channel & 3) << 6,
                   0])
    adcout1 = float(((r1[1] & 15) << 8) + r1[2]) / float(4095) * 3.3

    # This dynamically changes the range of the sensor since it might change.
    f = open('/home/weewx/bin/wind_adjustment.txt', 'a')
    datetime = strftime("%Y-%m-%d %H:%M:%S", localtime())
    if adcout1 < wind_dir_adc_min:
        wind_dir_adc_min = adcout1
        data = "%s Wind adc min changed to : %.2f\n" % (datetime, adcout1)
        f.write(data)
    if adcout1 > wind_dir_adc_max:
        wind_dir_adc_max = adcout1
        data = "%s Wind adc max changed to : %.2f\n" % (datetime, adcout1)
        f.write(data)
    f.close()
    wind_dir = round(float((adcout1 - wind_dir_adc_min) /
                     float(wind_dir_adc_max - wind_dir_adc_min)) *
                     float(360), 0)

    # Apply offset
    wind_dir = wind_dir + wind_dir_offset
    if wind_dir > 360:
        wind_dir = wind_dir - 360

    return wind_dir


# Function to monitor for lightning
def get_lightning():
    global lightning_cnt
    count = lightning_cnt
    lightning_cnt = 0
    global distance_sum
    if count > 0:
        storm_distance = float(distance_sum / count)
    else:
        storm_distance = 0
    distance_sum = 0
#   count = None
#   storm_distance = None
    return count, storm_distance


# Function to get RPi's temperature
def get_pi_temp():
    f = open('/sys/class/thermal/thermal_zone0/temp', 'r')
    input = f.readline()
    if input:
        system_temp = float(input) / 1000
    else:
        system_temp = None
    return system_temp


# Main Program. Sample all the sensors and created data file.
# This data file can then be picked up by ingester (WEEWX)
while True:
    GPIO.output(18, True)  # turn led status light on.
    GPIO.output(17, False)  # turn lightning status light off.
    # Get time
    start_time = time.time()
    datetime = strftime("%Y-%m-%d %H:%M:%S", localtime())

    # Get Temperature and Humidity
    temperature_sfc, humidity_sfc = get_sfc_temprh()
    # Get Pressure
    pressure_sfc = get_sfc_pres()
    # Get Wind Direction
    winddir_10m = get_10m_wind_dir()
    # Get wind speed and three second peak. (WMO standard)
    windspd_10m, windspd_peak_10m = get_10m_wind_speed()
    if windspd_10m < 0.01:  # Wind speed is zero
        winddir_10m = None
    # Get Solar
    solar_sfc = get_solar()
    # Get Precip
    precip_sfc = get_precip()
    # Get Lightning Data
    total_lightning, lightning_distance = get_lightning()
    # Get System temperature
    system_temp = get_pi_temp()

    # Get End Times and calculate program pause to next collection
    end_time = time.time()
    proc_time = round(end_time - start_time, 4)
    if (proc_time > 1) or (math.ceil(end_time) > math.ceil(start_time)):
        sleep_time = 0 
    else:
        sleep_time = math.ceil(end_time) - end_time

#   Build data string
    data = "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n" % (
           datetime, pressure_sfc, windspd_10m,
           winddir_10m, temperature_sfc, humidity_sfc,
           precip_sfc, total_lightning, lightning_distance,
           solar_sfc, proc_time, system_temp, windspd_peak_10m)
    filename = time.strftime("%Y-%m-%d")

#   Write data to archive
    log = open('/home/weewx/data/' + filename + '.csv', 'a')
    log.write(data)
    log.close()

#   Write current data
    log2 = open('/home/weewx/bin/wxdata.csv', 'w')
    log2.write(data)
    log2.close()

    GPIO.output(18, False)  # turn led status light off
    time.sleep(sleep_time)  # Sleep until beginning of next second


« Last Edit: August 25, 2015, 05:17:37 PM by weathernick »
PWS: Custom built with Raspberry Pi collecting the data from the sensors.
CWOP: EW5462
Wunderground: KAZYUMA27
Personal WX page: http://mccolls.weewx.s3-website-us-east-1.amazonaws.com/

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #64 on: June 10, 2015, 09:27:11 PM »

Thanks weathernick. I kind of got it working using the file parse code in Weewx. I just check it (count pulses) every 20 secs, but I get a "kernel:[18311.296290] Disabling IRQ #49" error and it goes to 2mph always. After a reboot all is well for a day or so. All the other sensors work fine.  I couldn't find much about it searching Google.  I'll take a look at your code to see if it there's something I'm doing to cause my error. I still need to hook up the rain gauge. I'm in the middle of moving to a better location from my temp one. I do notice I get "downward" spikes on temp and humidity. It will record 32F for a low when it didn't get below 60F. I'm not sure if it's the sensor or my code, it happens on the humidity side of the same sensor.

Thanks again for posting the code!

Offline geofb13

  • Contributor
  • ***
  • Posts: 131
Re: Homemade Weather Station using a Raspberry Pi
« Reply #65 on: June 11, 2015, 07:22:34 AM »
I do notice I get "downward" spikes on temp and humidity. It will record 32F for a low when it didn't get below 60F. I'm not sure if it's the sensor or my code, it happens on the humidity side of the same sensor.

There are two issues that I know of with the AM2315's (or actually any of the versions from them): one of them is that like most cheap sensors there are malfunctioning issues that apparently send out spikes in the signal and thus the data. The second issue is with the timing which if off can give you the random drops or spikes in the temperature and humidity. I've had issues myself with the second one especially if the sensor is reading at a more continuous rate and it only ever seemed to happen after a certain length of time doing it. Hopefully Nick can give you more insight when he responds if he's had any issues but I just wanted to throw in my own two cents with what I've experienced.

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #66 on: June 12, 2015, 05:41:36 PM »

There are two issues that I know of with the AM2315's (or actually any of the versions from them): one of them is that like most cheap sensors there are malfunctioning issues that apparently send out spikes in the signal and thus the data. The second issue is with the timing which if off can give you the random drops or spikes in the temperature and humidity. I've had issues myself with the second one especially if the sensor is reading at a more continuous rate and it only ever seemed to happen after a certain length of time doing it. Hopefully Nick can give you more insight when he responds if he's had any issues but I just wanted to throw in my own two cents with what I've experienced.


Thanks. I'll have to experiment with taking 2 readings and if one is way off ignore it. I did order a couple extras, the AM2301, from ebay. I can try to see if it is better. 

Thanks for the help.

Offline Josiah

  • Add-InWx Software Author
  • Forecaster
  • *****
  • Posts: 439
    • Add-InWx
Re: Homemade Weather Station using a Raspberry Pi
« Reply #67 on: June 12, 2015, 06:20:26 PM »
If your going to experiment with taking 2 readings, Why don't you take 3 then you can compare all 3 to each other and have a better idea of which 1, if any are off.
e.g. if you get these with 2 readings:
Reading A: °72
Reading B: °78

You may be able to tell which one is off by comparing them to previous readings. But if you take 3, you could then compare them to each other and get a more definitive idea on which one (if any) are incorrect.
So, in the above example if you took a third and got °73 so you now have:
Reading A: °72
Reading B: °78
Reading C: °73

You can see that readings A and C are close, meaning that B is almost certainly incorrect.

Just wanted to throw this out there.

Offline weathernick

  • Senior Member
  • **
  • Posts: 89
Re: Homemade Weather Station using a Raspberry Pi
« Reply #68 on: June 12, 2015, 11:04:29 PM »
Man I so wanted that AM2315 sensor to work... but in the end the humidity failed and I ended up replacing it with a SHT25. Got the sensor from http://www.embeddedadventures.com/sht25_humidity_temperature_sensor_MOD-1018.html since it had the extremely small sensor on a break out board. Good luck with the AM2315 but keep in mind that it is a squirrelly sensor and it may never really work for you. The SHT sensor are those found in the Davis weather station so they are great sensors. Ok I will get off my sensor soapbox...

Nickolas
PWS: Custom built with Raspberry Pi collecting the data from the sensors.
CWOP: EW5462
Wunderground: KAZYUMA27
Personal WX page: http://mccolls.weewx.s3-website-us-east-1.amazonaws.com/

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #69 on: June 13, 2015, 12:23:50 PM »
Man I so wanted that AM2315 sensor to work... but in the end the humidity failed and I ended up replacing it with a SHT25. Got the sensor from http://www.embeddedadventures.com/sht25_humidity_temperature_sensor_MOD-1018.html since it had the extremely small sensor on a break out board. Good luck with the AM2315 but keep in mind that it is a squirrelly sensor and it may never really work for you. The SHT sensor are those found in the Davis weather station so they are great sensors. Ok I will get off my sensor soapbox...

Nickolas

I'll try taking 3 readings like Josiah suggested and see what happens. If that doesn't work, I'll replace it with one like yours.

Here's a SHT21 for $7 :http://www.ebay.com/itm/SHT21-Digital-Humidity-And-Temperature-Sensor-Module-Replace-SHT11-SHT15-/200941266522?pt=LH_DefaultDomain_0&hash=item2ec908665a


Offline sroof

  • Member
  • *
  • Posts: 2
Re: Homemade Weather Station using a Raspberry Pi
« Reply #70 on: June 19, 2015, 11:30:17 AM »
Greetings from a new user here!
Very impressive project and great discussion in this forum thread!
I’ve been managing a Campbell Scientific weather station for over 10 years.  Now I’d like to send its data to Weather Underground using a Raspberry Pi and custom Python code.  I have studied the Wunderground PWS Upload Protocol site but have some questions on formatting the data for uploading.   Since many of you have experience with the nitty-gritty data formatting, I’m hoping you can provide some help.

My first question, is there another helpful online forum for Wunderground PWS users, particularly those using custom weather stations?

My specific data formatting questions:

Can I upload data in metric units?  (doesn’t look like it, but sure would be nice!)

For precipitation, I was expecting to upload the interval precipitation, i.e., accumulation since the last data upload.  However, “rainin” is described as “rain inches over the past hour” and “the accumulated rainfall in the past 60 min”.  So it seems “rainin” must be just used to report precip rate, right?  And the “dailyrainin” is used for totalizing precipitation?

Can I upload snow depth? (there’s no field listed for snow depth, but it shown for some PWS)

Finally, is there a way to edit or delete entries that have already been uploaded to a PWS?

Many thanks!

Online nincehelser

  • Forecaster
  • *****
  • Posts: 1973
    • nincehelser.com
Re: Homemade Weather Station using a Raspberry Pi
« Reply #71 on: June 19, 2015, 12:17:04 PM »
Greetings from a new user here!
Very impressive project and great discussion in this forum thread!
I’ve been managing a Campbell Scientific weather station for over 10 years.  Now I’d like to send its data to Weather Underground using a Raspberry Pi and custom Python code.  I have studied the Wunderground PWS Upload Protocol site but have some questions on formatting the data for uploading.   Since many of you have experience with the nitty-gritty data formatting, I’m hoping you can provide some help.

My first question, is there another helpful online forum for Wunderground PWS users, particularly those using custom weather stations?

My specific data formatting questions:

Can I upload data in metric units?  (doesn’t look like it, but sure would be nice!)

For precipitation, I was expecting to upload the interval precipitation, i.e., accumulation since the last data upload.  However, “rainin” is described as “rain inches over the past hour” and “the accumulated rainfall in the past 60 min”.  So it seems “rainin” must be just used to report precip rate, right?  And the “dailyrainin” is used for totalizing precipitation?

Can I upload snow depth? (there’s no field listed for snow depth, but it shown for some PWS)

Finally, is there a way to edit or delete entries that have already been uploaded to a PWS?

Many thanks!

It's english-only units as far as I know.  I haven't seen any metric parameters published.

Rainin is used to compute a rain rate.  There wouldn't be much of a reason for it otherwise.

No idea on snow depth.  I haven't seen a published parameter for that, either.

You can delete entries from wunderground by looking up your station and looking at the table data.  From there you can delete bad data.


Offline weathernick

  • Senior Member
  • **
  • Posts: 89
Re: Homemade Weather Station using a Raspberry Pi
« Reply #72 on: July 14, 2015, 11:37:45 PM »
One year update on my station.
- Finally fixed the precipitation error where a lightning strike would cause interference and give me 100 tips in a few seconds. The solution is to build an Resistor Capacitor filter (RC filter, or low level filter). I got the specs here: http://www.wetter-garching.de/howto.html

- Temperature/humidity sensor and the FARS has been solid for about 10 months ever since I switched to the SHT sensor.

- Wind direction sensor developed a crack that allowed water to enter the electronics and fried it twice. Isolated the problem and repaired. In the process raised the sensor to 10 meters.

- Solar sensor has worked flawlessly. No issues.

- Pressure sensor has also worked flawlessly.

-  Lightning sensor still doesn't work but the filter I build for precip might also help it out as well...

-  Two web cameras have been added . One usb camera to the original station and a second HD Raspberry pi camera in an enclosure. Timelapse video can be viewed on my youtube channel. https://www.youtube.com/channel/UC2X3uvFF1hiKrTccpNh_2VQ/feed

-  The raspberry pi weather station has been online 99.4% of the time this year. Most of that was associated with fixes to the wind sensor.

Now time for some updated pics:












« Last Edit: July 15, 2015, 07:12:29 PM by weathernick »
PWS: Custom built with Raspberry Pi collecting the data from the sensors.
CWOP: EW5462
Wunderground: KAZYUMA27
Personal WX page: http://mccolls.weewx.s3-website-us-east-1.amazonaws.com/

Offline thorn

  • Member
  • *
  • Posts: 43
    • Weather STation
Re: Homemade Weather Station using a Raspberry Pi
« Reply #73 on: July 15, 2015, 10:59:02 AM »
That looks nice! Thanks for the update.

I was able to get the temp/hum readings without spikes from the AM2315 just comparing 2 readings in a while loop. The ebay ones were really bad, almost every reading was way off, 3,000% humidity at times. I did order a SHT21.

I am experimenting with a couple of UV sensors. One from Adafruit which works well and one like the light sensor:

http://www.ebay.com/itm/REYAX-UVI-01-Ultraviolet-rays-detector-UVI-UV-sensor-/180846474255

I just have to figure out how to mount them outdoors.

I lost a channel from my Adafruit ADC, I'm not sure what happened, static? I just switched to another, there are 4 on it. I would get the same voltages even with nothing on it.

Greg

Offline Red Dragon

  • Member
  • *
  • Posts: 27
Re: Homemade Weather Station using a Raspberry Pi
« Reply #74 on: August 14, 2015, 12:34:44 AM »
I'm planning on building my own weather station too once I get the money for it. I'm thinking of using the Arduino Yún instead of the Raspberry Pi. What do you guys think?