using System.IO.Ports;
using System.Text;
namespace Termite_SAI_05_.NET_8._0
{
public partial class Form1 : Form
{
SerialPort puertoSerie;
bool verComandoBFlag = false;
bool verComandoX72Flag = false;
bool verComandoX5Flag = false;
const string COMANDO_B = "B\r";
const string COMANDO_X72 = "X72\r";
const string COMANDO_X5 = "X5\r";
public Form1()
{
InitializeComponent();
InicioPuertoSerie();
}
private void Form1_Load(object sender, EventArgs e)
{
//timer1.Start();
timer1.Enabled = true;
}
/* Iniciar y configurar el puerto serie */
private void InicioPuertoSerie()
{
try
{
puertoSerie
= new SerialPort
() {
// Configuración del puerto serie.
PortName = "COM3", // Nombre del puerto serie.
BaudRate = 2400, // Velocidad en baudios.
Parity = Parity.None, // Esquema para comprobar la paridad de cada byte recibido.
StopBits = StopBits.One, // Número de bits de parada por byte.
DataBits = 8, // Número de bits de datos por byte.
Handshake = Handshake.None, // Protocolo de establecimiento.
Encoding = Encoding.GetEncoding(28591),
DtrEnable = true, // Línea de terminal de datos.
RtsEnable = true, // Línea de solicitud.
// Establecer los tiempos de espera de lectura / escritura.
ReadTimeout = 500, // Tiempo de espera de escritura en ms.
WriteTimeout = 500, // Tiempo de espera de escritura en ms.
// Más configuraciones.
DiscardNull = false, // Descartar bytes nulos recibidos.
ParityReplace = 63, // Reemplaza los bytes recibidos con errores de paridad.
ReadBufferSize = 4096, // Tamaño del búfer de lectura en bytes.
WriteBufferSize = 2018, // Tamaño del búfer de escritura en bytes.
ReceivedBytesThreshold = 1 // Número de bytes que se necesitan.
};
// Abrir puerto serie.
puertoSerie.Open();
// Subscribir el evento DatosRecividos cuando lleguen datos.
puertoSerie.DataReceived += DatosRecibidos;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Warning);
timer1.Stop();
puertoSerie.Close(); // Cierra el puerto en caso de error
}
}
/* Evento para leer asíncronamente datos del puerto serie */
void DatosRecibidos(object sender, SerialDataReceivedEventArgs e)
{
Task.Run(async () =>
{
try
{
await Task.Delay(500); // Pausa para recibir datos.
string cadena = puertoSerie.ReadExisting();
if (!string.IsNullOrEmpty(cadena))
{
if (verComandoBFlag == true) { ProcesoCOMANDO_B(cadena); }
if (verComandoX72Flag) { ProcesoCOMANDO_X72(cadena); }
if (verComandoX5Flag) { ProcesoCOMANDO_X5(cadena); }
}
else
{
Console.Write("Datos leídos corruptos.");
}
}
catch (IndexOutOfRangeException ex)
{
Console.Write("Índice fuera de los límites de la matriz.");
MessageBox.Show(ex.Message);
}
catch (FormatException ex)
{
Console.Write("La cadena de entrada no tiene el formato correcto.");
MessageBox.Show(ex.Message, "Error");
}
});
}
/* Procesar COMANDO_X5 */
private void ProcesoCOMANDO_X5(string cadena)
{
verComandoX5Flag = false;
char[] separadores = { '#', ',', '\r' };
string[] salida = cadena.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
// Al manipular controles de Windows Forms desde un hilo diferente al
// hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia.
if (InvokeRequired)
{
{
ActualizarUIControlComandoX5(salida);
}));
}
else
{
ActualizarUIControlComandoX5(salida);
}
}
/* Procesar COMANDO_X72 */
private void ProcesoCOMANDO_X72(string str)
{
verComandoX72Flag = false;
char[] separadores = { '#', ',', '\r' };
string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
// Al manipular controles de Windows Forms desde un hilo diferente al
// hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia.
if (InvokeRequired)
{
{
ActualizarUIControlComandoX72(salida);
}));
}
else
{
ActualizarUIControlComandoX72(salida);
}
}
/* Procesar COMANDO_B */
private void ProcesoCOMANDO_B(string str)
{
verComandoBFlag = false;
char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S', '\r' };
string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
// Al manipular controles de Windows Forms desde un hilo diferente al
// hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia.
if (InvokeRequired)
{
{
ActualizarUIControlComandoB(salida);
}));
}
else
{
ActualizarUIControlComandoB(salida);
}
}
/* Mostrar datos COMANDO_X5 */
private void ActualizarUIControlComandoX5(string[] salida)
{
label_Resultado_Tension_nominal.Text
= salida[0] + " V";
label_Resultado_Cantidad_del_paquete.Text
= salida[1] + " Baterías";
label_Resultado_Capacidad_del_paquete.Text
= salida[2] + " Ah";
label_Resultado_Cantidad_externa.Text
= salida[3];
label_Resultado_Descarga_maxima.Text
= salida[4] + " Minuto";
// Convertir variable tipo string a tipo uint, es decir, la variable tipo string "salida[5]"
// se convierte en tipo uint "resultadoSalida5".
uint resultadoSalida5 = UInt32.Parse(salida[5]);
// Cálculos.
uint horas = resultadoSalida5 / 60;
//uint minutos = resultadoSalida5 % 60;
label_Resultado_Carga_maxima.Text
= $"{horas} Horas";
}
/* Mostrar datos COMANDO_X72 */
private void ActualizarUIControlComandoX72(string[] salida)
{
label_Resultado_valores_nonimales_de_alimentacion.Text
= salida[0] + " VA / " + salida[1] + " W";
label_Resultado_voltaje_nominal.Text
= salida[2] + " Vac";
label_Resultado_corriente_nominal.Text
= salida[5] + " A";
label_Resultado_valores_nominales_de_frecuencia.Text
= salida[3] + " ~ " + salida[4] + " Hz";
}
/* Mostrar datos COMANDO_B */
private void ActualizarUIControlComandoB(string[] salida)
{
label_I.Text
= salida[0] + " Vac";
label_O.Text
= salida[1] + " Vac";
label_L.Text
= salida[2].TrimStart('0').PadLeft(1, '0') + " %"; // Quita los ceros de la izquierda y pone un cero si no hay nada.
label_B.Text
= salida[3].TrimStart('0').PadLeft(1, '0') + " %"; // Quita los ceros de la izquierda y pone un cero si no hay nada.
label_V.Text
= salida[4] + " Vdc";
label_F.Text
= salida[5].PadRight(5, '0') + " Hz"; // Añade ceros a la derecha.
label_H.Text
= salida[6].PadRight(5, '0') + " Hz";
// Convertir variable tipo string a tipo uint, es decir, la variable tipo string "salida[7]"
// se convierte en tipo uint "resultadoSalida7".
uint resultadoSalida7 = uint.Parse(salida[7]);
#region Horas y minutos.
// Cálculos.
uint horas = resultadoSalida7 / 60;
uint minutos = resultadoSalida7 % 60;
// ¿0 horas y 1 minuto?
if ((horas == 0) && (minutos == 1))
{
label_R.Text = $"{minutos} minuto.";
}
// ¿0 horas y 0 minuto?
if ((horas == 0) && (minutos == 0))
{
label_R.Text = $"{minutos} minutos";
}
// ¿0 horas y más de 1 minuto?
if ((horas == 0) && (minutos > 1))
{
label_R.Text = $"{minutos} minutos.";
}
// ¿1 hora y 0 minutos?
if ((horas == 1) && (minutos == 0))
{
label_R.Text = $"{horas} hora.";
}
// ¿Más de una hora y 0 minutos?
if ((horas > 1) && (minutos == 0))
{
label_R.Text = $"{horas} horas.";
}
// ¿1 hora y 1 minuto?
if ((horas == 1) && (minutos == 1))
{
label_R.Text = $"{horas} hora y {minutos} minuto";
}
// ¿1 hora y más de 1 minuto?
if ((horas == 1) && (minutos > 1))
{
label_R.Text = $"{horas} hora y {minutos} minutos.";
}
// ¿Más de 1 hora y 1 minuto?
if ((horas > 1) && (minutos == 1))
{
label_R.Text = $"{horas} horas y {minutos} minuto.";
}
// ¿Más de 1 horas y más de 1 minuto?
if ((horas > 1) && (minutos > 1))
{
label_R.Text = $"{horas} horas y {minutos} minutos.";
}
#endregion
// Mostrar nivel barra de progreso.
uint barraProgresoL = uint.Parse(salida[2]);
progressBar_L.Value = (int)barraProgresoL;
uint barraProgresoB = uint.Parse(salida[3]);
progressBar_B.Value = (int)barraProgresoB;
uint[] numeros
= new uint[8]; uint contador = 0;
richTextBox1.Clear(); // Limpiar.
foreach (uint elemento in salida[8])
{
richTextBox1.Text += Environment.NewLine; // Nueva línea.
richTextBox1.Text += $"Array: {numeros[contador] = elemento}";
++contador;
}
// Mostrar información configuración del puerto serie.
statusStrip1.Items[0].Text = @$"{puertoSerie.PortName} {puertoSerie.BaudRate} {puertoSerie.DataBits} {puertoSerie.Parity} {puertoSerie.StopBits}";
}
/* Evento de botón: Abrir puerto serie y mandar "B" */
private void button_Comando_B_Click(object sender, EventArgs e)
{
verComandoBFlag = true;
puertoSerie.Write(COMANDO_B);
}
/* Evento de botón: Abrir puerto serie y mandar "X72" */
private void button_Comando_X72_Click(object sender, EventArgs e)
{
timer1.Enabled = false;
Thread.Sleep(1000);
verComandoX72Flag = true;
puertoSerie.Write(COMANDO_X72);
timer1.Enabled = true;
}
private void button_Comando_X5_Click(object sender, EventArgs e)
{
timer1.Enabled = false;
Thread.Sleep(1000);
verComandoX5Flag = true;
puertoSerie.Write(COMANDO_X5);
timer1.Enabled = true;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
timer1.Stop(); // Detiene el temporizador.
Thread.Sleep(700); // 0.7 segundos. 700 milisegundos.
puertoSerie.Close(); // Cierra el puerto serie.
}
private void timer1_Tick_1(object sender, EventArgs e)
{
verComandoBFlag = true;
// Enviar comando B al puerto serie.
puertoSerie.Write(COMANDO_B);
}
}
}