|
3 weeks ago | |
---|---|---|
C-MAG.png | 4 weeks ago | |
CTR-commands.pdf | 3 weeks ago | |
CTlaser-manual.pdf | 3 weeks ago | |
DCPower.png | 4 weeks ago | |
Dibujo.png | 4 weeks ago | |
Multimeter.png | 4 weeks ago | |
Pyrometer.png | 4 weeks ago | |
README.md | 3 weeks ago | |
SystemDC.png | 4 weeks ago | |
Tabla-comandos-pyrometer.PNG | 3 weeks ago | |
Table-Emissivity.PNG | 3 weeks ago |
README.md
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.
Equipment
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
:
pip install pyvisa
To find out if Pyvisa detects the instruments, run the following code in 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:
'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:
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
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:
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
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
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('<Return>', 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('<Return>', lambda event: aplicar_valores_fuente())
actualizar_lecturas()
ventana.mainloop()