# Monitoring of Electrical and Thermal Parameters in a Metal Part # Introduction This project aims to implement a data acquisition system for measuring temperature, voltage, and current in a metal part subjected to constant current, with the purpose of analyzing its electrical and thermal behavior in real time. # Methodology ## Representative drawing The image shows the parts that make up the experiment. ![](Dibujo.png "Diagrama") ## Equipment | Equipment | Model | Description | Pickture | |---------|-------------|-------------|----------| | Digit Multimeter | M3500A | Multimeter used to measure voltage and current | ![](Multimeter.png "Multimeter") | Programmable DC Power Supply 0-30 V | PWS4305 | DC supply for powering the Pyrometer | ![](DCPower.png "DCpower") | System DC Power Supply 150 V / 10 A | N5770A | DC source to heat the metal part | ![](SystemDC.png "SystemDC") | Pyrometer CTLaser LT | OPTCTLLTSF | Pyrometer, temperature sensor | ![](Pyrometer.png "Pyrometer") | Hot plate | IKA C-MAG HS7 | Heated bed with temperature control | ![](C-MAG.png "c-mag") ## Communication To communicate the `Digit Multimeter M3500A` and the `System DC Power Supply 150 V / 10 A` a USB cable was used through the VISA protocol (Virtual Instrument Software Architecture) which is a standard for configuring, programming and debugging instrumentation systems that include GPIB interfaces. To do this, you first have to download the NI-VISA software on the computer you intend to use since Python is used to communicate through the Python wrapper `pyvisa` which requires the real VISA installation on the system. Otherwise an error will be thrown.
It is installed `pyvisa`: ```bash pip install pyvisa ``` To find out if Pyvisa detects the instruments, run the following code in Python: ```python import pyvisa rm = pyvisa.ResourceManager() print(rm.list_resources()) ``` If a series of codes are displayed in the Terminal, it means the instruments have indeed been detected and are responding with their data. Something like this: ```Terminal 'USB0::0x164E::0x0DAD::TW00013644::INSTR' ``` ### Communication with the Optris CTlaser pyrometer Communication with the Optris CTlaser pyrometer was performed using the sensor's native binary protocol, using the Python programming language and the standard `pyserial` library for access to the COM port (virtual USB RS-232).
The sensor protocol consists of sending single-byte binary commands and receiving two-byte encoded responses, representing data such as temperature in `uint16` format.
Libraries used: ```python import serial import time ``` |communication parameters| | ---------------------------|----| |Baudrate |115200 bps| |Bits de datos |8| |Paridad |Ninguna| |Bits de parada |1| |Timeout |1 segundo| ### Command to get temperature ```python COMANDO_TEMPERATURA = bytes([0x01]) ``` This command requests the process temperature (Tprocess). The sensor's response is 2 bytes, which must be interpreted using the following formula: ```python temperatura = ((byte1 * 256 + byte2) - 1000) / 10 ``` All this information was obtained from the manufacturer's manuals which are attached to this repository. #### Minimum code for pyrometer reading ```python import serial import time sensor = serial.Serial('COM9', baudrate=9600, timeout=1) time.sleep(2) sensor.write(bytes([0x01])) #Comando para solicitar la temperatura time.sleep(0.2) respuesta = sensor.read(2) if len(respuesta) == 2: byte1, byte2 = respuesta[0], respuesta[1] temperatura = ((byte1 * 256 + byte2) - 1000) / 10 print(f"Temperatura: {temperatura:.1f} °C") else: print("No se recibió respuesta válida.") sensor.close() ``` ## Code ```python import tkinter as tk from tkinter import messagebox import pyvisa import time import csv from datetime import datetime import os from decimal import Decimal import serial PUERTO = 'COM9' #Puerto COM en donde se encuetra el Pyrometer BAUDRATE = 115200 COMANDO_TEMPERATURA = bytes([0x01]) # Según protocolo binario del sensor ID_M3500A = 'USB0::0x164E::0x0DAD::TW00013644::INSTR' #Multimetro ID_N5770A = 'USB0::0x0957::0x0807::N5770A-US11M7295J::INSTR' #Fuente rm = pyvisa.ResourceManager() sensor = serial.Serial( port=PUERTO, baudrate=BAUDRATE, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1 ) time.sleep(2) try: # Conectar al multímetro m3500a = rm.open_resource(ID_M3500A) m3500a.write('*RST') m3500a.write('*CLS') m3500a.write("CONF:VOLT:DC 100") # Voltaje DC, rango fijo de 100 V m3500a.write("CONF:CURR:DC 10") # Corriente DC, rango fijo de 10 A # Conectar a la fuente de poder fuente = rm.open_resource(ID_N5770A) fuente.write('*RST') fuente.write('*CLS') fuente.write('OUTP ON') except Exception as e: messagebox.showerror("Error", f"Error en la conexión con los instrumentos:\n{e}") exit() directorio = "Mediciones" os.makedirs(directorio, exist_ok=True) timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") archivo_csv = os.path.join(directorio, f"mediciones_{timestamp}.csv") with open(archivo_csv, mode='w', newline='') as archivo: escritor = csv.writer(archivo) escritor.writerow(["Temperatura","Voltaje Medido (V)", "Corriente Medida (A)","Voltaje fuente","Corriente fuente","Fecha"]) ##################################################### Lectura del multimetro def actualizar_lecturas(): try: # === Leer temperatura del sensor === sensor.write(COMANDO_TEMPERATURA) time.sleep(0.2) respuesta = sensor.read(2) if len(respuesta) == 2: byte1, byte2 = respuesta[0], respuesta[1] temperatura = ((byte1 * 256 + byte2) - 1000) / 10 label_temperatura.config(text=f"Temperatura: {temperatura:.1f} °C") else: temperatura = None label_temperatura.config(text="Temperatura: --- °C") m3500a.write('READ?') # Lectura del multimetro voltaje = float(m3500a.read().strip()) label_voltaje.config(text=f"Voltaje DC: {voltaje:.3f} V") fuente.write("VOLT?") # Lectura de la fuente voltaje_fuente = float(fuente.read().strip()) fuente.write("CURR?") corriente_fuente = float(fuente.read().strip()) ##################################################### Registro en CSV fecha_actual = datetime.now().strftime("%H:%M:%S") with open(archivo_csv, mode='a', newline='') as archivo: escritor = csv.writer(archivo) escritor.writerow([temperatura ,voltaje, "", voltaje_fuente, corriente_fuente, fecha_actual]) except Exception as e: label_temperatura.config(text="Temperatura: Error") label_voltaje.config(text="Voltaje DC: Error") label_corriente.config(text="Corriente DC: Error") print(f"Error al leer: {e}") # Repetir cada 500 ms ventana.after(500, actualizar_lecturas) ##################################################### Control de fuente def aplicar_valores_fuente(): try: v_set = entrada_voltaje.get() i_set = entrada_corriente.get() fuente.write(f"VOLT {v_set}") fuente.write(f"CURR {i_set}") #messagebox.showinfo("Configuración", "Valores aplicados correctamente.") except Exception as e: messagebox.showerror("Error", f"No se pudo configurar la fuente:\n{e}") ##################################################### Window ventana = tk.Tk() ventana.title("CONTROL Y MEDICIÓN") ventana.geometry("300x250") ######## Lecturas label_temperatura = tk.Label(ventana, text="temperaruta: --- °C", font=("Arial", 14)) label_temperatura.pack(pady=5) label_voltaje = tk.Label(ventana, text="Voltaje DC: --- V", font=("Arial", 14)) label_voltaje.pack(pady=5) label_corriente = tk.Label(ventana, text="Corriente DC: --- A", font=("Arial", 14)) label_corriente.pack(pady=5) ######## Control de fuente frame_fuente = tk.Frame(ventana) frame_fuente.pack(pady=10) tk.Label(frame_fuente, text="Voltaje de salida (V):",font=("Arial",14)).grid(row=0, column=0, padx=5, pady=2) entrada_voltaje = tk.Entry(frame_fuente, width=10) entrada_voltaje.grid(row=0, column=1) entrada_voltaje.bind('', lambda event: aplicar_valores_fuente()) tk.Label(frame_fuente, text="Corriente límite (A):",font=("Arial",14)).grid(row=1, column=0, padx=5, pady=2) entrada_corriente = tk.Entry(frame_fuente, width=10) entrada_corriente.grid(row=1, column=1) entrada_corriente.bind('', lambda event: aplicar_valores_fuente()) actualizar_lecturas() ventana.mainloop() ```