Ejemplo n.º 1
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    with open("tec_settings_dump.csv", "w") as f:
        for p in tec.TEC_PARAMETERS:
            p_id = p["id"]
            p_name = p["name"]
            p_type = p["mepar_type"]
            if p_id >= 50000:
                continue
            try:
                metadata = tec.read_metadata(p_id)
            except:
                continue
            (r_mepar_type, r_mepar_flag, _, _, _, _, _) = metadata
            if not r_mepar_flag.is_readwrite():
                continue
            if (r_mepar_type != p_type):
                print(
                    f"!!!MISTYPED!!! {p_name} {r_mepar_type.get_type()} vs {p_type.get_type()}"
                )
                continue
            p_set_value = tec._read_value(p_id, p_type)
            if not math.isnan(p_set_value):
                if p_set_value > 2147483646 or p_set_value < -2147483646:
                    print(f"!!!OUT OF BOUNDS!!! {p_name},{p_set_value}")
                else:
                    f.write(f"{p_name},{p_id},{p_type},{p_set_value}\n")
                #print(f"{p_name},{p_set_value}")
            else:
                print(f"!!!NAN!!! {p_name}")
Ejemplo n.º 2
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")
    print(tec.read_firmware_id())

    #check if TEC is running
    if tec.status() != MeCom_DeviceStatus.Run:
        print("TEC is not running")
        return

    #set tec stability indicator maximum temp. deviation
    tec.Set_TEC_StabilityTemperatureWindow(0.01)

    #read in table file
    table = [26.0]
    with open("sin_table.csv", "r") as filestream:
        for line in filestream:
            table += [float(line)]

    #perform software lookup table
    wait_for_stabilization = True  #wait at each step for temperature stabilization
    min_wait_time = 1.0  #seconds
    print_progress = True
    (times, temps,
     setpoints) = tec_perform_lookup(tec, table, wait_for_stabilization,
                                     min_wait_time, print_progress)

    #plot results
    plt.plot(times, temps, label='Temperature')
    plt.plot(times, setpoints, label='Set Point')
    plt.legend(loc="upper left")
    plt.xlabel("Time t / s")
    plt.ylabel("Temperature T / °C")
    plt.show()
Ejemplo n.º 3
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    # Special functions are all designated by using an non VR, VS frame for sending and usually serve a special purpose
    # Those are:

    #firmware id read
    print(tec.read_firmware_id())

    #metadata read (read the metadata for a given MeParID)
    #(mepar_type, mepar_flag, instance_nr, max_nr, min_value, max_value, act_value)
    print(tec.read_metadata(1010))

    #big value reads (the default display text in this case)
    print(tec.read_big_value(6024, MeParType.LATIN1, 1))
    #also available with tec.Get_TEC_DisplayDefaultText(1)

    #bulk value reads
    print(tec.read_bulk([100, 101, 102, 103, 104]))

    # All execute_* functions:
    tec.execute_emergency_stop(
    )  #stops the tec, goes into an error state with MeComError.ERR_CUSTOM_EMERGENCY_STOP
    tec.execute_reset()  #resets the tec
Ejemplo n.º 4
0
def main():
    
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port = "COM10")

    #read the firmware id
    print("Firmware ID: {}".format(tec.read_firmware_id()))

    #read the tec hardware
    print("Device Type: {}".format(tec.Get_COM_DeviceType()))
    print("Hardware Version: {}".format(tec.Get_COM_HardwareVersion()))
    print("Serial Number: {}".format(tec.Get_COM_SerialNumber()))

    #read the tec status
    print(tec.status())
Ejemplo n.º 5
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    #
    # The tec object implements all publicly known and available in/outs of the TEC
    # These properties are identified by a number called MeParID
    # Sometimes one might want to these ID's directly instead of the convenience functions, or direct calls
    # as well as interpreting the raw answers to that.
    # For those tasks, the tec object proved the read_raw and write_raw functions

    #
    # The actual temperature is known under the MeParID=1000
    # Lets read it out with the three known methods:
    print("Temperature (Convenience Function): {} °C".format(
        tec.temperature()))
    print("Temperature (Direct Function): {} °C".format(
        tec.Get_TEC_ObjectTemperature()))
    print("Temperature (Raw Function): {} °C".format(tec.read_raw(1000)))

    #As one can see however, the read_raw call returned a byte array instead.
    #It has to be interpreted as a float to be valid.
    #The TEC_Helper includes the MeParType class to do exactly that:
    raw_response = tec.read_raw(1000)
    interpreted_response = MeParType.FLOAT32.interpret_type(raw_response)
    print("---")
    print("Raw: {} --> Interpreted: {}".format(raw_response,
                                               interpreted_response))

    #
    # Also, the TEC class inherits a TEC_PARAMETERS array, which includes information about every known MeParID
    # Lets find the info about the MeParID=1050 for example:
    for d in tec.TEC_PARAMETERS:
        if d["id"] == 1050:
            print(d)
            break

    #
    # This can also be automated by the find_meparid function which takes in the meparid OR the name string
    print("---")
    print(tec.find_meparid(1010))
    print("---")
    print(tec.find_meparid("SinkTemperature"))
Ejemplo n.º 6
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")
    print(tec.read_firmware_id())

    #check if TEC is running
    if tec.status() != MeCom_DeviceStatus.Run:
        print("TEC is not running")
        return

    #temp the tec started out with
    starting_temp = tec.target_temperature()

    #perform the measurement run
    ramp_max_delta = 4.0  # maximunm temperature deviation to set
    ramp_min_delta = 0.1  # minimum temperature deviation to set
    ramp_max_time = 120.0  # maximum time for each ramp
    ramp_min_time = 30.0  # minimum time for each ramp
    ramps_n = 20  # perform 20 runs
    measurement_time = 0.05  # minimum time between measurements
    (times, setpoints, temps) = tec_perform_response_curves(
        tec, starting_temp, ramp_max_delta, ramp_min_delta, ramp_max_time,
        ramp_min_time, ramps_n, measurement_time)

    #reset to starting temperature
    tec.write_target_temperature(starting_temp)

    #transfer function estimation
    rate = len(times) / (times[-1] - times[1])
    _, pxy = csd(setpoints, temps, fs=rate, window='hann', nperseg=512)
    pxx_f, pxx = welch(setpoints, fs=rate, window='hann', nperseg=512)
    tfe_abs = [abs(xy / xx) for xy, xx in zip(pxy, pxx)]
    tfe_arg = [180.0 / pi * (xy / xx).imag for xy, xx in zip(pxy, pxx)]

    #plot results
    fig, axs = plt.subplots(2)
    axs[0].loglog(pxx_f, tfe_abs)
    axs[0].set(xlabel='Time t / s', ylabel='Temperature T / °C')
    axs[1].semilogx(pxx_f, tfe_arg)
    axs[1].set(xlabel='Time t / s', ylabel='Phase phi / °')
    plt.show()
Ejemplo n.º 7
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    # By default, all functions will read/write to channel 1
    # This can always be changed by using the channel option:
    print("Temperature Ch1: {}".format(tec.temperature(channel=1)))
    print("Temperature Ch2: {}".format(tec.temperature(channel=2)))

    #
    # Also, both channels can be read sequentially too:
    print(tec.temperature(channel=[1, 2]))
    #reading these simultaneously requires bulk reads (example 10)

    #
    # This also works for direkt functions as well as raw functions reads/writes
    tec.Set_TEC_CurrentLimitation(2.0, channel=[1, 2])
    print(tec.read_raw(1010, channel=2))
Ejemplo n.º 8
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    #
    # Bulk reads allow for reading multiple properties on multiple channels at once

    #
    #read both temperature channels at once:
    print(tec.read_bulk(1000, channels=[1, 2]))

    #
    #read the temperature and target temperature at channel 1 at once
    print(tec.read_bulk([1000, 1010]))

    #
    #One can specify the properties via their direct MeParID or their name:
    print(tec.read_bulk([1000, "TargetObjectTemperature"], channels=1))

    #
    #If both arguments are in vector form, then every parameter entry is read at the respective defined channel
    #Read temperature in channel 1, voltage in channel 2, and current in channel 1
    print(
        tec.read_bulk([
            "ObjectTemperature", "ActualOutputVoltage", "ActualOutputCurrent"
        ],
                      channels=[1, 2, 1]))

    #
    #Read the complete Hardware/Software identification
    print("---")
    read_str = [
        "DeviceType", "HardwareVersion", "SerialNumber", "FirmwareVersion",
        "DeviceStatus"
    ]
    answer = tec.read_bulk(read_str)
    for rs, a in zip(read_str, answer):
        print("{}: {}".format(rs, a))
Ejemplo n.º 9
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    #provoke an emergency error
    tec.execute_emergency_stop()
    time.sleep(1)

    #An error state is always indicated in the MeCom_DeviceStatus
    status = tec.status()
    if status == MeCom_DeviceStatus.Error:
        #Generally: if the TEC is in an error state, the get_error function can retreive all necessary information
        (err_number, err_instance, err_parameter,
         err_message) = tec.get_error()
        print("Error Nr. {} in instance {} (parameter {}): {}".format(
            err_number, err_instance, err_parameter, err_message))
        print("---")
    else:
        print("No Error")

    #If a request errors, then an exception (type: MeComException) will be raised
    try:
        #provoke an exception by raw reading a MeParID which does not exist
        tec.read_raw(999)
    except MeComException as e:
        print("MeCom Exception code {} ({}): {} => \"{}\"".format(
            e.mecom_error_number, e.mecom_error.name, e.mecom_error_message,
            str(e)))
        print("---")

    #
    # To recover from a fail state, the tec can programmatically be reset
    tec.execute_reset()

    #wait for reset and read out status again
    time.sleep(5)
    status = tec.status()
    print(status)
Ejemplo n.º 10
0
def main():

    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    #read current temperature and temperature target
    print("Temperature: {} °C".format(tec.temperature()))
    print("Target Temperature: {} °C".format(tec.target_temperature()))

    #change temperature target and wait for 10s
    print("Changing temperature target to 30°C and wait for 10s")
    tec.write_target_temperature(30.0)
    time.sleep(10.0)

    #read current temperature
    print("Temperature: {} °C".format(tec.temperature()))
    print("Target Temperature: {} °C".format(tec.target_temperature()))
    if tec.temperature_is_stable():
        print("Temperature is stable.")
    else:
        print("Temperature is NOT stable!")

    #reset temperature
    print("Reset temperature to 26°C")
    tec.write_target_temperature(26.0)
Ejemplo n.º 11
0
def main():

    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    #
    # The usual tec object provides for some convenience functions
    # to read out temperature, voltage, currents and their targets/limits
    #
    print("Temperature: {} °C".format(tec.temperature()))
    print("Output Current: {} A".format(tec.current()))
    print("Output Voltage: {} V".format(tec.voltage()))

    print("---")

    print("Target Temperature: {} °C".format(tec.target_temperature()))
    print("Current Limit: {} A".format(tec.current_limit()))
    print("Current Error Threshold: {} A".format(
        tec.current_error_threshold()))
    print("Voltage Limit: {} V".format(tec.voltage_limit()))
    print("Voltage Error Threshold: {} V".format(
        tec.voltage_error_threshold()))

    print("---")

    #
    # Check if temperature is stable
    #
    if tec.temperature_is_stable():
        print("Temperature is stable.")
    else:
        print("Temperature is NOT stable!")
Ejemplo n.º 12
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    #
    # For some values, automatic enumerations are available

    #
    # ATTENTION HERE: FOR THE TEC 1092, THE MeCom_CurrentSource AND MeCom_CurrentSource2Out
    # ARE DIFFERENT TO ALL OTHER TECS
    # THESE ARE CURRENTLY COMMENTED OUT. USE WITH CAUTION
    # THE DIFFERENCE WAS MADE INTO THE NAME:
    # MeCom_CurrentSource_1092 vs. MeCom_CurrentSource_Other
    # AND
    # MeCom_CurrentSource2Out_1092 vs. MeCom_CurrentSource2Out_Other
    #
    triples = [
        [MeCom_DeviceStatus, tec.Get_COM_DeviceStatus, 104],
        [MeCom_SaveDataToFlash, tec.Get_COM_ParameterSystemFlashStatus, 109],
        [MeCom_DriverStatus, tec.Get_TEC_DriverStatus, 1080],
        [MeCom_FlashStatus, tec.Get_TEC_ParameterSystemFlashStatus, 1081],
        [MeCom_TemperatureIsStable, tec.Get_TEC_TemperatureIsStable, 1200],
        [MeCom_InputSelection, tec.Get_TEC_OutputStageInputSelection, 2000],
        [MeCom_OutputStageStatus, tec.Get_TEC_OutputStageEnable, 2010],
        [MeCom_GeneralOperatingMode, tec.Get_TEC_GeneralOperatingMode, 2040],
        [MeCom_ThermalPowerRegulationMode, tec.Get_TEC_ModelizationMode, 3020],
        [MeCom_PositiveCurrentIs, tec.Get_TEC_PeltierPositiveCurrentIs, 3034],
        [MeCom_SensorType, 4034, 4034],
        [
            MeCom_SinkTemperatureSelection,
            tec.Get_TEC_SinkTemperatureSelection, 5030
        ],
        [MeCom_TuningStatus, tec.Get_TEC_AtmTuningStatus, 51020],
        [MeCom_PGAGain, tec.Get_TEC_ObjMeasPGAGain, 6000],
        #[MeCom_CurrentSource_1092, tec.Get_TEC_ObjMeasCurrentSource, 6001],
        [MeCom_CurrentSource_Other, tec.Get_TEC_ObjMeasCurrentSource, 6001],
        #[MeCom_CurrentSource2Out_1092, 6008, 6008],
        [MeCom_CurrentSource2Out_Other, 6008, 6008],
        [MeCom_MeasurementType, 6009, 6009],
        [
            MeCom_SensorTypeSelection, tec.Get_TEC_ObjMeasSensorTypeSelection,
            6005
        ],
        [MeCom_LookupTableStatus, tec.Get_TEC_LutTableStatus, 52002],
        [MeCom_DisplayType, tec.Get_TEC_DisplayType, 6020],
        [MeCom_DisplayLineAlternativeMode, tec.Get_TEC_AlternativeMode, 6023],
        [MeCom_GPIOFunction, tec.Get_TEC_PbcFunction, 6100],
        [MeCom_GPIOLevelAssignment, 6101, 6101],
        [MeCom_HardwareConfiguration, 6102, 6102],
        [MeCom_GPIOChannel, 6103, 6103],
        [MeCom_ActualTemperatureSource, 6120, 6120],
        [MeCom_ObserveMode, 6302, 6302],
        [MeCom_ControlSpeed, 6301, 6301],
        [MeCom_SourceSelection, tec.Get_TEC_MiscActObjectTempSource, 6300],
        [MeCom_DeviceTemperatureMode, 6330, 6330]
    ]

    #traverse all:
    for enumType, function, meparid in triples:
        if type(function) == int:
            result = tec._read_value(meparid, MeParType.INT32)
        else:
            result = function()
        enum = enumType(result)
        print("{:<32} (MeParID: {:<5}): Value {} = \"{:<21}\" [{}]".format(
            enumType.__name__, meparid, enum, enum.name,
            "no associated function"
            if type(function) == int else function.__name__))
Ejemplo n.º 13
0
def main():
    #allocate the tec object for a serial communication at serial port COM10
    tec = TEC_Serial(port="COM10")

    #
    # The tec object only provides convenience functions for commonly used values
    # For all other values, there is a raw function implemented by a name in the
    # shape of:
    # (Get|Set)_PREFIX_ValueName
    # As an example, lets look at the measured temperature:
    #
    # Get_TEC_ObjectTemperature
    #
    # Get|Set: Get
    # Prefix:  TEC
    # Name:    ObjectTemperature
    #
    # All those functions are implemented in src/TEC_autogen for reference.
    # The convenience functions are then just wrappers around those raw functions
    #

    #
    # For example:
    # the current_limit convenience function just wraps Get_TEC_CurrentLimitation
    # so we expect the same value from both calls:
    print("{} == {} ?".format(tec.current_limit(),
                              tec.Get_TEC_CurrentLimitation()))

    #
    # Lets read the sink temperature anf fan speed in this way:
    print("Sink temperature: {} °C".format(tec.Get_TEC_SinkTemperature()))
    print("Fan Speed: {} RPM".format(tec.Get_TEC_FanActualFanSpeed()))

    #
    # Write the current output limit via the convenience function and its direct function
    tec.write_current_limit(2.1)
    tec.Set_TEC_CurrentLimitation(2.2)

    #
    # A write to the tec usually waits for an answer to verify it was received and executed properly.
    # If there is no need to do that, use the fire_and_forget option to discard any answers
    # This is commonly used in situations were multiple TECs are on the same bus and the broadcast address is used
    tec.Set_TEC_CurrentLimitation(2.0, fire_and_forget=True)
    print(tec.current_limit())