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 (0–100) 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())