WFS – Weather Forecast System

Several years ago i tried to find a wind and weather station to suit my needs. The ones i found that did exactly what i wanted did not log and the ones that did log data where fare to advanced. I also had one special need, the station needed to move every weekend. As it was intended to monitor the winds on a stage construction. So i figured i make my own station, how hard can it be, right?

Now several years later i accept the fact that these things take time. Specially if it is your first time writing that particular coding language. i have learned a lot and is grateful for the challenges i have gotten to solve.

The project is still in prototype, and there are stuff that would like to improve and fix.

Future improvements

  • Container for the PSU, display and all electronics. I would like a made up one and not a general box that is modified to fit the system.
  • Better weather forecast.
  • Better graphs and user options on the graphs.
  • second screen to only see historical data.
  • Less memory usage over time.
  • probably more…


I have used kiCAD for drawing schematics. There are three PCB inside the container. One power distro, one anemometer step down , and a sensor board.


The part lists is quite simple, and i used the following parts:

  • Raspberry PI 3 B+
  • Bosch BME680
  • NEO-6M
  • A suitable power supply, i use a Meanwell RD-35. A dual supply with 5V and 12V with 32W capacity.
  • A anemometer with pulse signal.

The container i just used a box that suited my needs for the prototype and plan to design a box and 3D print it myself or via a supplier.


All code is written in python. For the most i used this project to learn python. I was very new to python when i started, and the first prototypes used Arduino only. At one point i used one RaspberryPi and two Arduinos.

All code is found here:

The only part of the whole project that is not python is a bash script that is used to install the whole system to a Linux device.


Raspberry Pi – Frequency pulse read 20 kHz

I was trying to find if it was possible to read a frequency generated by a anemometer with a Raspberry Pi. The information i found was there but very sparse and somewhat messy. Som said, NO!, the RPI cannot read frequencies and some said it had hard limitations. I figured the best way was to test everything out for myself and see if it would work out or not. Then i figured i try to simplify it here and hope it will help others in the same situation.

With this test i have concluded that up to 20 kHz the RPI is stable to read digital pulses.

First of i must say that i’m neither an expert in python or electronics. I studied electronics for three years back in 2002-2005. After that time i have had coding as a hobby. I worked my way trough html, css, php, mysql, after some years i started with arduino and c++ and now the last few years also raspberries and python. I have also run several Linux servers for home use.

Hardware used for this project:

  • Raspberry Pi 3 B+
  • One 100 ohm resistor
  • Uni-T UTG1005A Signal generator
  • Rigol DS1054 Z

The python code for this project is below.

import RPi.GPIO as g
from time import sleep

g.setup(16, g.IN, pull_up_down=g.PUD_DOWN)

global input
input = 0

def freq(x):
    global input
    input += 1

g.add_event_detect(16, g.RISING, callback=freq)

while True:
    input = 0

Code above uses pin 16 for reading the frequency. You can change this to suit your needs, just remember to alter the code as well as the input position.

Test bench setup

In the image above the signal generator is coming from the right(black and red clamp). It shares ground with the RPI and the signal generator gover over a 100 ohm resistor.

Kicad circuit of the test bench

For my project it is relevant to test the RPI with frequencies up to 600Hz. But i’m going to test how far the RPI can read stable frequencies in this setup.


I created a bit more advanced script to make the progress a bit smoother and more consistent. Also i wanted to log every reading in a database. I created a database table, with 30 empty rows.

To automate this test i added some more bits to the python script.

import mysql.connector
import RPi.GPIO as g
from time import sleep

global infreq
infreq = 0

def freq(x):
	global infreq
	infreq += 1

def db_insert(x, v, i2):
	writeDB = "UPDATE freq SET {} = {} WHERE id = {}".format(x, v, i2)
	cnx = mysql.connector.connect(user='pi', database='freq', password='password')
	cursor = cnx.cursor()

g.setup(16, g.IN, pull_up_down=g.PUD_DOWN)
g.add_event_detect(16, g.RISING, callback=freq)

v = [0] * 30
# x = 0
# i2 = 0
# dbid = 0

f = ["5hz", "10hz", "11hz", "20hz", "53hz", "100hz", "190hz", "253hz", "350hz",
 "500hz", "600hz", "700hz", "800hz", "900hz", "1000hz", "1500hz", "3000hz",
 "6000hz", "9000hz", "12000hz", "15000hz", "18000hz", "21000hz"]

print("      Raspberry Pi - Frequency test")
print("        Written by Stefan Bahrawy")
print("This test will read frequencies and store them in a database.")
print("Each test will work for 30 sec, then prompt for new frequency. So be patient.")
input("Hit enter to set you first frequency and start the reading.")

for x in f:
	input("Set frequency to \x1b[1;31m {} \x1b[0m, and hit enter. 
Sit back and relax for 30sec".format(x))
	infreq = 0
	for d in range(30):
		v[d] = infreq
		infreq = 0
	print("Reading done, now DB insert")
	for i in range(30):
		i2 = i + 1
		print(x, "Reads: ", v[i])
		db_insert(x, v[i], i2)
	print("\x1b[1;32m 30 readings stored in database column {} \x1b[0m".format(x))

print("The test is complete")

Random dumps from the oscilloscope. Showing all readings.

Below is the csv convertion from the MySQL dump i did after the full test. If you are interested in the data, just download it. Let me know if you would like the sql file and i can send it to you.


For my use the results are good enough. Having deviations of 1Hz here and there. If you are looking for higher accuracy, you might get some with the use of a new RPI, clean install or maybe threading to separate the processes.

If you have questions dont hesitate to ask.