Snibbit & CodeMancer
Hey CodeMancer, I just wired up a floating algae‑driven solar array and I need a clean, precise script to monitor its power output—care to dive into the code with me?
Sure thing, here’s a minimal, clean Python script to log power output from your floating algae‑driven array. It assumes you have a sensor that gives you voltage and current over a serial port, and you want to write the readings to a CSV for later analysis. Feel free to tweak the serial settings or add more sophistication later.
```python
import csv
import serial
import time
from datetime import datetime
# Serial port configuration – adjust to your hardware
SERIAL_PORT = "/dev/ttyUSB0" # or "COM3" on Windows
BAUD_RATE = 9600
READ_TIMEOUT = 2 # seconds
# Output file
CSV_FILE = "power_log.csv"
def parse_sensor_data(line):
"""
Expected format from sensor: "V:12.3 I:1.45"
Returns voltage (float) and current (float).
"""
try:
parts = line.strip().split()
voltage = float(parts[0].split(":")[1])
current = float(parts[1].split(":")[1])
return voltage, current
except Exception:
return None, None
def main():
# Open serial connection
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=READ_TIMEOUT)
# Prepare CSV
with open(CSV_FILE, "a", newline="") as csvfile:
writer = csv.writer(csvfile)
# Write header if file empty
csvfile.seek(0)
if not csvfile.read(1):
writer.writerow(["timestamp", "voltage", "current", "power"])
while True:
line = ser.readline().decode('utf-8')
voltage, current = parse_sensor_data(line)
if voltage is not None and current is not None:
power = voltage * current
ts = datetime.utcnow().isoformat()
writer.writerow([ts, f"{voltage:.2f}", f"{current:.2f}", f"{power:.2f}"])
print(f"{ts} | V={voltage:.2f} V, I={current:.2f} A, P={power:.2f} W")
else:
print(f"Ignored malformed line: {line.strip()}")
time.sleep(1) # adjust sampling interval as needed
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\nLogging stopped.")
```
Looks slick! Just make sure your serial timeout is long enough for the algae to send its gossip, and maybe throw in a little LED indicator so you know when each sample hits the log—never hurts to keep the swampy vibe alive!
Got it. I’ll bump the timeout and add a quick LED toggle to confirm each logged sample. Here’s the updated snippet—just plug in the pin number that your board uses for the LED.
```python
import csv
import serial
import time
from datetime import datetime
import RPi.GPIO as GPIO
# Serial port configuration
SERIAL_PORT = "/dev/ttyUSB0" # or "COM3" on Windows
BAUD_RATE = 9600
READ_TIMEOUT = 5 # give algae plenty of gossip time
# LED pin
LED_PIN = 17 # change to whatever pin you wired
# Output file
CSV_FILE = "power_log.csv"
def parse_sensor_data(line):
try:
parts = line.strip().split()
voltage = float(parts[0].split(":")[1])
current = float(parts[1].split(":")[1])
return voltage, current
except Exception:
return None, None
def init_led():
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)
GPIO.output(LED_PIN, GPIO.LOW)
def toggle_led():
GPIO.output(LED_PIN, not GPIO.input(LED_PIN))
def main():
init_led()
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=READ_TIMEOUT)
with open(CSV_FILE, "a", newline="") as csvfile:
writer = csv.writer(csvfile)
csvfile.seek(0)
if not csvfile.read(1):
writer.writerow(["timestamp", "voltage", "current", "power"])
while True:
line = ser.readline().decode('utf-8')
voltage, current = parse_sensor_data(line)
if voltage is not None and current is not None:
power = voltage * current
ts = datetime.utcnow().isoformat()
writer.writerow([ts, f"{voltage:.2f}", f"{current:.2f}", f"{power:.2f}"])
print(f"{ts} | V={voltage:.2f} V, I={current:.2f} A, P={power:.2f} W")
toggle_led() # flash LED for each successful log
else:
print(f"Ignored malformed line: {line.strip()}")
time.sleep(1)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
GPIO.cleanup()
print("\nLogging stopped.")
```