169 lines
5.0 KiB
Python
169 lines
5.0 KiB
Python
import csv
|
|
import os
|
|
import time
|
|
import json
|
|
import requests
|
|
from datetime import datetime
|
|
|
|
import RPi.GPIO as GPIO
|
|
from adafruit_ads1x15.ads1115 import ADS1115
|
|
from adafruit_ads1x15.analog_in import AnalogIn
|
|
from RPLCD.i2c import CharLCD
|
|
import board
|
|
import busio
|
|
from w1thermsensor import W1ThermSensor
|
|
|
|
# --- Konstanta ---
|
|
PULSES_PER_LITER = 290
|
|
INPUT_PIN = 16
|
|
BUZZER_PIN = 18
|
|
CSV_FILENAME = 'data_pengukuran.csv'
|
|
API_URL = 'http://robotika.upnvj.ac.id:3000/send-data'
|
|
|
|
# --- Inisialisasi Perangkat ---
|
|
lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1, cols=20, rows=4, dotsize=8)
|
|
i2c = busio.I2C(board.SCL, board.SDA)
|
|
ads = ADS1115(i2c)
|
|
ads.gain = 1
|
|
ph_channel = AnalogIn(ads, 0)
|
|
tds_channel = AnalogIn(ads, 1)
|
|
temperature_sensor = W1ThermSensor()
|
|
|
|
GPIO.cleanup()
|
|
GPIO.setmode(GPIO.BOARD)
|
|
GPIO.setup(INPUT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
|
GPIO.setup(BUZZER_PIN, GPIO.OUT)
|
|
GPIO.output(BUZZER_PIN, GPIO.LOW)
|
|
|
|
# --- Kelas Flow Sensor ---
|
|
class FlowSensor:
|
|
def __init__(self, ppl=PULSES_PER_LITER):
|
|
self.pulse_count = 0
|
|
self.ppl = ppl
|
|
self.last_time = datetime.now()
|
|
|
|
def pulse_callback(self, _):
|
|
self.pulse_count += 1
|
|
self.last_time = datetime.now()
|
|
|
|
def get_volume(self):
|
|
return self.pulse_count / self.ppl
|
|
|
|
def reset(self):
|
|
self.pulse_count = 0
|
|
|
|
flow_sensor = FlowSensor()
|
|
GPIO.add_event_detect(INPUT_PIN, GPIO.RISING, callback=flow_sensor.pulse_callback)
|
|
|
|
# --- Fungsi Pendukung ---
|
|
def display_data(tds, ph, temp, flow):
|
|
lcd.clear()
|
|
lcd.write_string(f"TDS : {tds:.2f} ppm")
|
|
lcd.cursor_pos = (1, 0)
|
|
lcd.write_string(f"pH : {ph:.2f}")
|
|
lcd.cursor_pos = (2, 0)
|
|
lcd.write_string(f"Suhu : {temp:.2f} C")
|
|
lcd.cursor_pos = (3, 0)
|
|
lcd.write_string(f"Flow : {flow:.2f} L")
|
|
|
|
def read_average_voltage(channel, samples=20, delay=0.2, min_valid=1.0):
|
|
total = 0
|
|
valid = 0
|
|
for _ in range(samples):
|
|
voltage = channel.voltage
|
|
if voltage >= min_valid:
|
|
total += voltage
|
|
valid += 1
|
|
time.sleep(delay)
|
|
return total / valid if valid else 0
|
|
|
|
def calculate_ph(voltage, temperature):
|
|
k = 0.008
|
|
T_ref = 27.0
|
|
return (-7.0381 * voltage + 28.4177) + k * (temperature - T_ref)
|
|
|
|
|
|
def calculate_tds(voltage):
|
|
return 487.1959 * voltage - 117.0762
|
|
|
|
def check_thresholds_and_buzzer(tds, ph, suhu, flow):
|
|
if tds > 500 or ph < 6 or ph > 9 or suhu > 35 or flow > 100 :
|
|
for i in range(5):
|
|
GPIO.output(BUZZER_PIN, GPIO.HIGH)
|
|
time.sleep(1)
|
|
GPIO.output(BUZZER_PIN, GPIO.LOW)
|
|
time.sleep(0.3)
|
|
else:
|
|
GPIO.output(BUZZER_PIN, GPIO.LOW)
|
|
|
|
def send_data_to_server(tds, ph, suhu, flow):
|
|
data = {
|
|
"tds": round(tds, 2),
|
|
"ph": round(ph, 2),
|
|
"suhu": round(suhu, 2),
|
|
"flow": round(flow, 2)
|
|
}
|
|
|
|
try:
|
|
headers = {'Content-Type': 'application/json'}
|
|
response = requests.post(API_URL, headers=headers, json=data)
|
|
if response.status_code == 200:
|
|
print("Data berhasil dikirim ke server.")
|
|
else:
|
|
print(f"Gagal mengirim data. Status code: {response.status_code}")
|
|
except requests.RequestException as e:
|
|
print(f"Kesalahan saat mengirim data: {e}")
|
|
|
|
def save_data_to_csv(timestamp, tds, ph, suhu, flow):
|
|
file_exists = os.path.isfile(CSV_FILENAME)
|
|
with open(CSV_FILENAME, mode='a', newline='') as file:
|
|
writer = csv.writer(file)
|
|
if not file_exists:
|
|
writer.writerow(['Timestamp', 'pH', 'Suhu (C)', 'TDS (ppm)', 'Volume Air (L)'])
|
|
writer.writerow([timestamp, f"{ph:.2f}", f"{suhu:.2f}", f"{tds:.2f}", f"{flow:.2f}"])
|
|
|
|
# --- Program Utama ---
|
|
try:
|
|
last_reset_date = datetime.now().date()
|
|
|
|
while True:
|
|
now = datetime.now()
|
|
timestamp = now.strftime('%Y-%m-%d %H:%M:%S')
|
|
|
|
if now.hour == 0 and now.minute == 0 and last_reset_date != now.date():
|
|
flow_sensor.reset()
|
|
last_reset_date = now.date()
|
|
|
|
suhu = temperature_sensor.get_temperature()
|
|
avg_voltage_ph = read_average_voltage(ph_channel)
|
|
avg_voltage_tds = read_average_voltage(tds_channel, min_valid=0.5)
|
|
ph = calculate_ph(avg_voltage_ph, suhu)
|
|
tds = calculate_tds(avg_voltage_tds)
|
|
flow = flow_sensor.get_volume()
|
|
|
|
# Cetak data ke terminal
|
|
print("=" * 50)
|
|
print(f"Timestamp : {timestamp}")
|
|
print(f"Suhu : {suhu:.2f} C")
|
|
print(f"pH : {ph:.2f}")
|
|
print(f"TDS : {tds:.2f} ppm")
|
|
print(f"Debit Air : {flow:.2f} L")
|
|
|
|
save_data_to_csv(timestamp, tds, ph, suhu, flow)
|
|
display_data(tds, ph, suhu, flow)
|
|
check_thresholds_and_buzzer(tds, ph, suhu, flow)
|
|
send_data_to_server(tds, ph, suhu, flow)
|
|
|
|
time.sleep(5)
|
|
|
|
except KeyboardInterrupt:
|
|
print("Program dihentikan oleh pengguna.")
|
|
lcd.clear()
|
|
GPIO.cleanup()
|
|
|
|
except Exception as e:
|
|
print(f"Terjadi kesalahan: {e}")
|
|
GPIO.cleanup()
|
|
|
|
finally:
|
|
GPIO.cleanup() |