From 231cb108de218cbf400fc632c36a8125590c7084 Mon Sep 17 00:00:00 2001 From: Corby Schmitz <cschmitz@anl.gov> Date: Thu, 5 Dec 2024 09:09:31 -0600 Subject: [PATCH] Removing unintentional sync --- valve-code/code (cschmitz@anl.gov).py | 347 -------------------------- 1 file changed, 347 deletions(-) delete mode 100644 valve-code/code (cschmitz@anl.gov).py diff --git a/valve-code/code (cschmitz@anl.gov).py b/valve-code/code (cschmitz@anl.gov).py deleted file mode 100644 index 07cf620..0000000 --- a/valve-code/code (cschmitz@anl.gov).py +++ /dev/null @@ -1,347 +0,0 @@ -# Corby Schmitz (cschmitz@anl.gov) -# Standard board import -import board -# For digital IO pins to control motor and listen for button press -from digitalio import DigitalInOut, Direction -# For analog pins (voltage of pot) -from analogio import AnalogIn -# For cooperative programming -import asyncio -# For handling button press -import keypad -# For status LED -import neopixel -# For environmental variables -import os - -# Debug setting -# True = print statements enabled for all stages -# False = plottable values only -debug = False - -# Set up digital pins to control the motor direction -valveClose = DigitalInOut(board.A1) -valveOpen = DigitalInOut(board.A2) -valveOpen.direction = Direction.OUTPUT -valveClose.direction = Direction.OUTPUT - -# Put the motor into a standstill, per the RZ7888 Motor control -# datasheet, indicating that High/High stops movement -valveOpen.value = True -valveClose.value = True - -# Pin to record the current placement of the valve -# 0v indicates closed. This is the calibrationposition, with -# counterclockwise rotation of the POT pin -# ReferenceVoltage is the maximum value at the full, open position -valveStatus = AnalogIn(board.A0) - -# Time between checks of the valve movement process -valveChangeTime = 0.125 -# Calibrated voltage reference for the POT values -referenceVoltage = 3.0 - -statusLED = neopixel.NeoPixel(board.NEOPIXEL, 1) -green = (0, 150, 0) -red = (150, 0, 0) -blue = (0, 0, 150) - -# Lapse Cycle -LAPSE_CYCLE = 2000 -# Wait value multiplier -WAIT_VALUE = 2 -0 -# Establish the shared datastructure variables -class Controls: - def __init__(self): - # Variable capture the system and wait for user input - self.waitingOnDirective = True - # Indication that we need to stop and shut down the system - self.halt = False - # Variable for the open time of the valve, from serial input - self.openTime = 0 - # Variable for the close time of the valve, from serial input - self.closeTime = 0 - # Variable for the number of cycle repeats for this program - self.repeat = 0 - # Set the value of the default position - closed - self.valveSetting = 0.0 - # Variable to hold the current run cycle - self.cycle = 0 - # Counting runtime in seconds - self.totalRuntime = 0 - self.cycleRuntime = 0 - # Current operation - self.operation = "initiating" - # Calibrated voltage reference for the POT values - self.referenceVoltage = referenceVoltage - # Valve name - self.valveName = os.getenv("VALVE_NAME") - -def print_state(control): - currentVoltage = round(analog_voltage(valveStatus)/control.referenceVoltage, 1) - writableValue = "valve=" + control.valveName + "," + \ - "curSet=" + str(control.valveSetting) + "," + \ - "curVal=" + str(currentVoltage) + "," \ - "curCycle=" + str(control.cycle) + "," + \ - "totCycle=" + str(control.repeat) + "," + \ - "curOp=" + control.operation - print(writableValue) - -# Function to take the pin value and convert to voltage consistent -# with the system reference (via the ADC 16bit value) -# reduce to 1 decimal place to prevent motor swing -def analog_voltage(pin): - return round((pin.value * referenceVoltage) / 65536.0, 2) - -# Function to reset the unit to the closed position -def closeValve(control): - # Closes the valve until it is confirmed set - currentVoltage = analog_voltage(valveStatus) - while (currentVoltage > 0.0): - currentVoltage = analog_voltage(valveStatus) - valveOpen.value = True - valveClose.value = False - valveClose.value = True - if debug: - print("Valve closed") - -# Given a value from 0.0 - referenceVoltage, open the valve to this level -# with no blocking Starting from the 0 position -def setValve(currentSetting, control): - currentVoltage = analog_voltage(valveStatus) - if (currentVoltage > currentSetting): - # Close the valve - valveOpen.value = True - valveClose.value = False - if debug: - print(round(currentVoltage/referenceVoltage, 2)*100, control.cycleRuntime, - control.totalRuntime, control.openTime, control.closeTime, - control.cycle, control.repeat, "closing", sep=',', end='\n') - elif (currentVoltage < currentSetting): - # Open the valve - valveOpen.value = False - valveClose.value = True - if debug: - print(round(currentVoltage/referenceVoltage, 2)*100, control.cycleRuntime, - control.totalRuntime, control.openTime, control.closeTime, - control.cycle, control.repeat, "opening", sep=',', end='\n') - else: - # Halt motion - valveOpen.value = True - valveClose.value = True - # complete = True - if debug: - print(round(currentVoltage/referenceVoltage, 2)*100, control.cycleRuntime, - control.totalRuntime, control.openTime, control.closeTime, - control.cycle, control.repeat, "stopped", sep=',', end='\n') - return True - return False - -# Gather and validate the user input from the serial CLI -def getDirective(control): - statusLED.fill(blue) - print("Awaiting directive") - inputSuccess = True - firstSettings = input() - print(firstSettings) - openSettingP = 0.0 - openTimeM = 0 - closeTimeM = 0 - repeatV = 0 - try: - (openSettingP, openTimeM, closeTimeM, repeatV) = firstSettings.split(",") - except Exception: - inputSuccess = False - try: - control.valveSetting = round(float(openSettingP), 1) - if not (control.valveSetting <= 1 and control.valveSetting >= 0): - raise Exception("invalid value for valveSetting") - except Exception: - if debug: - print("Invalid valvePosition. valvePosition(decimal value 0-1") - inputSuccess = False - try: - control.openTime = int(openTimeM) - if control.openTime <= 0: - raise Exception("invalid value for openTime") - except Exception: - if debug: - print("Invalid openTime. openTime(whole seconds)") - inputSuccess = False - try: - control.closeTime = int(closeTimeM) - if control.closeTime <= 0: - raise Exception("invalid value for closeTime") - except Exception: - if debug: - print("Invalid closeTime. closeTime(whole seconds)") - inputSuccess = False - try: - control.repeat = int(repeatV) - if control.repeat < 0: - raise Exception("invalid value for closeTime") - except Exception: - if debug: - print("Invalid cycleRepeat. cycleRepeat(integer >= 0)") - inputSuccess = False - if debug: - print(control.valveSetting, control.openTime, control.closeTime, control.repeat) - return inputSuccess - -# Reset all control values and issue a halt -def cancelDirective(control): - control.openTime = 0 - control.closeTime = 0 - control.repeat = 0 - control.cycle = 0 - control.valveSetting = 0.0 - control.halt = True - currentVoltage = analog_voltage(valveStatus)/control.referenceVoltage - currentVoltage = round(currentVoltage, 1) - control.operation = "halting" - print_state(control) - closeValve(control) - control.operation = "closed" - print_state(control) - -async def run_program(control): - while True: - # Reset the valve to the closed state - if debug: - print("Ensuring valve is closed to start") - closeValve(control) - # Gather user input - statusLED.fill(red) - validInput = getDirective(control) - while not validInput: - # Try to get directive - validInput = getDirective(control) - # Pause for possible reconnect by BLE monitor - await asyncio.sleep(2) - try: - while (control.cycle <= control.repeat and not control.halt): - if debug: - print("Starting cycle", control.cycle) - control.operation = "opening" - print_state(control) - statusLED.fill(green) - valveValue = round(referenceVoltage * control.valveSetting, 1) - if debug: - print("Setting the valve to", control.valveSetting*100, "%") - valveSet = setValve(valveValue, control) - lapse = 0 - while not valveSet: - valveValue = round(referenceVoltage * control.valveSetting, 1) - if lapse > LAPSE_CYCLE: - print_state(control) - lapse = 0 - else: - lapse += 1 - if control.halt: - valveSet = setValve(0.0, control) - else: - valveSet = setValve(valveValue, control) - await asyncio.sleep(0) - control.operation = "open" - print_state(control) - if debug: - print("Waiting", control.openTime, "seconds") - waitCount = 0 - while waitCount < control.openTime/WAIT_VALUE: - waitCount += 1 - await asyncio.sleep(WAIT_VALUE) - print_state(control) - control.cycleRuntime += control.openTime - control.totalRuntime += control.openTime - control.operation = "closing" - print_state(control) - if debug: - print("Closing the valve") - statusLED.fill(blue) - valveSet = setValve(0.0, control) - lapse = 0 - while not valveSet: - valveSet = setValve(0.0, control) - await asyncio.sleep(0) - if lapse > LAPSE_CYCLE: - print_state(control) - lapse = 0 - else: - lapse += 1 - control.operation = "closed" - print_state(control) - if debug: - print("Waiting", control.closeTime, "seconds") - waitCount = 0 - while waitCount < control.closeTime/WAIT_VALUE: - waitCount += 1 - await asyncio.sleep(WAIT_VALUE) - print_state(control) - control.cycleRuntime += control.closeTime - control.totalRuntime += control.closeTime - if debug: - print(0.0, 0.0, control.totalRuntime, control.openTime, - control.closeTime, control.cycle, control.repeat, - "newcycle", sep=',', end='\n') - control.operation = "newcycle" - control.cycle += 1 - print_state(control) - control.cycleRuntime = 0 - except KeyboardInterrupt: - # Handle a CTRL-C sent via the serial console - cancelDirective(control) - if debug: - print(0.0, 0.0, control.totalRuntime, control.openTime, control.closeTime, - control.cycle, control.repeat, "done", sep=',', end='\n') - control.operation = "done" - print_state(control) - await asyncio.sleep(5) - control.operation = "initiating" - # Reset values for next run - control.cycle = 0 - control.totalRuntime = 0 - control.cycleRuntime = 0 - control.halt = False - print_state(control) - await asyncio.sleep(0) - -# Button on board for signaling a close event -# board.A3, active=Low, pull=Up -# If button connected to board.A3 goes low, we abort the valve position and program -# We return to a closed state -async def monitorButton(haltButton, control): - # Syntax for (haltButton,) is critical, it requires a set with use of keypad module - with keypad.Keys((haltButton,), value_when_pressed=False, pull=True) as keys: - while True: - key_event = keys.events.get() - if key_event and key_event.pressed: - if key_event.key_number == 0: # Only one button here - if debug: - print("Halt requested") - statusLED.fill(red) - cancelDirective(control) - await asyncio.sleep(0) - -# Main function that launches the three system proceses -async def main(): - statusLED.fill(red) - # Create object to store shared data - control = Controls() - if debug: - print("Starting button watcher") - # Create the button process - buttonTask = asyncio.create_task(monitorButton(board.A3, control)) - if debug: - print("Starting valve control") - # Create the valve control process - valveTask = asyncio.create_task(run_program(control)) - # Asyncio operation to wait until both tasks complete to exit - try: - await asyncio.gather(valveTask, buttonTask) - except KeyboardInterrupt: - cancelDirective(control) - -if debug: - print("Initiating program") -asyncio.run(main()) -- GitLab