diff --git a/Contraste.sln b/Contraste.sln
new file mode 100644
index 0000000..a1b4a53
--- /dev/null
+++ b/Contraste.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.14.37216.2 d17.14
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Contraste", "Contraste\Contraste.csproj", "{D7324B75-9036-4DC1-91B8-84FCF8D101D6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D7324B75-9036-4DC1-91B8-84FCF8D101D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7324B75-9036-4DC1-91B8-84FCF8D101D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7324B75-9036-4DC1-91B8-84FCF8D101D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D7324B75-9036-4DC1-91B8-84FCF8D101D6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {04815428-65B0-4F3E-A204-944E0F290470}
+ EndGlobalSection
+EndGlobal
diff --git a/Contraste/Contraste.csproj b/Contraste/Contraste.csproj
new file mode 100644
index 0000000..59296f0
--- /dev/null
+++ b/Contraste/Contraste.csproj
@@ -0,0 +1,25 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+ ..\..\..\..\Cognex\DataMan SDK 5.6.3\Binaries\PC\Cognex.DataMan.CogNamer.PC.dll
+
+
+ ..\..\..\..\Cognex\DataMan SDK 5.6.3\Binaries\PC\Cognex.DataMan.SDK.Discovery.PC.dll
+
+
+ ..\..\..\..\Cognex\DataMan SDK 5.6.3\Binaries\PC\Cognex.DataMan.SDK.PC.dll
+
+
+ ..\..\..\..\Cognex\DataMan SDK 5.6.3\Binaries\PC\Cognex.DataMan.SDK.Utils.PC.dll
+
+
+
+
diff --git a/Contraste/Program.cs b/Contraste/Program.cs
new file mode 100644
index 0000000..a7cc67a
--- /dev/null
+++ b/Contraste/Program.cs
@@ -0,0 +1,228 @@
+using System;
+using System.IO;
+using System.Net;
+using System.Threading;
+using System.Xml;
+using Cognex.DataMan.SDK;
+
+class Program
+{
+ private static AutoResetEvent _esperaLectura = new AutoResetEvent(false);
+ private static bool _contrasteCapturado = false;
+ private static object _lock = new object();
+
+ private static string _configDirectory = "C:\\Jabil DM Config Station\\Files\\";
+ private static string _configPath = "";
+
+ static void Main(string[] args)
+ {
+ _configPath = Path.Combine(_configDirectory, "ConfigIP.txt");
+
+ Console.WriteLine("==========================================");
+ Console.WriteLine(" PROGRAMA: CAPTURA DE CONTRASTE ");
+ Console.WriteLine("==========================================\n");
+
+ // --- 1. VALIDACIÓN DEL ARCHIVO DE CONFIGURACIÓN ---
+ if (!File.Exists(_configPath))
+ {
+ Console.WriteLine($"[ERROR] No se encontró el archivo base: {_configPath}");
+ Thread.Sleep(3000);
+ return;
+ }
+
+ string[] configLines = File.ReadAllLines(_configPath);
+ if (configLines.Length < 2)
+ {
+ Console.WriteLine("[ERROR] El archivo ConfigIP.txt no tiene el formato correcto.");
+ Thread.Sleep(3000);
+ return;
+ }
+
+ string ipString = configLines[1].Trim();
+ if (!IPAddress.TryParse(ipString, out var lectorIp))
+ {
+ Console.WriteLine($"[ERROR] La IP '{ipString}' no es válida.");
+ Thread.Sleep(3000);
+ return;
+ }
+
+ Console.WriteLine($"Conectando al DataMan en la IP: {lectorIp}...");
+ EthSystemConnector connector = new EthSystemConnector(lectorIp);
+ DataManSystem myDevice = new DataManSystem(connector);
+
+ try
+ {
+ myDevice.Connect(5000);
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine("[OK] Conectado con éxito.");
+ Console.ResetColor();
+
+ Console.WriteLine("[SISTEMA] Analizando modelo de cámara y forzando configuración...");
+
+ // --- 2. BLINDAJE DE HARDWARE Y CONFIGURACIÓN DMCC ---
+ try
+ {
+ DmccResponse respuestaModelo = myDevice.SendCommand("GET DEVICE.TYPE");
+ string modeloCamara = respuestaModelo.PayLoad.ToUpper();
+ Console.WriteLine($"[SISTEMA] Hardware físico detectado: {modeloCamara}");
+
+ // Forzamos el Disparador a modo Único / Network (Valor Oficial DMCC: 0)
+ myDevice.SendCommand("SET TRIGGER.TYPE 0");
+
+ // Intentamos encender las métricas. Si la cámara no tiene licencia, lo rechazará internamente.
+ try { myDevice.SendCommand("SET DECODER.1D-QUALITY-METRICS 1"); } catch { }
+ try { myDevice.SendCommand("SET TRUCHECK.STANDARD 2"); } catch { }
+ try { myDevice.SendCommand("SET DECODER.1D-PCM 1"); } catch { }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[AVISO] Algunas configuraciones DMCC previas fallaron: {ex.Message}");
+ }
+
+ // --- 3. SUSCRIPCIÓN Y EXTRACCIÓN DE RESULTADOS ---
+ myDevice.SetResultTypes(ResultTypes.ReadString | ResultTypes.ReadXml);
+ Console.WriteLine("[SISTEMA] Suscripción a métricas activada.");
+
+ // -------------------------------------------------------------------------
+ // EVENTO 1: XML
+ // -------------------------------------------------------------------------
+ myDevice.XmlResultArrived += (sender, e) =>
+ {
+ lock (_lock)
+ {
+ if (_contrasteCapturado) return;
+
+ if (!string.IsNullOrEmpty(e.XmlResult))
+ {
+ try
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(e.XmlResult);
+
+ XmlNode nodoContraste = doc.SelectSingleNode("//contrast/value") ?? doc.SelectSingleNode("//symbol_contrast/value");
+ if (nodoContraste != null)
+ {
+ string contrasteDetectado = nodoContraste.InnerText.Replace("+", "").Trim();
+ Console.ForegroundColor = ConsoleColor.Cyan;
+ Console.WriteLine($"\n[ÉXITO - VÍA XML] Contraste capturado: {contrasteDetectado}");
+ Console.ResetColor();
+
+ _contrasteCapturado = true;
+ ActualizarArchivoConfigSeguro(contrasteDetectado);
+ _esperaLectura.Set();
+ }
+ else
+ {
+ // =================================================================
+ // ALERTA VISUAL DE HARDWARE INCOMPATIBLE O SIN LICENCIA
+ // =================================================================
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine("\n========================================================");
+ Console.WriteLine(" [ALERTA DE HARDWARE] ");
+ Console.WriteLine("========================================================");
+ Console.WriteLine("La cámara realizó la lectura, pero NO incluyó contraste.");
+ Console.WriteLine("Causa posible: Este lector NO TIENE LA LICENCIA (Feature");
+ Console.WriteLine("Key) de 'Quality Metrics' o 'PCM' instalada de fábrica.");
+ Console.WriteLine("========================================================");
+ Console.ResetColor();
+ _esperaLectura.Set(); // Abortamos la espera para no perder 10 segundos
+ }
+ }
+ catch { }
+ }
+ }
+ };
+
+ // -------------------------------------------------------------------------
+ // EVENTO 2: TEXTO (Respaldo)
+ // -------------------------------------------------------------------------
+ myDevice.ReadStringArrived += (sender, e) =>
+ {
+ lock (_lock)
+ {
+ if (_contrasteCapturado) return;
+
+ if (!string.IsNullOrEmpty(e.ReadString))
+ {
+ string[] partes = e.ReadString.Split('\t');
+ if (partes.Length >= 2)
+ {
+ string contrasteDetectado = partes[1].Trim();
+ Console.ForegroundColor = ConsoleColor.Cyan;
+ Console.WriteLine($"\n[ÉXITO - VÍA TEXTO] Contraste capturado: {contrasteDetectado}");
+ Console.ResetColor();
+
+ _contrasteCapturado = true;
+ ActualizarArchivoConfigSeguro(contrasteDetectado);
+ _esperaLectura.Set();
+ }
+ }
+ }
+ };
+
+ // --- 4. EJECUCIÓN DEL DISPARO ---
+ Console.WriteLine("\nEnviando disparo por software...");
+ myDevice.SendCommand("TRIGGER ON");
+
+ // Esperamos hasta 10 segundos
+ _esperaLectura.WaitOne(10000);
+
+ if (!_contrasteCapturado)
+ {
+ Console.WriteLine("\n[FINALIZADO] La sesión de lectura concluyó.");
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine($"\n[ERROR CRÍTICO] Hubo un problema de conexión: {ex.Message}");
+ Console.ResetColor();
+ }
+ finally
+ {
+ try { myDevice.SendCommand("TRIGGER OFF"); } catch { }
+ try { myDevice.Disconnect(); } catch { }
+ }
+
+ Console.WriteLine("\nEl programa finalizará en 3 segundos...");
+ Thread.Sleep(3000);
+ }
+
+ ///
+ /// Modifica de forma segura el archivo TXT para que LabVIEW lea el contraste
+ ///
+ private static void ActualizarArchivoConfigSeguro(string valorContraste)
+ {
+ try
+ {
+ string copiaPath = Path.Combine(_configDirectory, "ConfigIP_Copia.txt");
+ string[] lineasOriginales = File.ReadAllLines(_configPath);
+
+ string lineasMAC = lineasOriginales.Length > 0 ? lineasOriginales[0] : "";
+ string lineaIP = lineasOriginales.Length > 1 ? lineasOriginales[1] : "";
+
+ string[] nuevasLineas = new string[] {
+ lineasMAC,
+ lineaIP,
+ valorContraste
+ };
+
+ File.WriteAllLines(copiaPath, nuevasLineas);
+
+ if (File.Exists(_configPath))
+ {
+ File.Delete(_configPath);
+ Thread.Sleep(100);
+ }
+
+ File.Move(copiaPath, _configPath);
+ Console.WriteLine("[SISTEMA] ConfigIP.txt actualizado en la línea 3.");
+ }
+ catch (Exception ex)
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine($"[ERROR DE ARCHIVO] No se pudo guardar: {ex.Message}");
+ Console.ResetColor();
+ }
+ }
+}
\ No newline at end of file