def test_write_long(la: LogicAnalyzer, slave: I2CSlave): la.capture(2, block=False) slave.write_long(WRITE_DATA, REGISTER_ADDRESS) la.stop() scl, sda = la.fetch_data() assert len(scl) == (SCL_START + SCL_WRITE * 6 + SCL_STOP) assert len(sda) == (SDA_START + SDA_DEVICE_ADDRESS + SDA_REGISTER_ADDRESS + SDA_WRITE * 4 + SDA_ACK)
def test_pwm(pwm: PWMGenerator, la: LogicAnalyzer): frequency = 5e4 duty_cycle = 0.4 pwm.generate("SQ1", frequency, duty_cycle) time.sleep(0.1) assert la.measure_frequency("LA1") == pytest.approx(frequency, rel=RELTOL) assert la.measure_duty_cycle("LA1")[1] == pytest.approx(duty_cycle, rel=RELTOL)
def test_write(la: LogicAnalyzer, slave: I2CSlave): la.capture(2, block=False) slave.write(bytearray(b"\x00"), REGISTER_ADDRESS) la.stop() scl, sda = la.fetch_data() assert len(scl) == (SCL_START + SCL_WRITE * 3 + SCL_STOP) assert len(sda) == (SDA_START + SDA_DEVICE_ADDRESS + SDA_REGISTER_ADDRESS + SDA_WRITE + SDA_ACK)
def test_read_byte(la: LogicAnalyzer, slave: I2CSlave): la.capture(2, block=False) slave.read_byte(REGISTER_ADDRESS) la.stop() scl, sda = la.fetch_data() assert len(scl) == (SCL_START + SCL_WRITE * 2 + SCL_RESTART + SCL_WRITE + SCL_READ + SCL_STOP) assert len(sda) == (SDA_START + (SDA_DEVICE_ADDRESS + SDA_NACK) + (SDA_REGISTER_ADDRESS + SDA_NACK) + SDA_RESTART + (SDA_DEVICE_ADDRESS + SDA_NACK) + (SDA_READ + SDA_ACK))
def test_configure(la: LogicAnalyzer, master: I2CMaster, slave: I2CSlave): frequency = 1.25e5 master.configure(frequency) la.capture(1, block=False) slave._start(1) slave._stop() la.stop() (scl, ) = la.fetch_data() write_start = scl[1] # First event is start bit. write_stop = scl[-2] # Final event is stop bit. start_to_stop = 8.5 # 9 periods, but initial and final states are the same. period = (write_stop - write_start) / start_to_stop assert (period * MICROSECONDS)**-1 == pytest.approx(frequency, rel=RELTOL)
def test_unchanged_state(pwm: PWMGenerator, la: LogicAnalyzer): frequency = 2.5e3 duty_cycle = 0.9 pwm.generate(["SQ1", "SQ4"], frequency, duty_cycle) states = [None, True, False, None] pwm.set_state(*states) time.sleep(0.1) assert list(la.get_states().values())[1:3] == states[1:3] assert la.measure_frequency("LA1") == pytest.approx(frequency, rel=RELTOL) assert la.measure_frequency("LA4") == pytest.approx(frequency, rel=RELTOL) assert la.measure_duty_cycle("LA1")[1] == pytest.approx(duty_cycle, rel=RELTOL) assert la.measure_duty_cycle("LA4")[1] == pytest.approx(duty_cycle, rel=RELTOL)
def la(handler, request): """Return a LogicAnalyzer instance. In integration test mode, this function also enables the PWM output. """ if not isinstance(handler, MockHandler): pwm = PWMGenerator(handler) enable_pwm(pwm, request.node.name) handler._logging = True return LogicAnalyzer(handler)
def test_pwm_phase(pwm: PWMGenerator, la: LogicAnalyzer): frequency = 1e4 duty_cycle = 0.5 phase = 0.25 pwm.generate(["SQ1", "SQ2"], frequency, duty_cycle, phase) time.sleep(0.1) interval = la.measure_interval(["LA1", "LA2"], ["rising", "rising"]) if interval < 0: interval += frequency**-1 / MICROSECONDS assert interval * MICROSECONDS == pytest.approx(frequency**-1 * phase, rel=RELTOL)
def __init__(self): super().__init__() self.logic_analyzer = LogicAnalyzer(device=self) self.oscilloscope = Oscilloscope(device=self) self.waveform_generator = WaveformGenerator(device=self) self.pwm_generator = PWMGenerator(device=self) self.multimeter = Multimeter(device=self) self.power_supply = PowerSupply(device=self) self.i2c = I2CMaster(device=self) self.nrf = NRF24L01(device=self) if "V6" in self.version: # Set the built-in WS2812B to green :) self.rgb_led([0, 20, 0])
def test_start_slave(la: LogicAnalyzer, slave: I2CSlave): la.capture(2, block=False) slave._start(1) la.stop() slave._stop() init = la.get_initial_states() scl, sda = la.fetch_data() assert all([init[c] for c in [SCL, SDA]]) # Both start HIGH. assert sda[0] < scl[0] # Start bit: SDA 1->0 while SCL is 1.
def test_stop_slave(la: LogicAnalyzer, slave: I2CSlave): slave._start(1) la.capture(2, block=False) slave._stop() la.stop() init = la.get_initial_states() scl, sda = la.fetch_data() assert not init[SCL] and init[SDA] # SDA starts HIGH, SCL starts LOW. assert sda[0] < scl[0] < sda[1] # Stop bit: SDA 0->1 while SCL is 1.
def __init__( self, port: str = None, baudrate: int = 1000000, timeout: float = 1.0, ): super().__init__(port, baudrate, timeout) self.logic_analyzer = LogicAnalyzer(device=self) self.oscilloscope = Oscilloscope(device=self) self.waveform_generator = WaveformGenerator(device=self) self.pwm_generator = PWMGenerator(device=self) self.multimeter = Multimeter(device=self) self.power_supply = PowerSupply(device=self) self.i2c = I2CMaster(device=self) self.nrf = NRF24L01(device=self) if "V6" in self.version: # Set the built-in WS2812B to green :) self.rgb_led([0, 20, 0])
def logic_analyzer( device: SerialHandler, channels: int, duration: float ) -> Tuple[List[str], List[np.ndarray]]: """Capture logic events on up to four channels simultaneously. Parameters ---------- device : :class:`Handler` Serial interface for communicating with the PSLab device. channels : {1, 2, 3, 4} Number of channels to capture events on. Events will be captured on LA1, LA2, LA3, and LA4, in that order. duration : float Duration in seconds up to which events will be captured. Returns ------- list of str Name of active channels. list of numpy.ndarray List of numpy.ndarrays holding timestamps in microseconds when logic events were detected. The length of the list is equal to the number of channels that were used to capture events, and each list element corresponds to a channel. Warnings -------- This cannot be used at the same time as the oscilloscope. """ la = LogicAnalyzer(device) la.capture(channels, block=False) time.sleep(duration) la.stop() timestamps = la.fetch_data() channels_name = [la._channel_one_map, la._channel_two_map, "LA3", "LA4"] return channels_name[:channels], timestamps
def test_set_angle(servo: Servo, la: LogicAnalyzer): servo.angle = 90 wavelength, duty_cycle = la.measure_duty_cycle("LA1") assert wavelength * duty_cycle == pytest.approx(1500, rel=RELTOL)
def test_map_reference_clock(pwm: PWMGenerator, la: LogicAnalyzer): prescaler = 5 pwm.map_reference_clock(["SQ3"], prescaler) assert la.measure_frequency("LA3") == pytest.approx(128e6 / (1 << prescaler), rel=RELTOL)
def test_set_state(pwm: PWMGenerator, la: LogicAnalyzer): states = [True, False, True, True] pwm.set_state(*states) time.sleep(0.1) assert list(la.get_states().values()) == states
def la(handler: SerialHandler) -> LogicAnalyzer: handler._logging = True return LogicAnalyzer(handler)