diff --git a/DMM4040.png b/DMM4040.png new file mode 100644 index 0000000..eebd6a5 Binary files /dev/null and b/DMM4040.png differ diff --git a/README.md b/README.md index 45afe40..8a064d1 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,15 @@ The image shows the parts that make up the experiment. | 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") +| Digit Multimeter PICOTEST | M3500A | Multimeter used to measure voltage | ![](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") +| Digit Multimeter Tektronix | DMM4040 | Multimeter used to measure current | ![](DMM4040.png "DMM4040") ## Communication +### Communication with `Digit Multimeter M3500A` and `System DC Power Supply 150 V / 10 A` 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`: @@ -36,7 +38,7 @@ If a series of codes are displayed in the Terminal, it means the instruments hav ```Terminal 'USB0::0x164E::0x0DAD::TW00013644::INSTR' ``` -### Communication with the Optris CTlaser pyrometer +### Communication with the Optris CTlaser pyrometer `OPTCTLLTSF` 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: @@ -60,7 +62,7 @@ This command requests the process temperature (Tprocess). The sensor's response ```python temperatura = ((byte1 * 256 + byte2) - 1000) / 10 ``` -All this information was obtained from the manufacturer's manuals which are attached to this repository. +All this information was obtained from the manufacturer's manuals which are attached to this repository. [CTR-commands](https://gitea.itmorelia.com/delfin-25a/Experimento-de-Laboratorio-temperatura/src/branch/main/CTlaser-manual.pdf) and [CTlaser-manual](https://gitea.itmorelia.com/delfin-25a/Experimento-de-Laboratorio-temperatura/src/branch/main/CTlaser-manual.pdf) #### Minimum code for pyrometer reading ```python @@ -83,150 +85,43 @@ else: sensor.close() ``` -## Code +### Communication with `Digit Multimeter Tektronix DMM4040` +Para poder establecer comunicación entre el multímetro digital **Tektronix DMM4040** y la computadora mediante una interfaz **RS-232**, utilizando Python y la librería **Pyvisa**. La comunicación se realiza por comandos **SCPI** (Standar Commands for Programmable Instruments), ampliamente utilizados en istrumentación electrónica. +
Para poder comunicarnos con el multimetro es necesario tener un cable serial RS-232 a USB (adaptador compatible, ejemplo: PL2303, CH340, FTDI) y conectarlo tanto a la salida de datos serial del multimetro digital DMM4040 como a un puerto USB disponible en el computador, también, es necesario tener instalado el software de NI_VISA (Controlador requerido para comunicación serial por PyVISA), Python e instalar la librería `pyvisa`. + +#### Código de ejemplo para conectar el multimetro DMM4040 con pyhton ```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 - +# Crear administrador VISA 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) - +puerto = 'ASRL16::INSTR' # Asegurarse que este valor coincida con NI MAX 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') + multimetro = rm.open_resource(puerto) + + # Configuración de la interfaz RS-232 + multimetro.baud_rate = 9600 + multimetro.data_bits = 8 + multimetro.parity = pyvisa.constants.Parity.none + multimetro.stop_bits = pyvisa.constants.StopBits.one + multimetro.flow_control = pyvisa.constants.ControlFlow.none + multimetro.timeout = 5000 + multimetro.write_termination = '\r\n' + multimetro.read_termination = '\r\n' + # Configurar medición de corriente DC (puedes usar VOLT:DC para voltaje) + multimetro.write("*CLS") + multimetro.write("CONF:CURR:DC") + multimetro.write("VOLT:DC:NPLC 1") + multimetro.write("TRIG:SOUR IMM") + multimetro.write("TRIG:DEL 0") + multimetro.write("SAMP:COUN 1") + # Iniciar y obtener la lectura + multimetro.write("INIT") + lectura = multimetro.query("FETCH?") + primera_lectura = lectura.strip().split(',')[0] + print("Corriente medida (DC):", primera_lectura, "A") 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() -``` \ No newline at end of file + print("Error en la comunicación con el multímetro:", str(e)) +``` +## Code \ No newline at end of file diff --git a/ni-visa_19.5_online_repack3.rar b/ni-visa_19.5_online_repack3.rar new file mode 100644 index 0000000..7c910c8 Binary files /dev/null and b/ni-visa_19.5_online_repack3.rar differ