none
No me cambia el color de fondo de un label. RRS feed

  • Pregunta

  • Hola:

    He hecho este programa de ejemplo. Si pulso uno de los botones ON o OFF se me cambia el color de fondo del label. Rojo chillón encendido y rojo oscuro apagado.

    Cuando me llega una orden por puerto serie, ya que usa las mismas órdenes de cambiar de color el lable, no hace nada. La órden me llega al pulsar el botón "Estado".

    ¿Por qué?

    ¿Cómo soluciono este problema?

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    using System.IO.Ports; // No olvidar.
    
    namespace InterDuinoCS
    {
        public partial class Form_Principal : Form
        {
            // Utilizremos un string como buffer de recepción.
            string Recibidos;
    
            public Form_Principal()
            {
                InitializeComponent();
    
                // Abrir puerto mientras se ejecute la aplicación.
                if(!serialPort1.IsOpen)
                    {
                        try
                    {
                        serialPort1.Open();
                    }
                        catch (System.Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                        // Ejecutar la función Recepcion por disparo del Evento 'DataReived'.
                        serialPort1.DataReceived += new SerialDataReceivedEventHandler(Recepcion);
                    }
            }
    
            // Al recibir datos.
            private void Recepcion(object sender, SerialDataReceivedEventArgs e)
            {
                // Acumula los caracteres recibidos a nuestro 'buffer' (string).
                Recibidos += serialPort1.ReadExisting();
    
                // Invocar o llamar al proceso de tramas.
                Invoke(new EventHandler(Actualizar));
            }
    
            // Procesar los datos recibidos en el buffer y extraer tramas completas.
            private void Actualizar(object sender, EventArgs e)
            {
                // Asignar el valor de la trama al richTextBox.
                richTextBox_Mensajes.Text = Recibidos;
    
                // Selecciona la posición final para leer los mensajes entrantes.
                richTextBox_Mensajes.SelectionStart = richTextBox_Mensajes.Text.Length;
    
                // Mantiene el scroll en la entrada de cada mensaje.
                richTextBox_Mensajes.ScrollToCaret();
    
                // Método "estado" de los Led o relés desde Arduino.
                Estados();
            }
    
            // Llama a los Estados de Arduino.
            private void Estados()
            {
                switch (Recibidos)
                {
                    case "R1:0": // Cuando está apagado.
                        richTextBox_Mensajes.Text = Recibidos;
                        Color_Label_8_DarkRed();
                        Recibidos = "";
                        break;
                    case "R1:1": // Cuando está encendido.
                        richTextBox_Mensajes.Text = Recibidos;
                        Color_Label_8_Red();
                        Recibidos = "";
                        break;
                    case "R2:0": // Cuando está apagado.
                        richTextBox_Mensajes.Text = Recibidos;
                        Color_Label_13_DarkRed();
                        Recibidos = "";
                        break;
                    case "R2:1": // Cuando está encendido.
                        richTextBox_Mensajes.Text = Recibidos;
                        Color_Label_13_Red();
                        Recibidos = "";
                        break;
                }
            }
    
            private void Color_Label_8_Red()
            {
                label_Led_8.BackColor = Color.Red;
            }
    
            private void Color_Label_8_DarkRed()
            {
                label_Led_8.BackColor = Color.DarkRed;
            }
    
            private void Color_Label_13_Red()
            {
                label_Led_13.BackColor = Color.Red;
            }
    
            private void Color_Label_13_DarkRed()
            {
                label_Led_13.BackColor = Color.DarkRed;
            }
    
            private void button_Led_ON_8_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Led_8_ON");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
                Color_Label_8_Red();
            }
    
            private void button_Led_OFF_8_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Led_8_OFF");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
                Color_Label_8_DarkRed();
            }
    
            private void button_Led_ON_13_Click(object sender, EventArgs e)
            {
                // Enviar tramas de bytes.
                byte[] miBuffer = new byte[9]; // Led_13_ON son 9 byte máximo.
                miBuffer[0] = 0x4C; // ASCII letra "L".
                miBuffer[1] = 0x65; // ASCII letra "e".
                miBuffer[2] = 0x64; // ASCII letra "d".
                miBuffer[3] = 0x5F; // ASCII letra "_".
                miBuffer[4] = 0x31; // ASCII letra "1".
                miBuffer[5] = 0x33; // ASCII letra "3".
                miBuffer[6] = 0x5F; // ASCII letra "_".
                miBuffer[7] = 0x4F; // ASCII letra "O".
                miBuffer[8] = 0x4E; // ASCII letra "N".
                serialPort1.Write(miBuffer, 0, miBuffer.Length); // Envia las tramas de bytes.
                Color_Label_13_Red();
            }
    
            private void button_Led_OFF_13_Click(object sender, EventArgs e)
            {
                // Enviar tramas de bytes.
                byte[] miBuffer = new byte[10]; // Led_13_ON son 10 byte máximo.
                miBuffer[0] = 0x4C; // ASCII letra "L".
                miBuffer[1] = 0x65; // ASCII letra "e".
                miBuffer[2] = 0x64; // ASCII letra "d".
                miBuffer[3] = 0x5F; // ASCII letra "_".
                miBuffer[4] = 0x31; // ASCII letra "1".
                miBuffer[5] = 0x33; // ASCII letra "3".
                miBuffer[6] = 0x5F; // ASCII letra "_".
                miBuffer[7] = 0x4F; // ASCII letra "O".
                miBuffer[8] = 0x46; // ASCII letra "F".
                miBuffer[9] = 0x46; // ASCII letra "F".
                serialPort1.Write(miBuffer, 0, miBuffer.Length); // Envia las tramas de bytes.
                Color_Label_13_DarkRed();
            }
    
            // Si cierras el programa.
            private void Form_Principal_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (serialPort1.IsOpen) // ¿El puerto está abiero?
                {
                    serialPort1.Close(); // Cierra el puerto serie.
                }
            }
    
            private void button_Estado_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Estados");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Info");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
            }
        }
    }

    Un cordial saludo.


    http://electronica-pic.blogspot.com


    • Editado Metaconta miércoles, 11 de marzo de 2015 3:48
    miércoles, 11 de marzo de 2015 3:46

Respuestas

  • Lo más probable es que no esté funcionando porque la variable Recibidos no contiene EXACTAMENTE ninguno de los valores que tienes en los case del método Estados. Lo mejor para localizar el fallo es poner un punto de ruptura y seguir la ejecución paso a paso con el debugger, viendo qué líneas se ejecutan y examinando los valores de las variables en cada paso.
    • Marcado como respuesta Metaconta domingo, 5 de abril de 2015 8:40
    miércoles, 11 de marzo de 2015 6:28
  • Error    1    No se puede convertir el tipo 'char' en 'string'    C:\Users\Meta\Documents\Visual Studio 2013\Projects\InterDuinoCS\InterDuinoCS\Form1.cs    74    13    InterDuinoCS
    [...]

    foreach (string comparar in Recibidos) [...]

    No, eso no puede estar bien. Recibidos ya es un string. No puedes poner "foreach string in string". El enumerador del string lo que devuelve es un char, y al intentar convertir ese char en el string comparar, lógicamente da un error. No sé qué es lo que estás intentando conseguir, pero ese bucle no tiene ningún sentido.
    • Marcado como respuesta Metaconta domingo, 5 de abril de 2015 8:40
    miércoles, 11 de marzo de 2015 14:49
  • En Recibidos viaja al entrar al puerto serie esto:
    "\n\n\n\nR1     R2     \n----------------\nOFF   OFF"
    [...]
    quiero que se ponga en rojo el fondo del label
    [...]
    parece ser que es muy complicado de programarlo o simplemente no se puede. Espero que se pueda.

    Sí se puede... pero es más complejo de programar de lo que piensas. No se puede conseguir con un simple switch...case. Es necesario escribir código que "analice" la cadena Recibidos y separe los fragmentos ON y OFF que se emparejan con R1 y R2. Si se sabe que el formato es con seguridad siempre el mismo, podrías hacer un Split() de la cadena, quedarte con las dos últimas entradas, ver si respectivamente contienen las cadenas ON y OFF, y en consecuencia cambiar el color del label. Se puede hacer, pero llevará algo de trabajo, no es llegar y escribir dos líneas de código y ya está.

    Más o menos quedaría algo parecido a lo siguiente, pero ten en cuenta que no lo he probado y posiblemente tenga algunos fallos. No te limites a copiar a ciegas el ejemplo que te pongo debajo y luego decir que "no funciona". Asegúrate de que entiendes cómo se supone que debe funcionar y adáptalo debidamente para que opere correctamente con tus datos.

            private void Estados()
            {
                richTextBox_Mensajes.Text = Recibidos;
                string[] partes=Recibidos.Split(new char[]{' ','\n'}, StringSplitOptions.RemoveEmptyEntries)
                Recibidos = "";
                string onOffR1 = partes[partes.Length-2];
                string onOffR2 = partes[partes.Length-1];
                if (onOffR1.IndexOf("ON")>=0)
                {
                    Color_Label_8_Red();
                }
                else
                {
                    Color_Label_8_DarkRed();
                }
                if (onOffR2.IndexOf("ON")>=0)
                {
                    Color_Label_13_Red();
                }
                else
                {
                    Color_Label_13_DarkRed();
                }
            }




    jueves, 12 de marzo de 2015 7:57
  • El error me sigue dando la tabarra. [Indice fuera de los limites]

    Casi seguro que el error se produce cuando accedes al array partes. Por este motivo, cuando yo te puse el ejeplo de código, te decía que ese código funcionaría si el formato del mensaje era siempre fijo y tenía exactamente el formato que indicaste, ya que el ejemplo trocea la cadena Recibidos y se queda siempre con las dos últimas partes después de haberla cortado por los espacios en blanco. Si llega una cadena con menos de dos partes, al tratar de acceder a las dos últimas partes se produce el error de "índice fuera de límites". Esto requiere una lógica un poco más sofisticada, que examine con más detalle el contenido de la cadena y opere en consecuencia. La forma más fácil de evitar el error es poner "if (partes.Length>2) ...", pero evidentemente en ese caso el programa no hará nada si en Recibidos te llega un texto que no tenga esas dos partes.
    • Marcado como respuesta Metaconta domingo, 5 de abril de 2015 8:40
    viernes, 13 de marzo de 2015 6:12
  • Sí, el código tiene pinta de estar escrito correctamente. Si da errores de índice fuera de rango, parece más probable que sea un problema de la variable Recibidos, que debe traer menos de 8 partes y por eso falla el acceso a las últimas 8 partes de la variable. Ejecútalo con el debugger, examina la variable, y examina la matriz partes después de realizar el Split. A la vista de lo que observes, deberías hacerte una buena idea de por qué no está funcionando.
    • Marcado como respuesta Metaconta domingo, 5 de abril de 2015 8:40
    viernes, 13 de marzo de 2015 16:16

Todas las respuestas

  • Lo más probable es que no esté funcionando porque la variable Recibidos no contiene EXACTAMENTE ninguno de los valores que tienes en los case del método Estados. Lo mejor para localizar el fallo es poner un punto de ruptura y seguir la ejecución paso a paso con el debugger, viendo qué líneas se ejecutan y examinando los valores de las variables en cada paso.
    • Marcado como respuesta Metaconta domingo, 5 de abril de 2015 8:40
    miércoles, 11 de marzo de 2015 6:28
  • Hola:

    Eso parece, que no es lo mismo.

    He probado con este código también y no me funciona mucho.

    Error    1    No se puede convertir el tipo 'char' en 'string'    C:\Users\Meta\Documents\Visual Studio 2013\Projects\InterDuinoCS\InterDuinoCS\Form1.cs    74    13    InterDuinoCS

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    using System.IO.Ports; // No olvidar.
    
    namespace InterDuinoCS
    {
        public partial class Form_Principal : Form
        {
            // Utilizremos un string como buffer de recepción.
            string Recibidos;
    
            public Form_Principal()
            {
                InitializeComponent();
    
                // Abrir puerto mientras se ejecute la aplicación.
                if(!serialPort1.IsOpen)
                    {
                        try
                    {
                        serialPort1.Open();
                    }
                        catch (System.Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                        // Ejecutar la función Recepcion por disparo del Evento 'DataReived'.
                        serialPort1.DataReceived += new SerialDataReceivedEventHandler(Recepcion);
                    }
            }
    
            // Al recibir datos.
            private void Recepcion(object sender, SerialDataReceivedEventArgs e)
            {
                // Acumula los caracteres recibidos a nuestro 'buffer' (string).
                Recibidos += serialPort1.ReadExisting();
    
                // Invocar o llamar al proceso de tramas.
                Invoke(new EventHandler(Actualizar));
            }
    
            // Procesar los datos recibidos en el buffer y extraer tramas completas.
            private void Actualizar(object sender, EventArgs e)
            {
                // Asignar el valor de la trama al richTextBox.
                richTextBox_Mensajes.Text = Recibidos;
    
                // Selecciona la posición final para leer los mensajes entrantes.
                richTextBox_Mensajes.SelectionStart = richTextBox_Mensajes.Text.Length;
    
                // Mantiene el scroll en la entrada de cada mensaje.
                richTextBox_Mensajes.ScrollToCaret();
    
                // Método "estado" de los Led o relés desde Arduino.
                Estados();
            }
    
    
            // Llama a los Estados de Arduino.
            public void Estados()
            {
                label_Led_8.Text = "Led 8";
    
                Recibidos.Split(' ');
    
                foreach (string comparar in Recibidos)
                {
                    switch (comparar)
                    {
                        case "R1:OFF": // Cuando está apagado.
                            richTextBox_Mensajes.Text = Recibidos;
                            Color_Label_8_DarkRed();
                            Recibidos = "";
                            break;
                        case "R1:ON": // Cuando está encendido.
                            richTextBox_Mensajes.Text = Recibidos;
                            Color_Label_8_Red();
                            Recibidos = "";
                            break;
                        case "R2:OFF": // Cuando está apagado.
                            richTextBox_Mensajes.Text = Recibidos;
                            Color_Label_13_DarkRed();
                            Recibidos = "";
                            break;
                        case "R2:ON": // Cuando está encendido.
                            richTextBox_Mensajes.Text = Recibidos;
                            Color_Label_13_Red();
                            Recibidos = "";
                            break;
                        default:
                            label_Led_8.Text = "Error de algo.";
    
                            break;
                    }
                }
            }
    
            private void Color_Label_8_Red()
            {
                label_Led_8.BackColor = Color.Red;
            }
    
            private void Color_Label_8_DarkRed()
            {
                label_Led_8.BackColor = Color.DarkRed;
            }
    
            private void Color_Label_13_Red()
            {
                label_Led_13.BackColor = Color.Red;
            }
    
            private void Color_Label_13_DarkRed()
            {
                label_Led_13.BackColor = Color.DarkRed;
            }
    
            private void button_Led_ON_8_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Led_8_ON");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
                Color_Label_8_Red();
            }
    
            private void button_Led_OFF_8_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Led_8_OFF");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
                Color_Label_8_DarkRed();
            }
    
            private void button_Led_ON_13_Click(object sender, EventArgs e)
            {
                // Enviar tramas de bytes.
                byte[] miBuffer = new byte[9]; // Led_13_ON son 9 byte máximo.
                miBuffer[0] = 0x4C; // ASCII letra "L".
                miBuffer[1] = 0x65; // ASCII letra "e".
                miBuffer[2] = 0x64; // ASCII letra "d".
                miBuffer[3] = 0x5F; // ASCII letra "_".
                miBuffer[4] = 0x31; // ASCII letra "1".
                miBuffer[5] = 0x33; // ASCII letra "3".
                miBuffer[6] = 0x5F; // ASCII letra "_".
                miBuffer[7] = 0x4F; // ASCII letra "O".
                miBuffer[8] = 0x4E; // ASCII letra "N".
                serialPort1.Write(miBuffer, 0, miBuffer.Length); // Envia las tramas de bytes.
                Color_Label_13_Red();
            }
    
            private void button_Led_OFF_13_Click(object sender, EventArgs e)
            {
                // Enviar tramas de bytes.
                byte[] miBuffer = new byte[10]; // Led_13_ON son 10 byte máximo.
                miBuffer[0] = 0x4C; // ASCII letra "L".
                miBuffer[1] = 0x65; // ASCII letra "e".
                miBuffer[2] = 0x64; // ASCII letra "d".
                miBuffer[3] = 0x5F; // ASCII letra "_".
                miBuffer[4] = 0x31; // ASCII letra "1".
                miBuffer[5] = 0x33; // ASCII letra "3".
                miBuffer[6] = 0x5F; // ASCII letra "_".
                miBuffer[7] = 0x4F; // ASCII letra "O".
                miBuffer[8] = 0x46; // ASCII letra "F".
                miBuffer[9] = 0x46; // ASCII letra "F".
                serialPort1.Write(miBuffer, 0, miBuffer.Length); // Envia las tramas de bytes.
                Color_Label_13_DarkRed();
            }
    
            // Si cierras el programa.
            private void Form_Principal_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (serialPort1.IsOpen) // ¿El puerto está abiero?
                {
                    serialPort1.Close(); // Cierra el puerto serie.
                }
            }
    
            private void button_Estado_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Estados");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Info");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
            }
        }
    }

    Por si te interesa y por si acaso, dejo el código de Arduino.

    char caracter;
    String comando;
    int LF = 10; // Salto de línea.
    
    void setup() {
      pinMode(8, OUTPUT); // Pin 8 la configuramos como salida.
      pinMode(13, OUTPUT);
      digitalWrite(8, HIGH); // Mantener relés del pin 8 apagado.
      digitalWrite(13, HIGH); // Mantener relés del pin 13 apagado.
      Serial.begin(115200); // Baudios a 115200.
    }
    
    void loop()
    {
      /* Se lee carácter por carácter por el puerto serie, mientras, se va
      concatenando uno tras otro en una cadena. */
      while (Serial.available() > 0)
      {
        caracter = Serial.read();
        comando.concat(caracter);
        delay(10); // Este retardo muy corto es para no saturar el puerto
        // serie y que la concatenación se haga de forma ordenada.
      }
    
      // Verifica si requieren de estados de los relés.
      if (comando.equals("Estados") == true)
      {
        int r1 = digitalRead(8);  // Almacena 0 ó 1 en la variable r1.
        int r2 = digitalRead(13); // Tanto r1, r2 representa los relés.
    
        Serial.write(LF); // Salto de línea.
        Serial.write(LF);
        Serial.write(LF);
        Serial.write(LF);
        Serial.write("R1     ");
        Serial.write("R2     ");
        Serial.write(LF);
        Serial.write("----------------");
        Serial.write(LF);
        Serial.write(!r1 ? "ON " : "OFF"); // He puesto el ! para invertir los datos.
        Serial.write(!r2 ? "   ON" : "   OFF"); // He puesto el ! para invertir los datos.
        Serial.write(LF); // Salto de línea.
        Serial.write(LF);
        Serial.write(LF);
      }
    
    
      if (comando.equals("Led_8_ON") == true) // Si la cadena o comando "Led_8_ON" es verdadero.
      {
        digitalWrite(8, !HIGH); // El Led 8 se enciende.
        Serial.println("Led 8 encendido."); // Envía mensaje por puerto serie.
      }
    
      if (comando.equals("Led_8_OFF") == true) // Si el comando "Led_8_OFF" es verdadero.
      {
        digitalWrite(8, !LOW); // Se apaga el Led 8.
        Serial.println("Led 8 apagado."); // Envía mensaje por puerto serie.
      }
    
      if (comando.equals("Led_13_ON") == true)
      {
        digitalWrite(13, !HIGH);
        Serial.println("Led 13 encendido.");
      }
    
      if (comando.equals("Led_13_OFF") == true)
      {
        digitalWrite(13, !LOW);
        Serial.println("Led 13 apagado.");
      }
    
      // Limpiamos la cadena para volver a recibir el siguiente comando.
      comando = "";
    }

    Saludos.


    http://electronica-pic.blogspot.com


    • Editado Metaconta miércoles, 11 de marzo de 2015 13:45
    miércoles, 11 de marzo de 2015 13:44
  • Error    1    No se puede convertir el tipo 'char' en 'string'    C:\Users\Meta\Documents\Visual Studio 2013\Projects\InterDuinoCS\InterDuinoCS\Form1.cs    74    13    InterDuinoCS
    [...]

    foreach (string comparar in Recibidos) [...]

    No, eso no puede estar bien. Recibidos ya es un string. No puedes poner "foreach string in string". El enumerador del string lo que devuelve es un char, y al intentar convertir ese char en el string comparar, lógicamente da un error. No sé qué es lo que estás intentando conseguir, pero ese bucle no tiene ningún sentido.
    • Marcado como respuesta Metaconta domingo, 5 de abril de 2015 8:40
    miércoles, 11 de marzo de 2015 14:49
  • Hola:

    Mejor quitar el foreach entonces.Lo que quiero hacer es que me funciona lo de cambiar el color del label dentro de los case.

    Saludo.


    http://electronica-pic.blogspot.com

    miércoles, 11 de marzo de 2015 15:43
  • Lo que quiero hacer es que me funciona lo de cambiar el color del label dentro de los case.


    Pues entonces tienes que cambiar el texto que hay en cada case de forma que coincida con el texto que viene en la variable que has puesto en el switch. Por ejemplo, si en Recibidos está llegando "R1  ", pues solo te cambiará el color si uno de los case es "R1  ". No vale tener un case que sea "R1:0". Tendrás que usar el debugger para examinar qué es lo que en realidad te está llegando en Recibidos, y poner unos case que sean consecuentes con el contenido de Recibidos.
    miércoles, 11 de marzo de 2015 16:52
  • Hola:

    En Recibidos viaja al entrar al puerto serie esto:

    "\n\n\n\nR1     R2     \n----------------\nOFF   OFF"

    En el RichTextBox muestra esto, que es lo que quiero:

    A parte que quiero que se ponga en rojo el fondo del label, sin ningún problema muestre el mensaje en el RichTextBox.

    Espero que ahora se entienda lo que quiero decir. Si lo entiendes, parece ser que es muy complicado de programarlo o simplemente no se puede.

    Espero que se pueda.

    Saludos.


    http://electronica-pic.blogspot.com

    jueves, 12 de marzo de 2015 3:21
  • En Recibidos viaja al entrar al puerto serie esto:
    "\n\n\n\nR1     R2     \n----------------\nOFF   OFF"
    [...]
    quiero que se ponga en rojo el fondo del label
    [...]
    parece ser que es muy complicado de programarlo o simplemente no se puede. Espero que se pueda.

    Sí se puede... pero es más complejo de programar de lo que piensas. No se puede conseguir con un simple switch...case. Es necesario escribir código que "analice" la cadena Recibidos y separe los fragmentos ON y OFF que se emparejan con R1 y R2. Si se sabe que el formato es con seguridad siempre el mismo, podrías hacer un Split() de la cadena, quedarte con las dos últimas entradas, ver si respectivamente contienen las cadenas ON y OFF, y en consecuencia cambiar el color del label. Se puede hacer, pero llevará algo de trabajo, no es llegar y escribir dos líneas de código y ya está.

    Más o menos quedaría algo parecido a lo siguiente, pero ten en cuenta que no lo he probado y posiblemente tenga algunos fallos. No te limites a copiar a ciegas el ejemplo que te pongo debajo y luego decir que "no funciona". Asegúrate de que entiendes cómo se supone que debe funcionar y adáptalo debidamente para que opere correctamente con tus datos.

            private void Estados()
            {
                richTextBox_Mensajes.Text = Recibidos;
                string[] partes=Recibidos.Split(new char[]{' ','\n'}, StringSplitOptions.RemoveEmptyEntries)
                Recibidos = "";
                string onOffR1 = partes[partes.Length-2];
                string onOffR2 = partes[partes.Length-1];
                if (onOffR1.IndexOf("ON")>=0)
                {
                    Color_Label_8_Red();
                }
                else
                {
                    Color_Label_8_DarkRed();
                }
                if (onOffR2.IndexOf("ON")>=0)
                {
                    Color_Label_13_Red();
                }
                else
                {
                    Color_Label_13_DarkRed();
                }
            }




    jueves, 12 de marzo de 2015 7:57
  • Hola:

    Me dice mucho esto a la segunda vez que pulso Estado o los botones.

    Excepción no controlada del tipo 'System.IndexOutOfRangeException' en System.Windows.Forms.dll
    
    Información adicional: Índice fuera de los límites de la matriz.

    A veces como que se come algunos bytes y no muestra R1 R2 en el richTextBox.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    using System.IO.Ports; // No olvidar.
    
    namespace InterDuinoCS
    {
        public partial class Form_Principal : Form
        {
            // Utilizremos un string como buffer de recepción.
            string Recibidos;
    
            public Form_Principal()
            {
                InitializeComponent();
    
                // Abrir puerto mientras se ejecute la aplicación.
                if (!serialPort1.IsOpen)
                {
                    try
                    {
                        serialPort1.Open();
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                    // Ejecutar la función Recepcion por disparo del Evento 'DataReived'.
                    serialPort1.DataReceived += new SerialDataReceivedEventHandler(Recepcion);
                }
            }
    
            // Al recibir datos.
            private void Recepcion(object sender, SerialDataReceivedEventArgs e)
            {
                // Acumula los caracteres recibidos a nuestro 'buffer' (string).
                Recibidos += serialPort1.ReadExisting();
    
                // Invocar o llamar al proceso de tramas.
                Invoke(new EventHandler(Actualizar));
            }
    
            // Procesar los datos recibidos en el buffer y extraer tramas completas.
            private void Actualizar(object sender, EventArgs e)
            {
                // Asignar el valor de la trama al richTextBox.
                richTextBox_Mensajes.Text = Recibidos;
    
                // Selecciona la posición final para leer los mensajes entrantes.
                richTextBox_Mensajes.SelectionStart = richTextBox_Mensajes.Text.Length;
    
                // Mantiene el scroll en la entrada de cada mensaje.
                richTextBox_Mensajes.ScrollToCaret();
    
                // Método "estado" de los Led o relés desde Arduino.
                Estados();
            }
    
    
            // Llama a los Estados de Arduino.
                 private void Estados()
            {
                richTextBox_Mensajes.Text = Recibidos;
                string[] partes = Recibidos.Split(new char[] { ' ', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                Recibidos = "";
                string onOffR1 = partes[partes.Length-2];
                string onOffR2 = partes[partes.Length-1];
                if (onOffR1.IndexOf("ON")>=0)
                {
                    Color_Label_8_Red();
                }
                else
                {
                    Color_Label_8_DarkRed();
                }
                if (onOffR2.IndexOf("ON")>=0)
                {
                    Color_Label_13_Red();
                }
                else
                {
                    Color_Label_13_DarkRed();
                }
            }
    
            private void Color_Label_8_Red()
            {
                label_Led_8.BackColor = Color.Red;
            }
    
            private void Color_Label_8_DarkRed()
            {
                label_Led_8.BackColor = Color.DarkRed;
            }
    
            private void Color_Label_13_Red()
            {
                label_Led_13.BackColor = Color.Red;
            }
    
            private void Color_Label_13_DarkRed()
            {
                label_Led_13.BackColor = Color.DarkRed;
            }
    
            private void button_Led_ON_8_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Led_8_ON");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
                Color_Label_8_Red();
            }
    
            private void button_Led_OFF_8_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Led_8_OFF");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
                Color_Label_8_DarkRed();
            }
    
            private void button_Led_ON_13_Click(object sender, EventArgs e)
            {
                // Enviar tramas de bytes.
                byte[] miBuffer = new byte[9]; // Led_13_ON son 9 byte máximo.
                miBuffer[0] = 0x4C; // ASCII letra "L".
                miBuffer[1] = 0x65; // ASCII letra "e".
                miBuffer[2] = 0x64; // ASCII letra "d".
                miBuffer[3] = 0x5F; // ASCII letra "_".
                miBuffer[4] = 0x31; // ASCII letra "1".
                miBuffer[5] = 0x33; // ASCII letra "3".
                miBuffer[6] = 0x5F; // ASCII letra "_".
                miBuffer[7] = 0x4F; // ASCII letra "O".
                miBuffer[8] = 0x4E; // ASCII letra "N".
                serialPort1.Write(miBuffer, 0, miBuffer.Length); // Envia las tramas de bytes.
                Color_Label_13_Red();
            }
    
            private void button_Led_OFF_13_Click(object sender, EventArgs e)
            {
                // Enviar tramas de bytes.
                byte[] miBuffer = new byte[10]; // Led_13_ON son 10 byte máximo.
                miBuffer[0] = 0x4C; // ASCII letra "L".
                miBuffer[1] = 0x65; // ASCII letra "e".
                miBuffer[2] = 0x64; // ASCII letra "d".
                miBuffer[3] = 0x5F; // ASCII letra "_".
                miBuffer[4] = 0x31; // ASCII letra "1".
                miBuffer[5] = 0x33; // ASCII letra "3".
                miBuffer[6] = 0x5F; // ASCII letra "_".
                miBuffer[7] = 0x4F; // ASCII letra "O".
                miBuffer[8] = 0x46; // ASCII letra "F".
                miBuffer[9] = 0x46; // ASCII letra "F".
                serialPort1.Write(miBuffer, 0, miBuffer.Length); // Envia las tramas de bytes.
                Color_Label_13_DarkRed();
            }
    
            // Si cierras el programa.
            private void Form_Principal_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (serialPort1.IsOpen) // ¿El puerto está abiero?
                {
                    serialPort1.Close(); // Cierra el puerto serie.
                }
            }
    
            private void button_Estado_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Estados");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Info");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
            }
        }
    }


    Saludos.


    http://electronica-pic.blogspot.com


    • Editado Metaconta viernes, 13 de marzo de 2015 4:03
    viernes, 13 de marzo de 2015 3:29
  • Hola de nuevo:

    Otro error que me daba era que al pulsar un botón de los Led, se me apagaba siempre.

    Estube con el Debbuger y me fijé en su funcionamiento.

    He modificado tu ódigo sin usar los else, solo if, ahora parece ser que me funciona todo.

    Tu código mejorado o adaptado por decirlo de alguna manera. No llegar ser por tu código se me parte el alma. Muchas gracias.

            // Llama a los Estados de Arduino.
                 private void Estados()
            {
                richTextBox_Mensajes.Text = Recibidos;
                string[] partes = Recibidos.Split(new char[] { ' ', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                //Recibidos = "";
                string onOffR1 = partes[partes.Length-2];
                string onOffR2 = partes[partes.Length-1];
    
                if (onOffR1.IndexOf("ON")>=0)
                {
                    Color_Label_8_Red();
                    partes = null;
                }
    
                if (onOffR1.IndexOf("OFF") >= 0)
                {
                    Color_Label_8_DarkRed();
                    partes = null;
                }
    
                if (onOffR2.IndexOf("ON")>=0)
                {
                    Color_Label_13_Red();
                    partes = null;
                }
    
                if (onOffR2.IndexOf("OFF") >= 0)
                {
                    Color_Label_13_DarkRed();
                    partes = null;
                }
            }


    Código completo.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    using System.IO.Ports; // No olvidar.
    
    namespace InterDuinoCS
    {
        public partial class Form_Principal : Form
        {
            // Utilizremos un string como buffer de recepción.
            string Recibidos;
    
            public Form_Principal()
            {
                InitializeComponent();
    
                // Abrir puerto mientras se ejecute la aplicación.
                if (!serialPort1.IsOpen)
                {
                    try
                    {
                        serialPort1.Open();
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                    // Ejecutar la función Recepcion por disparo del Evento 'DataReived'.
                    serialPort1.DataReceived += new SerialDataReceivedEventHandler(Recepcion);
                }
            }
    
            // Al recibir datos.
            private void Recepcion(object sender, SerialDataReceivedEventArgs e)
            {
                // Acumula los caracteres recibidos a nuestro 'buffer' (string).
                Recibidos += serialPort1.ReadExisting();
    
                // Invocar o llamar al proceso de tramas.
                Invoke(new EventHandler(Actualizar));
            }
    
            // Procesar los datos recibidos en el buffer y extraer tramas completas.
            private void Actualizar(object sender, EventArgs e)
            {
                // Asignar el valor de la trama al richTextBox.
                richTextBox_Mensajes.Text = Recibidos;
    
                // Selecciona la posición final para leer los mensajes entrantes.
                richTextBox_Mensajes.SelectionStart = richTextBox_Mensajes.Text.Length;
    
                // Mantiene el scroll en la entrada de cada mensaje.
                richTextBox_Mensajes.ScrollToCaret();
    
                // Método "estado" de los Led o relés desde Arduino.
                Estados();
            }
    
    
            // Llama a los Estados de Arduino.
                 private void Estados()
            {
                richTextBox_Mensajes.Text = Recibidos;
                string[] partes = Recibidos.Split(new char[] { ' ', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                //Recibidos = "";
                string onOffR1 = partes[partes.Length-2];
                string onOffR2 = partes[partes.Length-1];
    
                if (onOffR1.IndexOf("ON")>=0)
                {
                    Color_Label_8_Red();
                    partes = null;
                }
    
                if (onOffR1.IndexOf("OFF") >= 0)
                {
                    Color_Label_8_DarkRed();
                    partes = null;
                }
    
                if (onOffR2.IndexOf("ON")>=0)
                {
                    Color_Label_13_Red();
                    partes = null;
                }
    
                if (onOffR2.IndexOf("OFF") >= 0)
                {
                    Color_Label_13_DarkRed();
                    partes = null;
                }
            }
    
            private void Color_Label_8_Red()
            {
                label_Led_8.BackColor = Color.Red;
            }
    
            private void Color_Label_8_DarkRed()
            {
                label_Led_8.BackColor = Color.DarkRed;
            }
    
            private void Color_Label_13_Red()
            {
                label_Led_13.BackColor = Color.Red;
            }
    
            private void Color_Label_13_DarkRed()
            {
                label_Led_13.BackColor = Color.DarkRed;
            }
    
            private void button_Led_ON_8_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Led_8_ON");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
                label_Led_8.BackColor = Color.Red;
            }
    
            private void button_Led_OFF_8_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Led_8_OFF");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
                label_Led_8.BackColor = Color.DarkRed;
            }
    
            private void button_Led_ON_13_Click(object sender, EventArgs e)
            {
                // Enviar tramas de bytes.
                byte[] miBuffer = new byte[9]; // Led_13_ON son 9 byte máximo.
                miBuffer[0] = 0x4C; // ASCII letra "L".
                miBuffer[1] = 0x65; // ASCII letra "e".
                miBuffer[2] = 0x64; // ASCII letra "d".
                miBuffer[3] = 0x5F; // ASCII letra "_".
                miBuffer[4] = 0x31; // ASCII letra "1".
                miBuffer[5] = 0x33; // ASCII letra "3".
                miBuffer[6] = 0x5F; // ASCII letra "_".
                miBuffer[7] = 0x4F; // ASCII letra "O".
                miBuffer[8] = 0x4E; // ASCII letra "N".
                serialPort1.Write(miBuffer, 0, miBuffer.Length); // Envia las tramas de bytes.
                label_Led_13.BackColor = Color.Red;
            }
    
            private void button_Led_OFF_13_Click(object sender, EventArgs e)
            {
                // Enviar tramas de bytes.
                byte[] miBuffer = new byte[10]; // Led_13_ON son 10 byte máximo.
                miBuffer[0] = 0x4C; // ASCII letra "L".
                miBuffer[1] = 0x65; // ASCII letra "e".
                miBuffer[2] = 0x64; // ASCII letra "d".
                miBuffer[3] = 0x5F; // ASCII letra "_".
                miBuffer[4] = 0x31; // ASCII letra "1".
                miBuffer[5] = 0x33; // ASCII letra "3".
                miBuffer[6] = 0x5F; // ASCII letra "_".
                miBuffer[7] = 0x4F; // ASCII letra "O".
                miBuffer[8] = 0x46; // ASCII letra "F".
                miBuffer[9] = 0x46; // ASCII letra "F".
                serialPort1.Write(miBuffer, 0, miBuffer.Length); // Envia las tramas de bytes.
                label_Led_13.BackColor = Color.DarkRed;
            }
    
            // Si cierras el programa.
            private void Form_Principal_FormClosing(object sender, FormClosingEventArgs e)
            {
                if (serialPort1.IsOpen) // ¿El puerto está abiero?
                {
                    serialPort1.Close(); // Cierra el puerto serie.
                }
            }
    
            private void button_Estado_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Estados");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                byte[] mBuffer = Encoding.ASCII.GetBytes("Info");
                serialPort1.Write(mBuffer, 0, mBuffer.Length);
            }
        }
    }

    Arriba todo bien , aunqu e a veces s ele va la olla con el error del anterior post.

    Justo abajo ahora recibe los 8 R como puedes ver en la captura. Este si no me cuesta lograrlo.

    El error me sigue dando la tabarra.

                // Invocar o llamar al proceso de tramas.           

    Invoke(new EventHandler(Actualizar));

    En la línea de arriba.




    http://electronica-pic.blogspot.com

    viernes, 13 de marzo de 2015 5:27
  • El error me sigue dando la tabarra. [Indice fuera de los limites]

    Casi seguro que el error se produce cuando accedes al array partes. Por este motivo, cuando yo te puse el ejeplo de código, te decía que ese código funcionaría si el formato del mensaje era siempre fijo y tenía exactamente el formato que indicaste, ya que el ejemplo trocea la cadena Recibidos y se queda siempre con las dos últimas partes después de haberla cortado por los espacios en blanco. Si llega una cadena con menos de dos partes, al tratar de acceder a las dos últimas partes se produce el error de "índice fuera de límites". Esto requiere una lógica un poco más sofisticada, que examine con más detalle el contenido de la cadena y opere en consecuencia. La forma más fácil de evitar el error es poner "if (partes.Length>2) ...", pero evidentemente en ese caso el programa no hará nada si en Recibidos te llega un texto que no tenga esas dos partes.
    • Marcado como respuesta Metaconta domingo, 5 de abril de 2015 8:40
    viernes, 13 de marzo de 2015 6:12
  • Buenas:

    Con tu código ahora mismo no me falla usando dos relés, R1 y R2.

    Puse datos de entrada desde R1 hasta R8. El código sería algo así.

          // Llama a los Estados de Arduino.
                 private void Estados()
            {
                richTextBox_Mensajes.Text = Recibidos;
                string[] partes = Recibidos.Split(new char[] { ' ', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                //Recibidos = "";
                string onOffR1 = partes[partes.Length-8];
                string onOffR2 = partes[partes.Length-7];
    
                string onOffR3 = partes[partes.Length - 6];
                string onOffR4 = partes[partes.Length - 5];
                string onOffR5 = partes[partes.Length - 4];
                string onOffR6 = partes[partes.Length - 3];
                string onOffR7 = partes[partes.Length - 2];
                string onOffR8 = partes[partes.Length - 1];
    
                if (onOffR1.IndexOf("ON")>=0)
                {
                    Color_Label_8_Red();
                    partes = null;
                }
    
                if (onOffR1.IndexOf("OFF") >= 0)
                {
                    Color_Label_8_DarkRed();
                    partes = null;
                }
    
                if (onOffR2.IndexOf("ON")>=0)
                {
                    Color_Label_13_Red();
                    partes = null;
                }
    
                if (onOffR2.IndexOf("OFF") >= 0)
                {
                    Color_Label_13_DarkRed();
                    partes = null;
                }
    
                if (onOffR3.IndexOf("ON") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR3.IndexOf("OFF") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR4.IndexOf("ON") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR4.IndexOf("OFF") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR5.IndexOf("ON") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR5.IndexOf("OFF") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR6.IndexOf("ON") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR6.IndexOf("OFF") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR7.IndexOf("ON") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR7.IndexOf("OFF") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR8.IndexOf("ON") >= 0)
                {
    
                    partes = null;
                }
    
                if (onOffR8.IndexOf("OFF") >= 0)
                {
    
                    partes = null;
                }

    Me da muchos fallos de lo mismo. A lo mejor tiene que ver con esta parte.

                string onOffR1 = partes[partes.Length-8];
                string onOffR2 = partes[partes.Length-7];
    
                string onOffR3 = partes[partes.Length - 6];
                string onOffR4 = partes[partes.Length - 5];
                string onOffR5 = partes[partes.Length - 4];
                string onOffR6 = partes[partes.Length - 3];
                string onOffR7 = partes[partes.Length - 2];
                string onOffR8 = partes[partes.Length - 1]
    No lo habré puesto correctamente.

    http://electronica-pic.blogspot.com

    viernes, 13 de marzo de 2015 6:50
  • Sí, el código tiene pinta de estar escrito correctamente. Si da errores de índice fuera de rango, parece más probable que sea un problema de la variable Recibidos, que debe traer menos de 8 partes y por eso falla el acceso a las últimas 8 partes de la variable. Ejecútalo con el debugger, examina la variable, y examina la matriz partes después de realizar el Split. A la vista de lo que observes, deberías hacerte una buena idea de por qué no está funcionando.
    • Marcado como respuesta Metaconta domingo, 5 de abril de 2015 8:40
    viernes, 13 de marzo de 2015 16:16
  • Hola:

    Parece ser que en Recibidos se llena lo que le de la gana.

    Cuando lo vuelves a ejecutar otra vez...ç

    Aparece el Recibidos muy diferente, como que no completa a la primera todo los datos completos, se queda a medias.

    Eso si, a veces lo hace bien a la primera y no da error.

    Array Split.

    https://www.youtube.com/watch?v=3MNbKlAI47o

    https://www.youtube.com/watch?v=GpY3c6_N8Ms

    https://msdn.microsoft.com/es-es/library/ms228388.aspx?f=255&MSPPError=-2147217396


    http://electronica-pic.blogspot.com




    • Editado Metaconta sábado, 14 de marzo de 2015 7:45
    viernes, 13 de marzo de 2015 18:13