Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 56 additions & 11 deletions pslab/sciencelab.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,43 @@
from pslab.instrument.waveform_generator import PWMGenerator, WaveformGenerator


class ScienceLab:
"""Aggregate interface for the PSLab's instruments.

Attributes
----------
logic_analyzer : pslab.LogicAnalyzer
oscilloscope : pslab.Oscilloscope
waveform_generator : pslab.WaveformGenerator
pwm_generator : pslab.PWMGenerator
multimeter : pslab.Multimeter
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Outdated
power_supply : pslab.PowerSupply
i2c : pslab.I2CMaster
nrf : pslab.peripherals.NRF24L01
"""

def __init__(self, device: ConnectionHandler | None = None):
self.device = device if device is not None else autoconnect()
self.firmware = self.device.get_firmware_version()
self.logic_analyzer = LogicAnalyzer(device=self.device)
self.oscilloscope = Oscilloscope(device=self.device)
self.waveform_generator = WaveformGenerator(device=self.device)
self.pwm_generator = PWMGenerator(device=self.device)
self.multimeter = Multimeter(device=self.device)
self.power_supply = PowerSupply(device=self.device)

# CTMU current range index for temperature measurement (0b11110 = 55 µA)
_CTMU_CURRENT_RANGE_55UA = 0b11110

# Temperature calibration constants per current source setting.
# Format: (offset_mV, slope_mV_per_degree_celsius)
_TEMP_CALIB = {
1: (646.0, 1.92), # current source 1: offset=646mV, slope=1.92mV/°C
2: (701.5, 1.74), # current source 2: offset=701.5mV, slope=1.74mV/°C
3: (760.0, 1.56), # current source 3: offset=760mV, slope=1.56mV/°C
}


class ScienceLab:
"""Aggregate interface for the PSLab's instruments.

Expand Down Expand Up @@ -46,18 +83,26 @@ def __init__(self, device: ConnectionHandler | None = None):

@property
def temperature(self):
"""float: Temperature of the MCU in degrees Celsius."""
# TODO: Get rid of magic numbers.
cs = 3
V = self._get_ctmu_voltage(0b11110, cs, 0)

if cs == 1:
return (646 - V * 1000) / 1.92 # current source = 1
elif cs == 2:
return (701.5 - V * 1000) / 1.74 # current source = 2
elif cs == 3:
return (760 - V * 1000) / 1.56 # current source = 3
"""float: Temperature of the MCU in degrees Celsius.

Uses the CTMU (Charge Time Measurement Unit) with a 55 µA current
source (current_range index 0b11110) on channel 3 to measure the
internal temperature sensor voltage.

The voltage is converted to Celsius using calibration constants
defined in _TEMP_CALIB for each current source setting.

Returns
-------
float
Temperature in degrees Celsius.
"""
cs = 3 # current source index used for temperature measurement
tgen = 0 # disable time delay mode for direct voltage measurement
V = self._get_ctmu_voltage(_CTMU_CURRENT_RANGE_55UA, cs, tgen)
offset, slope = _TEMP_CALIB[cs]
return (offset - V * 1000) / slope

def _get_ctmu_voltage(self, channel: int, current_range: int, tgen: bool = True):
"""Control the Charge Time Measurement Unit (CTMU).

Expand Down