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()