141 lines
3.8 KiB
Python
141 lines
3.8 KiB
Python
'''
|
|
__ _____ _ _ ____
|
|
\ \ / /_ _| \ | | _ \
|
|
\ \ /\ / / | || \| | | | |
|
|
\ V V / | || |\ | |_| |
|
|
\_/\_/ |___|_| \_|____/
|
|
|
|
Script to read wind speed from a Davis Anémomètre-girouette Vantage Pro (6410)
|
|
https://www.shapemaker.io/blog/wind-speed-measurements-with-anemometer-and-a-raspberry-pi
|
|
|
|
Connexion:
|
|
black (wind speed ) -> gpio21
|
|
green (wind direction) -> ADS1115 (module I2C)
|
|
Yellow -> 5v
|
|
RED -> GND
|
|
|
|
Attention: The Raspberry Pi doesn't have analog inputs, so we need an analog-to-digital converter (ADC) to read the wind direction.
|
|
|
|
sudo /usr/bin/python3 /var/www/nebuleair_pro_4g/windMeter/read.py
|
|
|
|
this need to run as a service
|
|
|
|
--> sudo nano /etc/systemd/system/windMeter.service
|
|
|
|
⬇️
|
|
[Unit]
|
|
Description=Master manager for the Python wind meter scripts
|
|
After=network.target
|
|
|
|
[Service]
|
|
ExecStart=/usr/bin/python3 /var/www/nebuleair_pro_4g/windMeter/read.py
|
|
Restart=always
|
|
User=root
|
|
WorkingDirectory=/var/www/nebuleair_pro_4g
|
|
StandardOutput=append:/var/www/nebuleair_pro_4g/logs/wind.log
|
|
StandardError=append:/var/www/nebuleair_pro_4g/logs/wind_errors.log
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
⬆️
|
|
|
|
Reload systemd (first time after creating the service):
|
|
sudo systemctl daemon-reload
|
|
|
|
Enable (once), start (once and after stopping) and restart (after modification)systemd:
|
|
sudo systemctl enable windMeter.service
|
|
sudo systemctl start windMeter.service
|
|
sudo systemctl restart windMeter.service
|
|
|
|
Check the service status:
|
|
sudo systemctl status windMeter.service
|
|
|
|
'''
|
|
#!/usr/bin/python3
|
|
import time
|
|
import sqlite3
|
|
import board
|
|
import busio
|
|
import numpy as np
|
|
import threading
|
|
import adafruit_ads1x15.ads1115 as ADS
|
|
from adafruit_ads1x15.analog_in import AnalogIn
|
|
from gpiozero import Button
|
|
from datetime import datetime
|
|
|
|
# Constants
|
|
DB_PATH = "/var/www/nebuleair_pro_4g/sqlite/sensors.db"
|
|
|
|
# Initialize I2C & ADS1115
|
|
i2c = busio.I2C(board.SCL, board.SDA)
|
|
ads = ADS.ADS1115(i2c)
|
|
channel = AnalogIn(ads, ADS.P0) # Connect to A0 on the ADS1115
|
|
|
|
# Wind speed sensor setup
|
|
wind_speed_sensor = Button(21)
|
|
wind_count = 0
|
|
wind_lock = threading.Lock()
|
|
|
|
def spin():
|
|
global wind_count
|
|
with wind_lock:
|
|
wind_count += 1
|
|
|
|
def reset_wind():
|
|
global wind_count
|
|
with wind_lock:
|
|
wind_count = 0
|
|
|
|
wind_speed_sensor.when_activated = spin # More reliable
|
|
|
|
def calc_speed(spins, interval):
|
|
return spins * (2.25 / interval) * 1.60934 # Convert MPH to km/h
|
|
|
|
def get_wind_direction():
|
|
voltage = channel.voltage
|
|
return voltage
|
|
|
|
def save_to_database(wind_speed, wind_direction, spin_count):
|
|
"""Save wind data to SQLite database."""
|
|
try:
|
|
conn = sqlite3.connect(DB_PATH)
|
|
cursor = conn.cursor()
|
|
|
|
cursor.execute("SELECT * FROM timestamp_table LIMIT 1")
|
|
row = cursor.fetchone()
|
|
rtc_time_str = row[1] if row else datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
cursor.execute('''
|
|
INSERT INTO data_wind (timestamp, wind_speed, wind_direction)
|
|
VALUES (?, ?, ?)
|
|
''', (rtc_time_str, round(wind_speed, 2), round(wind_direction, 2)))
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
print(f"Saved: {rtc_time_str}, {wind_speed:.2f} km/h, {wind_direction:.2f}V, Spins: {spin_count}")
|
|
|
|
except Exception as e:
|
|
print(f"Database error: {e}")
|
|
|
|
def main():
|
|
print("Wind monitoring started...")
|
|
|
|
try:
|
|
while True:
|
|
reset_wind()
|
|
print("Measuring for 60 seconds...")
|
|
time.sleep(60)
|
|
|
|
wind_speed_kmh = calc_speed(wind_count, 60)
|
|
wind_direction = get_wind_direction()
|
|
|
|
save_to_database(wind_speed_kmh, wind_direction, wind_count)
|
|
|
|
except KeyboardInterrupt:
|
|
print("\nMonitoring stopped.")
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|