Diseñar mejor código Arduino

Hola a todos y a todas:

Uso Arduino UNO r3. Tengo hecho una aplicación que puede enviar por USB, en realidad por puerto serie para apagar y encender un Led.

En el código de Arduino que es este.

char caracter;
String comando;

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.
  }

  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 = "";
}

Quiero diseñar de alguna manera la interfaz que al ejecutarla de nuevo, le envíe un comando a Arduino que le devuelva los tados de información como tienen los estados de los Led la última vez.

Por ejemplo:
Si tengo el Led 8 encendido y el Led 13 apagado, cierro el programa lo vuelvo abrir, ya no se que estados están los Led indicado en la interfaz. Así que…

Quiero poner un botón que diga INFO, lo envíe a Arduino y le llegue a la interfaz todos los estados de los Led atualmente, que son apagados o encendidos. Hay que programarlo desde Arduino. Por lo que veo, hay que guardar en cada Led una variable que diga cuando está en ese momento encendido o apagado, para luego enviar todas esas variables de estado de cada Led a la interfaz.

¿Captan la idea?

Si no entiendes lo que quiero decir, me explicaré mejor.

Tengo tutoriales a PDF y XPS aún sin acabar algunas cosas. Por ahora tengo terminado Visual C#, VB. net, C++ y algo de Java. Si los quiere ya como está, me lo dices y lo paso por e-mail.

Saludos.

Lo que se me ocurre es que al iniciar el software, envíes un caracter o frase para que arduino devuelva los valores con los estados de cada Led, por ejemplo

Desde el software envías "estado"

if (comando.equals("estado") == true){
   // aqui compruebas el estado de cada led y luego devuelves el valor con serial.write
   Serial.Write("1:ON");
   Serial.Write("2:OFF");
   Serial.Write("3:OFF");
}

luego en el software solo quedaría interpretar la cadena "1:ON"
obviamente habría que enviarlo a la conexión serial que corresponda.

Me parece que es eso lo que quieres, verdad?

Buenas:

Así es. Algo así quiero. Arduino debe de alguna forma guardar en cada variable para cada Led para que lo pueda enviar al PC y ahí lo interpreta.

Ahora. ¿Cómo hay que hacerlo en Arduino?

Es decir, recopilar los estados de los Led estén encendidos y apagados para que la interfaz desde el PC envíe "estado" y lo devuelta al PC.

char caracter;
String comando;

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.
  }

  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.");
  }

// Si en la Interfaz recibe el comando "estado".
if (comando.equals("estado") == true){
   // aqui compruebas el estado de cada led y luego devuelves el valor con serial.write
   Serial.Write("1:ON");
   Serial.Write("2:OFF");
   Serial.Write("3:OFF");
}
  // Limpiamos la cadena para volver a recibir el siguiente comando.
  comando = "";
}

Necesito ideas para programarlo como quiero.

Saludos.

El código sería algo como eso, ahora solo quedaría leerlo desde el software e interpretarlo

char caracter;
String comando;

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); 
  	int r2 = digitalRead(13);

  	Serial.write("R1:" + r1); // envía estado de relé 8
  	Serial.write("R2:" + r2); // envía estado de relé 13
  }

  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 = "";
}

Hola:

Puse esto en Visual C#.

            switch (Recibidos)
            {
                case "R1:8":
                    richTextBox_Mensajes.Text = Recibidos;
                    Recibidos = "";
                    break;
            }

No se por ahora como interpretarlo.

¿Qué dato es este en realidad?
int r1 = digitalRead(8);
int r2 = digitalRead(13);

Debería ser un string todo junto.

"R1:8"?????????

Saludos.

Noo. No puedes enviar
"R1:8"
Debes enviar el estado,
"R1:1" o "R1:0"

@gepd te lo puso bien clarito. Lees los valores con digitalRead y luego envias

Serial.write("R1:" + r1); // envía estado de relé 8
Serial.write("R2:" + r2); // envía estado de relé 13

Si quieres puedes modificar esa linea ("R1:" + r1) para que envíe ON u OFF de este modo

Serial.write("R1:" + r1?"ON":"OFF");

NOTA : por favor no uses signos de pregunta seguidos porque aparecen como emoticons y no se entiende que quieres decir.

Saludos Surbyte probe la linea

Serial.write("R1:" + r1?"ON":"OFF");

y no me escribio R1:, use esta y si salio.

	Serial.print("R1:"); Serial.write(lectura?"ON":"OFF");

Como te indican surbyte y max, puedes modificar el código para que en envíe "on" u "off"
como está en este momento envía 0 cuando está apagado y 1 cuando está encendido, por lo que el código de C# sería así:

switch (Recibidos)
{
	case "R1:0": // cuando está apagado
		richTextBox_Mensajes.Text = Recibidos;
		Recibidos = "";
		break;
	case "R1:1": // cuando está encendido
		richTextBox_Mensajes.Text = Recibidos;
		Recibidos = "";
		break;
	case "R2:0": // cuando está apagado
		richTextBox_Mensajes.Text = Recibidos;
		Recibidos = "";
		break;
	case "R2:1": // cuando está encendido
		richTextBox_Mensajes.Text = Recibidos;
		Recibidos = "";
		break;

}

Evidentemente no lo tomó, pensé que lo haría.
Yo modifiqué el programa y lo compilé pero no vi el resultado que si vió Max.

Buena corrección.

Hola.

R1 no me lo escribe. me pasó lo mismo a max_saeta. Si pulso varias veces "Estados", se me queda al lado en vez de hacer un Enter como dice aquí.

He puesto este código.

  // Verifica si requieren de estados de los relés.
  if (comando.equals("Estados") == true)
  {
    int r1 = digitalRead(8);
    int r2 = digitalRead(13);

    Serial.write("R1:");
    Serial.write(r1 ? "ON" : "OFF");
    Serial.write(LF); // Salto de línea.
    
    Serial.write("R2:");
    Serial.write(r2 ? "ON" : "OFF");
    Serial.write(LF); // Salto de línea.
  }

No olvidar poner esta variable arriba.

int LF = 10; // Salto de línea.

Aquí hay ejemplos. No olvidar que para puerto serie no se le pone print sino write. Por eso no detectaba el R1 ni R2.

El código de arriba funciona al contrario de los resusltados, es decir, que si quiero 1, me aparece 0 y viceversa.

Así que le he puesto abajo el ! delante de los r1 y r2 a la hora de enviar datos.

  // Verifica si requieren de estados de los relés.
  if (comando.equals("Estados") == true)
  {
    int r1 = digitalRead(8);
    int r2 = digitalRead(13);

    Serial.write("R1:");
    Serial.write(!r1 ? "ON" : "OFF"); // He puesto el ! para invertir los datos.
    Serial.write(LF); // Salto de línea.
    
    Serial.write("R2:");
    Serial.write(!r2 ? "ON" : "OFF"); // He puesto el ! para invertir los datos.
    Serial.write(LF); // Salto de línea.
  }

No digo lo que hice es la mejor forma de programarlo, seguro que se puede hacer mejor.

Por ejemplo, ya que tengo intención de programarlo para 8 relé, pues...

Los datos de estado debería ser algo así:

R1 R2 R3 R4 R5 R6 R7 R8

ON OFF ON OFF OFF OFF OFF ON

Ya lo haré más adelante cuando tenga que pulir todo.

El código de Arduino completo lo dejo aquí, seguro que se puede mejorar.

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);
    int r2 = digitalRead(13);

    Serial.write("R1:");
    Serial.write(!r1 ? "ON" : "OFF");
    Serial.write(LF); // Salto de línea.
    
    Serial.write("R2:");
    Serial.write(!r2 ? "ON" : "OFF");
    Serial.write(LF); // Salto de línea.
  }

  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 = "";
}

Muchas gracias a todos.

Lo importante que tomaste la idea y la arreglaste.
Buen trabajo Metaconta.

Que bueno que te resultó, como sugerencia, creo que sería mejor, en términos de usabilidad, que los botones se modifiquen según el estado que tengan, por ejemplo:

case "R1:0": // cuando está apagado
  // cambio estado del botón a apagado
  break;
case "R1:1": // cuando está encendido
  // cambio el estado del botón a encendido
  break;

para eso tendrías que modificar la interfaz gráfica y dejar solo un botón, modificar sus valores según el estado corresponda, además de agregar una función que se ejecute cada vez que el programa inicia para saber el estado en el que se encuentra.

Pero es solo una sugerencia, de seguro ya la tienes en mente.

Saludos!

Buenas:

Antes lo hacía así en la época del Visual Studio 2008. Luego decidó hacerlo como ahora porque hace años, comunicaba por Internet un PIC, que controlaba puerto serie y MySQL incluido con Visual C#.

Si hago lo que dices, a veces no funciona bien los datos que viaja por la red, y es más majadero que asegurarse como tiene el estado realmente, ya que también tarde en recibir desde aquí a otros países. He hecho la prueba y te aseguro que como lo tengo, es más eficiente, si dudas o no te hace caso, le vuelves a pulsar el mismo botón y no cambios de estado.

Aquí hhice uno de la época con ON OFF independiente. Es programa copleto y funcional.

Muchas gracias a todos.

PD: No descarto esa posibilidad en mis futuros tutoriales.

Código completo.

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);
    int r2 = digitalRead(13);

    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 = "";
}

Algo que se me escapó y me falta por completar, es que Arduino UNO al apagarse y encenderlo otra vez, no tiene la memoria guardada, así que aprovechar la EEPROM interna para conservar los datos a la hora de iniciarse de nuevo, acto seguido, entrega los valores a la Interfaz.

Parece ser en empezar a pensar como diseñar ahora el programa, quizás haya que cambiar muchas cosas.

1) Desde que haya un cambio de estado, guarda automáticamente a Arduino UNO la EEPROM. Modo escritura.
2) Desde que se inicia o reinicie Arduino UNO, automáticamente se le entrega todos sus estados a la Interfaz de Visual C#. Modo lectura.
3) ¿Es necesario por algún motivo el borrado de la EEPROM con un botón desde la interfaz?

(Se que es mejor usar una EEPROM externa como el 24LCxx de I2C, opción que haré muschísimo más adelante)

Cualquier consejo es bienvenido.

Saludos.

Hola:

Hay algo que no funciona y no se el motivo.

Tengo este código en Visual C# 2013 y no me cambia el color de fondo de un label del formulario cuando recibe una orden desde el puerto serie.

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);
        }
    }
}

Usando el mismo código con un botón del formulario si funciona.

Este es el código de Arduino es el mismo.

 // 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);
  }

¿Alguna solución del problema?
Almenos saber el motivo.

Aunque eso no tiene nada que ver con Arduino, te responderé.
No estoy seguro si es la solución, pero sé que el problema es por la forma que llamas a la función dentro de otra que es privada. Lo que tienes que hacer es primero instanciarla y luego llamarla así:

// Llama a los Estados de Arduino.
        private void Estados()
        {
            LabelColor = new Form_Principal();
            switch (Recibidos)
            {
                case "R1:0": // Cuando está apagado.
                    richTextBox_Mensajes.Text = Recibidos;
                    LabelColor.Color_Label_8_DarkRed();
                    Recibidos = "";
                    break;
                case "R1:1": // Cuando está encendido.
                    richTextBox_Mensajes.Text = Recibidos;
                    LabelColor.Color_Label_8_Red();
                    Recibidos = "";
                    break;
                case "R2:0": // Cuando está apagado.
                    richTextBox_Mensajes.Text = Recibidos;
                    LabelColor.Color_Label_13_DarkRed();
                    Recibidos = "";
                    break;
                case "R2:1": // Cuando está encendido.
                    richTextBox_Mensajes.Text = Recibidos;
                    LabelColor.Color_Label_13_Red();
                    Recibidos = "";
                    break;
            }
        }

si no te resulta, para descartar problemas, intenta cambiando el color directamente:

// Llama a los Estados de Arduino.
        private void Estados()
        {
            LabelColor = new Form_Principal();
            switch (Recibidos)
            {
                case "R1:0": // Cuando está apagado.
                    richTextBox_Mensajes.Text = Recibidos;
                    label_Led_8.BackColor = Color.DarkRed;
                    Recibidos = "";
                    break;
                case "R1:1": // Cuando está encendido.
                    richTextBox_Mensajes.Text = Recibidos;
                    label_Led_8.BackColor = Color.Red;
                    Recibidos = "";
                    break;
                case "R2:0": // Cuando está apagado.
                    richTextBox_Mensajes.Text = Recibidos;
                    label_Led_13.BackColor = Color.Red;
                    Recibidos = "";
                    break;
                case "R2:1": // Cuando está encendido.
                    richTextBox_Mensajes.Text = Recibidos;
                    label_Led_13.BackColor = Color.DarkRed;
                    Recibidos = "";
                    break;
            }
        }

Hola:

Primero lo he hecho directamente como hiciste y no funciona.

Una cosa de los más curioso que he visto y todavía no salgo de mi asombro.

He puesto todo el código del Switch (Recibidos) en modo comentario y me llega todos los mensajes.

Mi pregunta es:

¿Hace falta el código Switch realmente?

Sin él funciona igual.

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);
        }
    }
}

Hola:

He hecho este código de Switch con default incluido y siempre se ejecuta.

        // Llama a los Estados de Arduino.
        public void Estados()
        {
            label_Led_8.Text = "Led 8";

            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;
                default:
                    label_Led_8.Text = "Error de algo.";
                    break;
            }
        }

Deduzco que este código de Arduino no funciona como debería.

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 = "";
}

Concretamente esta parte del código no anda bien.

  // 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);
  }

Así que ningún comando del switch es recibido, por eso se pasa a default. Por lo que veo, hay que corregir, encontrar, localizar el mejor método del código de Arduino.

¿Hay alguna solución?

Saludos.

PD: Mira que me he pegado horas y horas solo por deducir que es el código de Arduino, ya que en C# a pesar sigo pescando...

Supongo que debe ser porque estás enviando la información de una manera errada.

R1      R2
--------------
ON     OFF

Así es como se ve tu variable Recibidos en C#, o por lo menos así es como la formateaste en Arduino.
Pero luego el swich está esperando R1:0, R1:1, R2:0, R2:1, uno cada vez, por lo tanto tienes que eliminar todo lo que no corresponde y enviar los datos limpiamente.

  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("R1:");
    Serial.write(!r1 ? "ON " : "OFF"); // He puesto el ! para invertir los datos.
    Serial.write(" R2:");
    Serial.write(!r2 ? "   ON" : "   OFF"); // He puesto el ! para invertir los datos.
  }

he dejado un espacio en el segundo parámetro para que luego puedas dividirlo en C#
los datos recibidos se ven así: R1:ON R2:OFF (según corresponda). por lo tanto en tu programa debes separarlos y luego comprarlo, para que primero sea R1:ON-OFF y luego compare R2:ON-OFF

Además tu switch espera que llegue un 0 o 1 pero tu le envías on y off por lo tanto debería ser:

 // Llama a los Estados de Arduino.
        public void Estados()
        {
            label_Led_8.Text = "Led 8";

            switch (Recibidos)
            {
                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;
            }
        }

Usa Split(' '); para dividir la cadena en C#

el switch debería quedar algo así:
(no estoy del todo seguro si está bien realizado el foreach, pero esa es la diea principal)

// Llama a los Estados de Arduino.
public void Estados()
{
    label_Led_8.Text = "Led 8";

    Recibidos.split(' ');

    foreach (string comparar in Recibidos)
    {
        switch (comprar)
        {
            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;
            default:
                label_Led_8.Text = "Error de algo.";
                break;
        }
    }
}

Y todo lo adicional que quieres que se muestre en el textbox debes hacerlo desde c# no desde Arduino

Hola:

Se me pasó por alto lo del R1:0 que debe ser R1:OFF. Error grave de despiste.

He probado el código y en el foreach da este error.

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

He intentado hacer algo con este convertidor de tipos, pero no encuentro solución.

Saludos.