This commit is contained in:
2026-06-16 13:02:06 +02:00
commit 9e45f1f199
29 changed files with 2531 additions and 0 deletions

238
main.py Normal file
View File

@@ -0,0 +1,238 @@
import time
import uasyncio as asyncio
import machine
import gc
import neopixel
from config import *
from wifi import connect_wifi
from timeutil import setup_rtc
from sensors import Sensors
from display import OLED
from webserver import WebServer
# Set CPU speed
machine.freq(CPU_FREQ)
#HOSTNAME = "Testname"
# Connect WiFi
print("Version = ", VERSION)
print("Hostname = ", HOSTNAME)
wlan = connect_wifi(SSID, PASSWORD, HOSTNAME)
rtc = setup_rtc(TZ_OFFSET)
print("Server running on http://" + wlan.ifconfig()[0])
#TANK_CAPACITY_L = 3000
print("Heart Beat =", HEARTBEAT)
print("Tank Volume =", TANK_CAPACITY_L)
# Init sensors and display
sensors = Sensors()
if DISPLAY_ON:
oled = OLED()
sensors.test_pin1.on()
sensors.test_pin2.on()
sensors.test_pin0.on()
# Capture boot time
start_time = time.time()
# print("Boot timestamp:", start_time)
# Set tank full reference from current reading at boot
#MAX_PRESSURE_KPA = sensors.read_pressure()
time.sleep_ms(250)
sensors.test_pin1.off()
sensors.test_pin2.off()
sensors.test_pin0.off()
print("✔ Config loaded.")
print("Initial MAX_PRESSURE_KPA =", MAX_PRESSURE_KPA, "KPA")
print("Initial Known Depth =", KNOWN_DEPTH_M, "m")
#print("Initial Known Pressure =", MAX_PRESSURE_KPA)
def rssi_percent():
rssi = wlan.status("rssi")
rssi = max(-100, min(-50, rssi))
return int((rssi + 100) * 2)
class HeartbeatFadeNeoPixel:
def __init__(self, neopixel_obj, pixel_index=0, color=(255, 0, 0),
min_brightness=5, max_brightness=100,
step=2, interval_ms=20):
self.np = neopixel_obj
self.index = pixel_index
self.color = color
self.min_brightness = min_brightness
self.max_brightness = max_brightness
self.step = step
self.interval = interval_ms
self.brightness = min_brightness
self.direction = 1 # 1 = fade up, -1 = fade down
self.last_time = time.ticks_ms()
def apply_brightness(self, c, level):
r, g, b = c
factor = level / 100
return (int(r * factor), int(g * factor), int(b * factor))
def update(self):
now = time.ticks_ms()
if time.ticks_diff(now, self.last_time) >= self.interval:
self.last_time = now
# Update brightness
self.brightness += self.direction * self.step
# Bounce at limits
if self.brightness >= self.max_brightness:
self.brightness = self.max_brightness
self.direction = -1
if self.brightness <= self.min_brightness:
self.brightness = self.min_brightness
self.direction = 1
# Apply brightness
self.np[self.index] = self.apply_brightness(self.color, self.brightness)
self.np.write()
# ============================================================
# NEOPIXEL SETUP
# ============================================================
STRIP_PIN = 17
STRIP_LEDS = 3
strip = neopixel.NeoPixel(machine.Pin(STRIP_PIN), STRIP_LEDS)
SINGLE_PIN = 28
single = neopixel.NeoPixel(machine.Pin(SINGLE_PIN), 1)
# ============================================================
# BUTTONS
# ============================================================
button_pins = [20, 21, 22]
buttons = [machine.Pin(pin, machine.Pin.IN, machine.Pin.PULL_UP) for pin in button_pins]
# ============================================================
# COLOR PALETTE
# ============================================================
colors = [
(0, 0, 0), # Off
(255, 0, 0), # Red
(0, 255, 0), # Green
(0, 0, 255), # Blue
(255, 255, 255), # White
]
# ============================================================
# STRIP STATE
# ============================================================
color_index = [0, 0, 0]
brightness = [50, 50, 50]
last_state = [1, 1, 1]
press_time = [0, 0, 0]
# ============================================================
# HEARTBEAT CONFIG (NOW HAS MIN + MAX)
# ============================================================
FLASH_COLOR_INDEX = 1 # Palette color
FLASH_MIN = 1 # << lowest brightness (0100)
FLASH_MAX = 10 # << highest brightness
FLASH_STEP = 0.2 # fade speed
FLASH_INTERVAL_MS = 20 # smoothness
heartbeat = HeartbeatFadeNeoPixel(
neopixel_obj=single,
pixel_index=0,
color=colors[FLASH_COLOR_INDEX],
min_brightness=FLASH_MIN,
max_brightness=FLASH_MAX,
step=FLASH_STEP,
interval_ms=FLASH_INTERVAL_MS
)
# ============================================================
# HELPERS
# ============================================================
def apply_brightness(color, level):
r, g, b = color
factor = level / 100
return (int(r * factor), int(g * factor), int(b * factor))
def update_strip():
for i in range(STRIP_LEDS):
strip[i] = apply_brightness(colors[color_index[i]], brightness[i])
strip.write()
# ============================================================
# INITIAL
# ============================================================
update_strip()
async def sensor_task():
global MAX_PRESSURE_KPA
while True:
gc.collect()
sensors.check_buttons()
# heartbeat.update()
if AVERAGE:
pressure = sensors.read_pressure_avg()
else:
pressure = sensors.read_pressure()
#sensors.test_pin1.on()
if sensors.tank_full:
sensors.tank_full = False
MAX_PRESSURE_KPA = sensors.read_pressure()
if HEARTBEAT:
# sensors.test_pin2.on()
# time.sleep_ms(100)
# sensors.test_pin2.off()
# color_index[i] = 0
i=0
color_index[i] = (color_index[i] + 1) % len(colors)
update_strip()
# time.sleep_ms(100)
else:
# sensors.test_pin2.off()
# color_index[i] = 3
update_strip()
# time.sleep_ms(100)
percent = pressure / MAX_PRESSURE_KPA
depth_mm = percent * MAX_DEPTH_M * 1000
sensors.tank_percentage = percent * 100
if DISPLAY_ON:
oled.show(
rtc,
pressure,
sensors.tank_percentage,
sensors.cpu_temp(),
rssi_percent(),
depth_mm
)
await asyncio.sleep(1)
async def main():
asyncio.create_task(sensor_task())
server = WebServer(wlan, sensors, start_time, MAX_CONNECTIONS)
srv = await asyncio.start_server(server.handle, "0.0.0.0", 80)
async with srv:
await asyncio.Event().wait()
asyncio.run(main())