import math from ScEpTIC.emulator.energy import energy_utils from ScEpTIC.emulator.energy.mcu.options import MCUClockCycleAction, ADCPowerState from ScEpTIC.emulator.energy.options import OpModeName from ScEpTIC.emulator.energy.voltage_drawner import VoltageDrawner class GenericADCSensorModel(VoltageDrawner): """ Energy model of a generic ADC sensor model """ STATES = ['on', 'off'] CC_SET = 1 # LM19C data = {'V': '5', 'I': '4.5u'} def __init__(self): self.state = 'off' self.resistance = energy_utils.equivalent_resistance(self.data['V'], self.data['I']) self.system_model = None def attach_system_model(self, system_model): self.system_model = system_model def set_state(self, state): """ Set state (off, on) """ if state not in self.STATES: raise Exception('GenericSensor - Invalid state') self.state = state def simulate_set_state(self, state): ticks = 0 for _ in range(self.CC_SET): ticks += self.system_model.run_step(MCUClockCycleAction.NO_MEMORY_ACCESS, OpModeName.SIMULATE_SENSOR) self.set_state(state) return ticks def simulate_read(self, n_samples): print(f"READING {n_samples} samples") # Activate the sensor ticks = self.simulate_set_state('on') # Set ADC on for _ in range(self.system_model.mcu.adc_instructions['on']): ticks += self.system_model.run_step(MCUClockCycleAction.NO_MEMORY_ACCESS, OpModeName.SIMULATE_SENSOR) self.system_model.mcu.set_adc_state(ADCPowerState.ON) for _ in range(n_samples): # Wait for startup and data to be ready for _ in range(self.system_model.mcu.get_ADC_wait_cycles()): ticks += self.system_model.run_step(MCUClockCycleAction.NO_MEMORY_ACCESS, OpModeName.SIMULATE_SENSOR) # Transfer for _ in range(self.system_model.mcu.adc_instructions['transfer']): ticks += self.system_model.run_step(MCUClockCycleAction.NO_MEMORY_ACCESS, OpModeName.SIMULATE_SENSOR) # Set ADC off ticks += self.system_model.run_step(MCUClockCycleAction.NO_MEMORY_ACCESS, OpModeName.SIMULATE_SENSOR) self.system_model.mcu.set_adc_state(ADCPowerState.OFF) # Deactivate the sensor ticks += self.simulate_set_state('off') return ticks def get_drained_energy(self, t): """ Calculates the energy consumed by the component. :param t: elapsed time :return: the consumed energy """ voltage = self.voltage_source.get_voltage() if self.state == 'off': return 0.0 energy_from_R = energy_utils.energy_from_R_t(voltage, self.resistance, t) return energy_from_R