Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Meta

#31
Hola:

Los comandos que tiene subcomandos como el K60:1 no hay problemas. Hay respuesta que me lelgan de error,el que no tiene error es este.

Aquí un terminal que ejecuto B y X87.

ver imagen.

Cuando hay errore sraros, suele recibir estos mensajes.
#0
#-1
#-3
#-10
Con guines en medio.

Aquí abajo activa y desactiva el zumbador del SAI cuyo comando tiene subcomando.



Cualquier comando enviado se envía fácil, aquí el comando a enviar.
Código (csharp) [Seleccionar]
       private void button_Desactivar_Click(object sender, EventArgs e)
       {
           byte[] mBuffer = Encoding.ASCII.GetBytes("K60:0\r"); // Comando K60:0 desactivar.
           serialPort1.Write(mBuffer, 0, mBuffer.Length);
       }


El problema está cuando hay que recibir respuesta de dicho comando y ya no estan fácil.

Hay que organizar todo, las respuestas. Como se dijo arriba, cada día una interpretación de cada comando que tarda uno por día porque es laaaaaarrrrrrrrrrgo y tedioso.

Aquí dejo un programa completo solo de un comando, el K60 que activa y desactiva el zumbador.

Código (csharp) [Seleccionar]
using System;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace Terminal_UPS_SAI_02
{
   public partial class Form1 : Form
   {
       // Utilizaremos un string como buffer de recepción.
       string recibidos;

       public Form1()
       {
           InitializeComponent();
       }


       private void Form1_Load(object sender, EventArgs e)
       {
           try
           {
               // Codificación.
               //serialPort1.Encoding = Encoding.GetEncoding(437);
               //serialPort1.Encoding = Encoding.GetEncoding(28591); // 28591 es lo mismo que ISO-8859-1.
               serialPort1.Encoding = Encoding.GetEncoding("ISO-8859-1");
               
               // Añado los puertos disponible en el PC con SerialPort.GetPortNames() al comboBox_Puerto.
               comboBox_Puerto.DataSource = SerialPort.GetPortNames();

               // Añade puertos disponibles físicos  y virtuales.
               serialPort1.PortName = comboBox_Puerto.Text.ToString();

               // Añadir datos recibidos en el evento.
               serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
           }

           catch (Exception error)
           {
               MessageBox.Show(error.Message, "Aviso:",
                   MessageBoxButtons.OK, MessageBoxIcon.Warning);
           }
       }

       // Detecta USB o puerto serie virtual cuando lo conecta y desconecta del cable.
       protected override void WndProc(ref Message USB)
       {
           if (USB.Msg == 0x219)
           {
               comboBox_Puerto.DataSource = SerialPort.GetPortNames();
           }

           // Detecta si hay cambios en el usb y si los hay los refleja.
           base.WndProc(ref USB);
       }

       private void button_Conectar_Click(object sender, EventArgs e)
       {
           try
           {
               serialPort1.PortName = comboBox_Puerto.Text.ToString(); // Puerto seleccionado previamente.
               serialPort1.BaudRate = Convert.ToInt32(comboBox_Baudios.Text); // Baudios.
               serialPort1.Open(); // Abrir puerto.
               comboBox_Puerto.Enabled = false;
               comboBox_Baudios.Enabled = false;
               button_Conectar.Enabled = false;
               button_Desconectar.Enabled = true;
               groupBox_Control_Zumbador.Enabled = true;
           }
           catch (Exception error)
           {
               MessageBox.Show(error.Message, "Aviso:",
               MessageBoxButtons.OK, MessageBoxIcon.Warning);
           }
       }

       private void button_Desconectar_Click(object sender, EventArgs e)
       {
           try
           {
               serialPort1.Close(); // Cerrar puerto.
               comboBox_Puerto.Enabled = true;
               comboBox_Baudios.Enabled = true;
               button_Conectar.Enabled = true;
               button_Desconectar.Enabled = false;
               groupBox_Control_Zumbador.Enabled = false;
           }

           catch (Exception error)
           {
               MessageBox.Show(error.Message, "Aviso:",
               MessageBoxButtons.OK, MessageBoxIcon.Warning);
           }
       }

       // Al cerrar el formulario, cierra el puerto si está abierto.
       private void Form1_FormClosing(object sender, FormClosingEventArgs e)
       {
           try
           {
               serialPort1.Close(); // Cerrar puerto.
           }

           catch (Exception error)
           {
               MessageBox.Show(error.Message, "Aviso:",
               MessageBoxButtons.OK, MessageBoxIcon.Warning);
           }
       }

       // Al recibir datos.
       private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
       {
           // Retardo de 500 ml.
           //Thread.Sleep(500);

           // Acumula los caracteres recibidos a nuestro 'buffer' (string).
           recibidos += serialPort1.ReadExisting();

           // Invocar o llamar al proceso de tramas.
           this.Invoke(new EventHandler(Actualizar));
       }

       // Procesar los datos recibidos en el bufer y extraer tramas completas.
       private void Actualizar(object sender, EventArgs e)
       {

           // Asignar el valor de la trama al richTextBox.
           richTextBox1.Text += recibidos;

           // Pasar a hexadecimal.
           foreach (byte b in recibidos)
           {
               // x = minúscula, X = mayúscula.
               richTextBox1.Text += b.ToString("X2");
           }

           // Nueva línea.
           richTextBox1.Text += Environment.NewLine;

           // Pasar a binario.
           foreach (string leer in recibidos.Select(c => Convert.ToString(c, 2)))
           {
               richTextBox1.Text += leer.ToString();
           }

           // Nueva línea.
           richTextBox1.Text += Environment.NewLine;
           richTextBox1.Text += Environment.NewLine;

           // Selecciona la posición final para leer los mensajes entrantes.
           richTextBox1.SelectionStart = richTextBox1.Text.Length;

           // Mantiene el scroll en la entrada de cada mensaje.
           richTextBox1.ScrollToCaret();

           // Limpiar.
           recibidos = "";
       }

       private void button_Activar_Click(object sender, EventArgs e)
       {
           byte[] mBuffer = Encoding.ASCII.GetBytes("K60:1\r"); // Comando K60:1 activar.
           serialPort1.Write(mBuffer, 0, mBuffer.Length);
       }

       private void button_Desactivar_Click(object sender, EventArgs e)
       {
           byte[] mBuffer = Encoding.ASCII.GetBytes("K60:0\r"); // Comando K60:0 desactivar.
           serialPort1.Write(mBuffer, 0, mBuffer.Length);
       }

       private void button_Mute_temporal_Click(object sender, EventArgs e)
       {
           byte[] mBuffer = Encoding.ASCII.GetBytes("K60:2\r"); // Comando K60:2 Mute temporal.
           serialPort1.Write(mBuffer, 0, mBuffer.Length);
       }

       private void button_Limpiar_Click(object sender, EventArgs e)
       {
           // Limpiar.
           richTextBox1.Clear();
       }

       #region DTR y RTS.
       private void checkBox_DTR_CheckedChanged(object sender, EventArgs e)
       {
           // ¿Marcado en true?
           if (checkBox_DTR.Checked == true)
           {
               // Sí.
               serialPort1.DtrEnable = true;
               checkBox_DTR.Checked = true;
           }

           // No. Entonces...
           else
           {
               serialPort1.DtrEnable = false;
               checkBox_DTR.Checked = false;
           }
       }

       private void checkBox_RTS_CheckedChanged(object sender, EventArgs e)
       {
           // ¿Marcado en true?
           if (checkBox_RTS.Checked == true)
           {
               // Sí.
               serialPort1.RtsEnable = true;
               checkBox_RTS.Checked = true;
           }

           // No. Entonces...
           else
           {
               serialPort1.RtsEnable = false;
               checkBox_RTS.Checked = false;
           }
       }
       #endregion
   }
}


Otra cosa que no se si hay que usar el codificador Encoder que usé, por ejemplo este.
Código (csharp) [Seleccionar]
Encoding.GetEncoding("ISO-8859-1");

Y no se si realmente usar DTR como indica en el manual.


A ver si me responde que sistema de codificación usar realmente para que cuando me devuelva ASCII sea el que realmente es.

Estaba pensando en hacer un programa padre que cada comando tiene su propia interfaz hijo, así lo interpreta la respuesta recibida por cada interfaz. Suena chapuza pero pinta que funciona.

Interpretar el mismo interfaz diferentes respuestas ya es otro cantar.

Lo buenoq eu tiene al recibir respueta, es que empieza por # y termina en <cr> y ya se puede dibidir cadenas para analizarlas.

Sigo investigando y interpretando tus consejos.

Gaacias.
#32
Aunque no lo parezca, sigo comiéndome las neuronas sobre código a a enviar y cuando recibos los comandos.

Ya daré con el tiempo códigos de ejemplos.
#33
Funciona.
Código (csharp) [Seleccionar]
        void UnidadDisco()
        {
            // Nombre de la unidad.
            ConsigueComponentes("Win32_CDROMDrive", "Id");

            datos = datos.Trim();

            // Delimitador.
            string[] unidad = datos.Split(' ');
            comboBox_Unidad.Items.AddRange(unidad);
           

            //comboBox_Unidad.Items.AddRange(unidades.Split(':'));  //el Split se puede hacer en una sola linea.

            // Selecciona la primera unidad.
            comboBox_Unidad.SelectedIndex = 0;
        }


Me he dado cuenta que en el otro programa más grande no.

Ya no me dice si tiene disco o no.
Código (csharp) [Seleccionar]
using System;
using System.Management; // No olvidar y añadir en Dependencias, NuGet.
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace Lector_discos_Net_5_01_cs
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Variable.
        string datos = "";

        [DllImport("winmm.dll")]
        public static extern Int32 mciSendString(string lpstrCommand,
            StringBuilder lpstrReturnString,
            int uReturnLength,
            IntPtr hwndCallback);

        StringBuilder rt = new StringBuilder(127);

        private void button_Abrir_Click(object sender, EventArgs e)
        {
            label_Mensaje.Text = "Abriendo...";
            Application.DoEvents();
            mciSendString("set CDAudio!" + comboBox_Unidad.Text + " door open", rt, 127, IntPtr.Zero);

            /*
               Si quieres por ejemplo elegir la unidad que quieras, en este caso la H, se le asigana !H
               como indica abajo. En vez de CDAudio, CDAudio!H.
               mciSendString("set CDAudio!H door open", rt, 127, IntPtr.Zero);
            */

            label_Mensaje.Text = "Abierto.";
            discoSiNo();
        }

        private void button_Cerrar_Click(object sender, EventArgs e)
        {
            label_Mensaje.Text = "Cerrando...";
            Application.DoEvents();
            mciSendString("set CDAudio!" + comboBox_Unidad.Text + " door closed", rt, 127, IntPtr.Zero);
            label_Mensaje.Text = "Cerrado.";
            label_Mensaje_disco.Text = "Disco en el lector: Leyendo...";
            discoSiNo();
        }

        // Lectura de dispositivos.
        void ConsigueComponentes(string hwclass, string syntax)
        {
            ManagementObjectSearcher mos = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + hwclass);
            foreach (ManagementObject mj in mos.Get())
            {
                if (Convert.ToString(mj[syntax]) != "")
                {
                    //datos = Convert.ToString(mj[syntax]);
                    datos += Convert.ToString(mj[syntax]).ToString() + " ";
                }
            }
        }

        // Comprobar si hay disco en el lector.
        void discoSiNo()
        {
            // Disco en la unidad del lector.
            ConsigueComponentes("Win32_CDROMDrive", "MediaLoaded");

            // ¿Disco en el lector?
            if (datos == "True")
            {
                label_Mensaje_disco.Text = "Disco en el lector: Sí.";
            }

            else
            {
                label_Mensaje_disco.Text = "Disco en el lector: No.";     
            }

            // Limpiar.
            datos = "";
           

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            discoSiNo();

            // Nombre de la unidad.
            ConsigueComponentes("Win32_CDROMDrive", "Id");

            // Borra espacios en blanco.
            datos = datos.Trim();

            // Delimitador.
            string[] unidad = datos.Split(' ');
            comboBox_Unidad.Items.AddRange(unidad);


            // Selecciona la primera unidad.
            comboBox_Unidad.SelectedIndex = 0;

            // Limpiar.
            datos = "";
        }
    }
}
#34
Programación C/C++ / Re: C o C ++ ??
8 Abril 2021, 13:18 PM
Aprendiendo o familiarizándome estoy con este librito que compré. Se lee mejor en papel que por Web. ;)



Primero C y luego cosas de C++, sobre todo a la hora de mostrar textos en pantalla.
Aprende los dos. Al final opto por C++ que hace más cosas y mejor.

Com lenguaje favorito, prefiero C# y asm.

Saludos.
#35
Buenas gente:

Desde que llegue en el depurador hasta aquí indicado.

Código (csharp,8) [Seleccionar]
        void UnidadDisco()
        {
            // Nombre de la unidad.
            ConsigueComponentes("Win32_CDROMDrive", "Id");
           
            // Delimitador.
            string[] unidad = datos.Split(' ');
            comboBox_Unidad.Items.AddRange(unidad);
           

            //comboBox_Unidad.Items.AddRange(unidades.Split(':'));  //el Split se puede hacer en una sola linea.

            // Selecciona la primera unidad.
            comboBox_Unidad.SelectedIndex = 0;
        }


Se añade un espacio por la cara.


Saludos.
#36
Funciona mejor, casi perfecto.  ;-) ;-) ;-) ;-) ;-) ;-)

Ahora pone:
G:
F:
Espacio enblanco

No se que pinta en el último elemento un espacio en blanco, queda feo.

Solo hace falta corregir ese último detalle.

Lo demás, perfecto.

:silbar: :silbar: :silbar: :silbar: :silbar:
#37
Muy bueno:
;-) ;-) ;-) ;-) ;-) ;-) ;-)

Sí, es largo y tedioso.

Los comandos de error he recibido estos.
#-0
#-1
#-3
#-10

Tendría que probocar algo para que me dieran más respuestas erróneas. El fabricante no me hace caso sobre qué significa estos errores. Lo del PDF lo tengo más que leído, es más, este documento que me dieron que es del 2018, mi versión de la UPS aunque lo compré hace semanas, es la 2.020. El firmware que tiene una versión y no se si se puede actualizar.

Si te fijas bien, hay comando que no vienen como indica en el PDF.
CitarHay todos estos comandos:  "The I, O, L, B, V, T, F, H, R, C, Q, S, W, X are single uppercase

Su respuesta es esta.
Citar#I223.3O224.0L000B100V26.4F50.2H50.2R0080S,,€€,,À

Otra cosa.
La interfaz oficial es por Web.

Pruebo los comandos del en el Hyper Terminal de Windows o otro similar y me funciona. He hecho un poco mi propio programa en Windows Form y controlado el puerto serie en el cual puedo con botones apagar y encender el zumbador o pitido del SAI o UPS.

El programa que incluye es por Web local. La ruta para acceder es con un archivo que se llama agent.cmd y en su interior tiene este código.

start http://localhost:3052/local/


Ver imagen.

Lo curioso que la forma de controlar el puerto serie el programa oficial, es con un programa modo servicio, que lo puedo detener o arrancar como dice abajo.

Ver imagen.

Este detalle lo intentaré hacerlo en otro proyecto mucho más adelante. ;)
No controlar la UPS, sino otros aparatos como Arduino por puerto serie de esta manera, por vía Web.

Antes lo hacía de esta manera por capaz.
Actuadores <-----> Arduino <-----> PC <-----> Base de datos <-----> Interfaz <-----> Conexión a Internet.


  •     Un ejemplo. Uso Arduino que tiene un display LCD 20x4 en el cual me muestra en todo momento los estados de entradas y salidas. Arduino controla una habitación, ventilador, extractor de aire, ventana motorizada, deteción de gases, alarma, temperatura, humedad, detección si hay apagón de luz y incluye su UPS, etc...
        Ese Arduino lo tengo directamente conectado a su USB al PC.
        En el PC tengo una interfaz que controla el puerto serie/USB y una base de datos.
        Tengo conexión en el PC a Internet.
        La base de datos instalada tengo una buena tabla hecha sobre control de relés y estados de avisos o alarmas.
        Si cambio un valor en una base de datos, por ejemplo, un 1, se me enciende un Led, si pongo un 0, se apaga un Led.
        La interfaz detecta un cambio en la base de datos los datos, lo envía al puerto serie ese valor y le llega a Arduino.
        En la propia Interfaz de un programa de escritorio o Web, puede cambiar valores en la base de datos que también envía datos a Arduino.

Es otra historia.

Sigo interpretado tu código, ya que me ha aportado muchas ideas. Sobre todo de diferenciar códigos de respuestas según código enviado.

Ahora estoy en plan chamuzqueándome la cabeza. A ver si me sale todo esto de alguna vez por todas.

Y sí, es muyyyyyyyyyyyyyyyyyyyy, laaaaaaaaaarrrrrrrrrrrrrrrrrrrrrrrrrrgo y tedioso de la leche.  ;D

Se hará poco a poco, mientras entiendas lo básico, todo lo demás saldrá poco a poco.

Saludos.
#38
Si lo hago así:
Código (csharp) [Seleccionar]
        void UnidadDisco()
        {
            // Nombre de la unidad.
            ConsigueComponentes("Win32_CDROMDrive", "Id");
           
            // Delimitador.
            string[] unidad = datos.Split(' ');
            comboBox_Unidad.Items.AddRange(unidad);

            //comboBox_Unidad.Items.AddRange(unidades.Split(':'));  //el Split se puede hacer en una sola linea.

            // Selecciona la primera unidad.
            comboBox_Unidad.SelectedIndex = 0;
        }


Me di cuenta que en dato primero pone F:
Luego hace otra pasada en el código de abajo.
Código (csharp) [Seleccionar]
        void ConsigueComponentes(string hwclass, string syntax)
        {
            ManagementObjectSearcher mos = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + hwclass);
            foreach (ManagementObject mj in mos.Get())
            {
                if (Convert.ToString(mj[syntax]) != "")
                {
                    datos = Convert.ToString(mj[syntax]);
                }
            }
        }


Y se pone en G: borrando la F:
#39
La idea es que me detecte las unidades de disco que tengo instalada o detectada. ;)
#40
No se que pasa.
En vez de verse:

F:
G:

En el comboBox, aparece esto.


Ver imagen.

En este otro código de abajo, solo se me ve así:
G:
:

¿Dónde está la F:?  ;D

Código (csharp) [Seleccionar]
       void UnidadDisco()
       {
           // Nombre de la unidad.
           ConsigueComponentes("Win32_CDROMDrive", "Id");

           // Delimitador.
           string[] unidades = datos.Split(':');

           foreach (string unidad in unidades)
           {
               comboBox_Unidad.Items.Add(unidad + ":");
           }

           // Selecciona la primera unidad.
           comboBox_Unidad.SelectedIndex = 0;
       }


Saludos.