def _test_temperature(): """Tests the temperature probe""" for i in range(5): temperature, res = interfaces.read_temperature() interfaces.lcd_out("Temperature: {0:0.3f}C".format(temperature), 1) interfaces.lcd_out("Res: {0:0.3f} Ohms".format(res), 2) interfaces.delay(0.5)
def drive_step_stick(self, cycles, direction): """ cycles and direction are integers Communicates with arduino to add HCl through pump :param cycles: number of rising edges for the pump :param direction: direction of pump """ if cycles == 0: return 0 interfaces.delay(0.01) if self.serial.writable(): self.serial.write(cycles.to_bytes(4, "little")) self.serial.write(direction.to_bytes(1, "little")) self.serial.flush() wait_time = cycles / 1000 + 0.5 print("wait_time = ", wait_time) interfaces.delay(wait_time) temp = self.serial.readline() if temp == b"DONE\r\n" or temp == b"": return 0 else: return int(temp) else: interfaces.lcd_out("Arduino Unavailable", 4, constants.LCD_CENT_JUST)
def degas(seconds): interfaces.lcd_clear() interfaces.lcd_out("Degassing {0:.0f}".format(seconds), line=1) interfaces.lcd_out("seconds", line=2) interfaces.stir_speed_fast() interfaces.delay(seconds, countdown=True) interfaces.stir_speed_slow()
def wait_pH_stable(total_sol, data): """ Continually polls probes until pH values are stable :param total_sol: total amount of HCl added to the solution so far :param data: list of recorded temperature, pH, and solution volume data so far :return: mean stable pH value of last 10 values """ # keep track of 10 most recent pH values to ensure pH is stable pH_values = [0] * 10 # a counter used for updating values in pH_values pH_list_counter = 0 # flag to ensure at least 10 pH readings have been made before adding solution valid_num_values_tested = False while True: pH_reading, pH_volts = interfaces.read_pH() temperature_reading = interfaces.read_temperature()[0] interfaces.lcd_out("pH: {0:>4.5f} pH".format(pH_reading), line=1) interfaces.lcd_out("pH V: {0:>3.4f} mV".format(pH_volts * 1000), line=2) interfaces.lcd_out("Temp: {0:>4.3f} C".format(temperature_reading), line=3) pH_values[pH_list_counter] = pH_reading if pH_list_counter == 9: valid_num_values_tested = True # Check that the temperature of the solution is within bounds if (abs(temperature_reading - constants.TARGET_TEMPERATURE) > constants.TEMPERATURE_ACCURACY): # interfaces.lcd_out("TEMPERATURE OUT OF BOUNDS") # TODO output to error log pass # Record data point (temperature, pH volts, total HCl) data.append( (temperature_reading, pH_volts, total_sol, None, None, None, None)) pH_list_counter = 0 if pH_list_counter >= 9 else pH_list_counter + 1 if (valid_num_values_tested and analysis.std_deviation(pH_values) < constants.TARGET_STD_DEVIATION): return pH_reading interfaces.delay(constants.TITRATION_WAIT_TIME)
def titration(pH_target, solution_increment_amount, data, total_sol_added, degas_time=0): """ Incrementally adds HCl depending on the input parameters, until target pH is reached :param pH_target: target pH for the titration :param solution_increment_amount: amount of HCl to add to solution. Units of mL :param data: list of recorded temperature, pH, and solution volume data so far :param total_sol_added: total amount of HCl added to the solution so far :param degas_time: optional parameter defining the de-gas time for the solution after the target pH has been reached :return: total solution added so far """ interfaces.lcd_out( "Titrating to {} pH".format(str(pH_target)), style=constants.LCD_CENT_JUST, line=4, ) # total HCl added total_sol = total_sol_added current_pH = wait_pH_stable(total_sol, data) while current_pH - pH_target > constants.PH_ACCURACY: interfaces.pump_volume(solution_increment_amount, 1) if constants.volume_in_pump < 0.05: # pump in 1 mL interfaces.pump_volume(1.0, 0) total_sol += solution_increment_amount # TESTING SETTLING interfaces.lcd_out("Mixing...", style=constants.LCD_CENT_JUST, line=4) interfaces.delay(10) # allow it to mix before taking measurements current_pH = wait_pH_stable(total_sol, data) interfaces.temperature_controller.update() interfaces.lcd_clear() interfaces.lcd_out("pH value {} reached".format(current_pH), line=1) interfaces.lcd_out("Degassing " + str(degas_time) + " seconds", line=2) interfaces.delay(degas_time, countdown=True) return total_sol
def set_motor_speed(self, target, gradual=False): if gradual is True: direction = math.copysign(1, target - self.motor.duty_cycle) # It won't move under 1000, so this speeds up the process if direction == 1 and self.motor.duty_cycle < 1000: self.motor.duty_cycle = 1000 if self.debug: print("Stirrer set to {0:.0f}".format(self.motor.duty_cycle)) while self.motor.duty_cycle != target: next_step = min(abs(target - self.motor.duty_cycle), 100) self.motor.duty_cycle = self.motor.duty_cycle + (next_step * direction) if self.debug: print("Stirrer set to {0:.0f}".format(self.motor.duty_cycle)) interfaces.delay(0.1) else: self.motor.duty_cycle = target if self.debug: print("Stirrer set to {0:.0f}".format(self.motor.duty_cycle))
def test_mode_read_values(numVals=60, timestep=0.5): numVals = numVals timestep = timestep timeVals = np.zeros(numVals) tempVals = np.zeros(numVals) resVals = np.zeros(numVals) pHVals = np.zeros(numVals) voltVals = np.zeros(numVals) for i in range(numVals): temp, res = interfaces.read_temperature() pH_reading, pH_volts = interfaces.read_pH() interfaces.lcd_out("Temp: {0:>4.3f} C".format(temp), line=1) interfaces.lcd_out("Res: {0:>4.3f} Ohms".format(res), line=2) interfaces.lcd_out("pH: {0:>4.5f} pH".format(pH_reading), line=3) interfaces.lcd_out("pH V: {0:>3.4f} mV".format(pH_volts * 1000), line=4) interfaces.lcd_out("Reading: {}".format(i), 1, console=True) timeVals[i] = timestep * i tempVals[i] = temp resVals[i] = res pHVals[i] = pH_reading voltVals[i] = pH_volts interfaces.delay(timestep)