Modificar códigos de Arduino.

Hola:

En este código se trata entre el PC y Arduino. Los dos programas están hechos con C/C++.

Si desde el PC pulso la tecla 1, envía el comando "Luz_ON" hasta Arduino, lo detecta y responde "ON - Led encendido." por el serialport y en el LCD 16x2 muestra "Luz ON. ".

Dejo código de Arduino que he hecho. A pesar que funciona, parece que es mejor usar bien los StartsWith como indica aquí pero veo que al final termino empezar desde cero el código porque no me funciona como debe ser o da problemas.

Desde cero es aquí. Arduino en C:
C:
#include <LiquidCrystal.h>

// Inicializa la librería con sus pines indicados.
// RS, RW, Enable, D4, D5, D6, D7.
LiquidCrystal lcd(8, NULL, 9, 4, 5, 6, 7);
// LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Pin 10 para saber que es luz de fondo.
const byte LuzFondo = 10;

const byte Led = 13;              // Declaramos la variable pin del Led.
char caracter;
String comando;

void setup()
{
  pinMode(Led, OUTPUT);           // Inicializa el pin del LED como salida:
  Serial.begin(115200);           // Puerto serie 115200 baudios.
  lcd.begin(16, 2);               // Formato de pantalla.
  lcd.clear();                    // Borra la pantalla y su posición superior izquierda.
  lcd.print("    Arduino     ");
  delay(1000);
}

void loop()
{
  /*
    Voy leyendo carácter a carácter lo que se recibe por el canal serie
    (mientras llegue algún dato allí), y los voy concatenando uno tras otro
    en una cadena. En la práctica, si usamos el "Serial monitor" el bucle while
    acabará cuando pulsamos Enter. El delay es conveniente para no saturar el
    canal serie y que la concatenación se haga de forma ordenada.
  */
  while (Serial.available() > 0)
  {
    caracter = Serial.read();
    comando.concat(caracter);
    delay(10);
  }

  /*
    Una vez ya tengo la cadena "acabada", compruebo su valor y hago que
    la placa Arduino reacciones según sea este. Aquí podríamos hacer lo
    que quisiéramos: si el comando es "tal", enciende un Led, si es cual,
    mueve un motor... y así.
  */

  // Si los carácteres es recibido y verdadero.
  if (comando.equals("Luz_ON") == true)
  {
    digitalWrite(Led, HIGH); // Enciende el Led 13.
    Serial.write("ON - Led encendido.");    // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print("Luz ON.         "); // Mostrar en el LCD.
  }


  if (comando.equals("Luz_OFF") == true)
  {
    digitalWrite(Led, LOW); // Apaga el Led 13.
    Serial.write("OFF - Led apagado. ");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print("Luz OFF.        "); // Mostrar en el LCD.
  }

    if (comando.equals("Salir") == true)
  {
    digitalWrite(Led, LOW); // Apaga el Led 13.
    Serial.write("Ha salido de C++.");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print("Ha salido de C++."); // Mostrar en el LCD.
  }

  // Limpiamos la cadena para volver a recibir el siguiente comando.
  comando = "";
}

Saludos.
 
Así te va a a funcionar una de cada diez veces.

Quita el *##*!$ delay de los *##*&@!
Haz un bucle que verifique que se ha pulsado intro ASCII 13 , depende de como esté configurado a veces es 13+10
Cuando detectes el 13 entonces todo lo que has acumulado en el buffer es el comando y entonces verificas si es la cadena que buscas.
Tanto si es como si no es borras el buffer y vuelves a empezar
 
Ten cuidado en esa comparación, básicamente sí pones el nueva línea o retorno de carro va a dar falso, la idea de poner un bucle buscando un carácter también causaría problema, en este caso te sugiero que leas el stream y uses el timeOut directamente, así cuando se envia el dato el Arduino simplemente asume que ya se envió todo cuando se excede el tiempo de espera.
C++:
#include <LiquidCrystal.h>

// Inicializa la librería con sus pines indicados.
// RS, RW, Enable, D4, D5, D6, D7.
LiquidCrystal lcd(8, NULL, 9, 4, 5, 6, 7);
// LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Pin 10 para saber que es luz de fondo.
const byte LuzFondo = 10;

const byte Led = 13;              // Declaramos la variable pin del Led.
char caracter;
String comando;

void setup()
{
  pinMode(Led, OUTPUT);           // Inicializa el pin del LED como salida:
  Serial.begin(115200);           // Puerto serie 115200 baudios.
  lcd.begin(16, 2);               // Formato de pantalla.
  lcd.clear();                    // Borra la pantalla y su posición superior izquierda.
  lcd.print("    Arduino     ");
  delay(1000);
  Serial.setTimeout(5); //Tiempo maximo de espera en ms para el dato en el puerto
}

void loop()
{
  /*
    Voy leyendo carácter a carácter lo que se recibe por el canal serie
    (mientras llegue algún dato allí), y los voy concatenando uno tras otro
    en una cadena. En la práctica, si usamos el "Serial monitor" el bucle while
    acabará cuando pulsamos Enter. El delay es conveniente para no saturar el
    canal serie y que la concatenación se haga de forma ordenada.
  */
  while (Serial.available() > 0)
  {
    comando = Serial.readString(); //Lees el stream directamente, la lectura termina segun el timeOut establecido.
  }

  /*
    Una vez ya tengo la cadena "acabada", compruebo su valor y hago que
    la placa Arduino reacciones según sea este. Aquí podríamos hacer lo
    que quisiéramos: si el comando es "tal", enciende un Led, si es cual,
    mueve un motor... y así.
  */

  // Si los carácteres es recibido y verdadero.
  if (comando.equals("Luz_ON") == true)
  {
    digitalWrite(Led, HIGH); // Enciende el Led 13.
    Serial.write("ON - Led encendido.");    // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print("Luz ON.         "); // Mostrar en el LCD.
  }


  if (comando.equals("Luz_OFF") == true)
  {
    digitalWrite(Led, LOW); // Apaga el Led 13.
    Serial.write("OFF - Led apagado. ");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print("Luz OFF.        "); // Mostrar en el LCD.
  }

    if (comando.equals("Salir") == true)
  {
    digitalWrite(Led, LOW); // Apaga el Led 13.
    Serial.write("Ha salido de C++.");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print("Ha salido de C++."); // Mostrar en el LCD.
  }

  // Limpiamos la cadena para volver a recibir el siguiente comando.
  comando = "";
}
Recuerda que si pruebas con la consola de Arduino no coloques terminador de línea.
1691234251506.png
 
Eso sí usas el "terminal" del Arduino.
Su usas cualquier otro que funcione normalmente* en el que cada tecla que pulsas se envía tendrás problemas.

* Claro, depende de lo que se considere normal. Como tengo más años que matusalén para mí lo normal es que cada tecla que se pulse se envíe. Y lo "raro" y "particular" es como funciona el terminal del Arduino.

Claro, si esperas a que llegue el retorno de carro, una de dos, o lo incluyes en la comparación o se lo quitas a la cadena a comparar, o sencillamente el if que verifica que ha llegado el 13 no lo añade.

Personalmente prefiero terminal clásico con eco desactivado, si pulsas A, envía A y el equipo devuelve A para que lo veas en pantalla y de paso sabes que está funcionando todo a cada pulsación. Si no puede ser que creas que va todo bien pero no va nada o va la mitad o la tercera parte de la comunicación.
 
Última edición:
lo que te está sucediendo es que la solución que te propone el entorno de Arduinería no es el más indicado para éste tipo de problemas....

Así como lo planteas, (y todos los ejemplos de Arduino en la Red son más o menos así en su filosofía) está orientado a una programación lineal, procesando eventos que se suceden uno a continuación de otro, mediante "Polling" (entiéndase muestreo en Castellano).

Vós requerís una programación orientada a sucesos para no perder datos, y un gran porcentaje de eso lo logras, obteniendo el control total del micro y sus interrupciones, lo que se puede hacer desde C plano (y olvidarse del entorno Arduino).

Bajo el lenguaje Arduino (Processing), no vi muchos ejemplos del uso de las interrupciones de hardware del micro en la Red. Entonces no hay mucho para orientarse, menos para crear tendencias y buenos hábitos de programación.

Al menos mejora tu programa, para no perder teclasos, configura el terminal/programa que envia por puerto serie, que no espere a presionar LF/CR, si no que envie cada teclazo.
Olvidate de comandos de cadena de caracteres tipo "Luz_ON", procesa caracter a caracter, los comandos hacelos con un solo byte, (tokens), por ejemplo que sean mayores a 127, usa full transmisión de 8 bits.

Y definitivamente, OLVIDATE DE LOS DELAYS!, ya te lo dijeron, y va de nuevo!

En C plano, personalmente procesaría, caracter a caracter, con una función que se dispará con la interrupción de "buffer lleno" del puerto serie (y pongo el micro a full 20Mhz a sus 20MPS!).
Interpretando los comando que serían de solo UN BYTE, el resto de la cadena, me amaño para procesarla desde el micro (los que no son comandos)... eso haría Yo en un caso como el tuyo.
 
Gracias por las respuestas.

En este ejemplo es sacado exactamente de este libro.

Me llevo leyendo este libro. Al menos se aprende cosas, pero el autor, parece que ya no quiere sacar un libro nuevo más avanzado y orientado a protocolos de comunicaciones como, RS232, I2C, SPI, etc...

Por si les interesa, les dejo el código en C++ nativo para PC que envía los comandos y recibe desde Arduino.
C++:
#include <iostream>
#include <fstream>
#include <conio.h>      // Controla el _getch.
#include <Windows.h>    // Para mostrar texto en el título de la ventana.
#include <stdio.h>      // Cambio color de fondo y letras.
#include "SerialClass.h"

using namespace std;
//using std::cout;
//using std::cin;

// Función posición del cursor.
void gotoxy(int ancho_x, int alto_y)
{
    HANDLE hcon;
    hcon = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD dwPos{};
    dwPos.X = ancho_x;
    dwPos.Y = alto_y;
    SetConsoleCursorPosition(hcon, dwPos);
}

int main()
{

#pragma region "Configuración ventana."
    // Mostrar caracteres correctamente en pantalla y título de la ventana.
    SetConsoleOutputCP(65001);
    wchar_t titulo[128];
    MultiByteToWideChar(CP_UTF8, 0, "Led Arduino C++ nativo", -1, titulo, 128);
    SetConsoleTitleW(titulo);

    // Tamaño de la pantalla. Se cambia en los dos últimos dígitos.
    SMALL_RECT r = { 0, 0, 80, 20 }; // X = 80, Y = 20.
    SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &r);

    // Cambio color de 6 (naranja / amarillo claro), color letras 0 (negro).
    system("color 60");

    // Ocultar cursor.
    CONSOLE_CURSOR_INFO cci;
    GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
    cci.bVisible = 0; // 0 oculta. 1 muestra cursor.
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
#pragma endregion



    // Comandos para Arduino.
    char Luz_ON[] = "Luz_ON";       // Envía "Luz_ON" al puerto serie.
    char Luz_OFF[] = "Luz_OFF";
    char limpiar7[] = "       ";    // Siete espacios en blanco para limpiar un área seleccionado.
    char lectura[50] = "\0";        // Guardan datos de entrada del puerto.
    char tecla;                     // Guarda un 1, 2 o un 3 tipo entero que introduces desde la consola.

    // Puerto serie.
    Serial* Puerto = new Serial("COM6");

    gotoxy(0, 0);                   // Posición de la pantalla.
    cout << endl;                   // Retorno.
    cout << "Introduzca la opcion deseada: " << endl;
    cout << "Pulse 1 para encender el Led, 2 para apagar, 3 para limpiar pantalla." << endl << endl;

    while (Puerto->IsConnected())
    {
        tecla = _getch();     // Aquí introduces un número, el 1 o el 2.

        switch (tecla)        // Espera recibir un 1 o un 2.
        {
        case '1':
            // Encener luz.
            gotoxy(10, 5);
            cout << limpiar7;
            gotoxy(0, 5);
            cout << "Enviando: " << Luz_ON << endl;         // Muestra en pantalla textos.
            Puerto->WriteData(Luz_ON, sizeof(Luz_ON) - 1);  // Envía al puerto el texto "Luz_ON".
            gotoxy(0, 9);
            cout << "                             ";        // Borrado del mensaje si haz pulsado distinto del 1 o la tecla 2.
            break;

        case '2':
            // Apagar luz.
            gotoxy(10, 5);
            cout << limpiar7;
            gotoxy(0, 5);
            cout << "Enviando: " << Luz_OFF << endl;
            Puerto->WriteData(Luz_OFF, sizeof(Luz_OFF) - 1);
            gotoxy(0, 9);
            cout << "                             ";
            break;

        default: // Si haz pulsado otro número distinto del 1 y 2, muestra
            gotoxy(0, 9);
            cout << "Pulse las teclas el 1 o el 2.";            // este mensaje.
        }

        Sleep(500);
        int numeros = Puerto->ReadData(lectura, 49);            // Recibe datos del puerto serie.
        if (numeros > 0)
        {
            lectura[numeros + 1] = '\0';                        // Limpia de basura la variable.
            gotoxy(0, 7);
            cout << "Recibido: " << lectura << endl;            // Muestra en pantalla dato recibido.
            cout << "-----------------------------" << endl;
        }
    }
    return 0;
}

Me he dado cuenta que si pongo esta cadena largo como esto.

Enviar comando: "EstoEsUnaCadenaLuz_ONQueTienes_Aquí".

Si te fijas bien, dentro de esa cadena grande Arduino puede leer Luz_ON y enciende el Led. Así que el código de ejemplo que viene en el libro no está muy allá.

Me fijé por probar este otro código, que lea código de comiendo y el final para que Arduino y el PC lo sepa.


Tendré que modificar el código del libro o el que puse en el primer post haber que tal.

La verdad quiero ver el mejor código posible.

Saludos.
 
Más la que me gusta, ahora prefiero la más eficaz o decente. ;)

Voy hacer lo del StartsWith haber que tal sale.

Edito:

No me devuelve ningún valor, no el LCD hace nada.
Código modificado.

C:
#include <LiquidCrystal.h>

// Inicializa la librería con sus pines indicados.
// RS, RW, Enable, D4, D5, D6, D7.
LiquidCrystal lcd(8, NULL, 9, 4, 5, 6, 7);
// LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Pin 10 para saber que es luz de fondo.
const byte LuzFondo = 10;

const byte Led = 13;  // Declaramos la variable pin del Led.
char caracter;
String comando;

void setup() {
  pinMode(Led, OUTPUT);  // Inicializa el pin del LED como salida:
  Serial.begin(115200);  // Puerto serie 115200 baudios.
  lcd.begin(16, 2);      // Formato de pantalla.
  lcd.clear();           // Borra la pantalla y su posición superior izquierda.
  lcd.print("    Arduino     ");
  delay(1000);
}

void loop() {
  /*
    Voy leyendo carácter a carácter lo que se recibe por el canal serie
    (mientras llegue algún dato allí), y los voy concatenando uno tras otro
    en una cadena. En la práctica, si usamos el "Serial monitor" el bucle while
    acabará cuando pulsamos Enter. El delay es conveniente para no saturar el
    canal serie y que la concatenación se haga de forma ordenada.
  */
  while (Serial.available() > 0) {
    caracter = Serial.read();
    comando.concat(caracter);
    delay(10);
  }

  /*
    Una vez ya tengo la cadena "acabada", compruebo su valor y hago que
    la placa Arduino reacciones según sea este. Aquí podríamos hacer lo
    que quisiéramos: si el comando es "tal", enciende un Led, si es cual,
    mueve un motor... y así.
  */

  // Si los carácteres es recibido y verdadero.
  if (comando.startsWith(F("Luz_ON")) == true) {
    digitalWrite(Led, HIGH);              // Enciende el Led 13.
    Serial.write("ON - Led encendido.");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Luz ON.         "));  // Mostrar en el LCD.
    // Limpiamos la cadena para volver a recibir el siguiente comando.
    comando = "";
  }


  if (comando.startsWith(F("Luz_OFF")) == true) {
    digitalWrite(Led, LOW);               // Apaga el Led 13.
    Serial.write("OFF - Led apagado. ");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Luz OFF.        "));  // Mostrar en el LCD.
    // Limpiamos la cadena para volver a recibir el siguiente comando.
    comando = "";
  }

  if (comando.startsWith(F("Salir")) == true) {
    digitalWrite(Led, LOW);             // Apaga el Led 13.
    Serial.write("Ha salido de C++.");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Ha salido de C++."));  // Mostrar en el LCD.
    // Limpiamos la cadena para volver a recibir el siguiente comando.
    comando = "";
  }
}
 
Última edición:
Editado arriba con códigos.

Edito aquí.

Funciona.

C:
#include <LiquidCrystal.h>

// Inicializa la librería con sus pines indicados.
// RS, RW, Enable, D4, D5, D6, D7.
LiquidCrystal lcd(8, NULL, 9, 4, 5, 6, 7);
// LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Pin 10 para saber que es luz de fondo.
const byte LuzFondo = 10;

const byte Led = 13;  // Declaramos la variable pin del Led.
char caracter;
String comando;

void setup() {
  pinMode(Led, OUTPUT);  // Inicializa el pin del LED como salida:
  Serial.begin(115200);  // Puerto serie 115200 baudios.
  lcd.begin(16, 2);      // Formato de pantalla.
  lcd.clear();           // Borra la pantalla y su posición superior izquierda.
  lcd.print("    Arduino     ");
  delay(1000);
}

void loop() {
  /*
    Voy leyendo carácter a carácter lo que se recibe por el canal serie
    (mientras llegue algún dato allí), y los voy concatenando uno tras otro
    en una cadena. En la práctica, si usamos el "Serial monitor" el bucle while
    acabará cuando pulsamos Enter. El delay es conveniente para no saturar el
    canal serie y que la concatenación se haga de forma ordenada.
  */
  while (Serial.available() > 0) {
    caracter = Serial.read();
    comando.concat(caracter);
    delay(10);
  }

  /*
    Una vez ya tengo la cadena "acabada", compruebo su valor y hago que
    la placa Arduino reacciones según sea este. Aquí podríamos hacer lo
    que quisiéramos: si el comando es "tal", enciende un Led, si es cual,
    mueve un motor... y así.
  */

  // Si los carácteres es recibido y verdadero.
  if (comando.startsWith(F("Luz_ON")) == true) {
    digitalWrite(Led, HIGH);              // Enciende el Led 13.
    Serial.write("ON - Led encendido.");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Luz ON.         "));  // Mostrar en el LCD.
  }


  if (comando.startsWith(F("Luz_OFF")) == true) {
    digitalWrite(Led, LOW);               // Apaga el Led 13.
    Serial.write("OFF - Led apagado. ");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Luz OFF.        "));  // Mostrar en el LCD.
  }

  if (comando.startsWith(F("Salir")) == true) {
    digitalWrite(Led, LOW);             // Apaga el Led 13.
    Serial.write("Ha salido de C++.");  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Ha salido de C++."));  // Mostrar en el LCD.
  }
      // Limpiamos la cadena para volver a recibir el siguiente comando.
    comando = "";
}

Me falta corregir o mejorar los tiempos, es decir, como dijo el compañero arriba, no usar delay.

Lo que no entiendo el motivo de que en los Serial.write no me deja poner los F.

De:
C:
Serial.write("ON - Led encendido.");

a:
C:
Serial.write(F("ON - Led encendido."));
 
Última edición:
Dentro del "while" del serial, comprobá si hay un "\r", un "\0" o un "\n" antes de concatenarlo al "comando", para evitar problemas...
 
El código de consola para Pc de C++ nativo hecho con Visual Studio 2022 es este.
C++:
        case '1':
            // Encener luz.
            gotoxy(10, 5);
            cout << limpiar7;
            gotoxy(0, 5);
            cout << "Enviando: " << Luz_ON << endl;         // Muestra en pantalla textos.
            Puerto->WriteData(Luz_ON, sizeof(Luz_ON) - 1);  // Envía al puerto el texto "Luz_ON".
            gotoxy(0, 9);
            cout << "                             ";        // Borrado del mensaje si haz pulsado distinto del 1 o la tecla 2.
            break;

No envía nada del \r o cosas así.

Si usas otros programas que nadie sabe si envía algo al final como la \r como dices. Mejor usar en Arduino para curarte en salud una solución para evitar problemas a cada al futuro.

Por ejemplo el Trim.

Ya son dos cosas que tengo que corregir. El dealy no ponerlo y evitar el ASCII 13.
 
Lo que no entiendo el motivo de que en los Serial.write no me deja poner los F.

De:
C:
Serial.write("ON - Led encendido.");

a:
C:
Serial.write(F("ON - Led encendido."));
Probablemente error de tipo, write espera un valor uint8_t mientras que el devuelto por usar F() un array distinto como __FlashStringHelper, en lugar de write usa
C:
Serial.print(F("ON - Led encendido."));
 
Gracias mi muy distinguido amigo.

Diferencia del Print, Println y Write.

Código de Arduino supuestamente completo con su Trim() y sin delay.


C:
#include <LiquidCrystal.h>

// Inicializa la librería con sus pines indicados.
// RS, RW, Enable, D4, D5, D6, D7.
LiquidCrystal lcd(8, NULL, 9, 4, 5, 6, 7);
// LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Pin 10 para saber que es luz de fondo.
const byte LuzFondo = 10;

const byte Led = 13;  // Declaramos la variable pin del Led.
char caracter;
String comando;

void setup()
{
  pinMode(Led, OUTPUT);  // Inicializa el pin del LED como salida:
  Serial.begin(115200);  // Puerto serie 115200 baudios.
  lcd.begin(16, 2);      // Formato de pantalla.
  lcd.clear();           // Borra la pantalla y su posición superior izquierda.
  lcd.print("    Arduino     ");
  delay(1000);
  Serial.setTimeout(5);  //Tiempo maximo de espera en ms para el dato en el puerto.
}

void loop()
{
  /*
    Voy leyendo carácter a carácter lo que se recibe por el canal serie
    (mientras llegue algún dato allí), y los voy concatenando uno tras otro
    en una cadena. En la práctica, si usamos el "Serial monitor" el bucle while
    acabará cuando pulsamos Enter. El delay es conveniente para no saturar el
    canal serie y que la concatenación se haga de forma ordenada.
  */
  while (Serial.available() > 0)
  {
    comando = Serial.readString();  //Lees el stream directamente, la lectura termina segun el timeOut establecido.
    comando.trim();                 // Limpia tabulaciones, espacios en blanco, etc.
  }

  /*
    Una vez ya tengo la cadena "acabada", compruebo su valor y hago que
    la placa Arduino reacciones según sea este. Aquí podríamos hacer lo
    que quisiéramos: si el comando es "tal", enciende un Led, si es cual,
    mueve un motor... y así.
  */

  // Si los carácteres es recibido y verdadero.
  if (comando.startsWith(F("Luz_ON")) == true)
  {
    digitalWrite(Led, HIGH);              // Enciende el Led 13.
    Serial.print(F("ON - Led encendido."));  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Luz ON.         "));  // Mostrar en el LCD.
  }


  if (comando.startsWith(F("Luz_OFF")) == true)
  {
    digitalWrite(Led, LOW);               // Apaga el Led 13.
    Serial.print(F("OFF - Led apagado. "));  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Luz OFF.        "));  // Mostrar en el LCD.
  }

  if (comando.startsWith(F("Salir")) == true)
  {
    digitalWrite(Led, LOW);             // Apaga el Led 13.
    Serial.print(F("Ha salido de C++."));  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Ha salido de C++."));  // Mostrar en el LCD.
  }
  // Limpiamos la cadena para volver a recibir el siguiente comando.
  comando = "";
}

A lo mejor se me escapa algo y el código puede ser mejor.

El del libro si se entera de esto, le da algo. :ROFLMAO: :ROFLMAO: :ROFLMAO:

En cuanto a Write y Print. Print requiere más ancho de bando para enviar caracteres por el puerto serie y el Write no. En este caso uso Print por el tema de ahorra RAM.

Si al final el código está como debe ser o es más mejorable, avisen y confirmen. Gracias a tod@s.

Saludos
 
Última edición:
Eso del ancho de banda me parece una fumada total.
Si envía caracteres pues usar write igual desperdicia ancho de banda, si dijera que enviamos un byte para codificar la información es que sí se ahorra. En un sensor que puse en lugar de enviar 4 bytes para pasar el valor del ADC solo enviaba 2 bytes inclusive agregando información de paridad y orden de bit ya que solo usaba 6 bits de datos, entonces era [0{datos 6 MSB}{bit paridad}] [1{datos 6 LSB}{bit paridad}]
 
Hice un programa hace tiempo por el 2016 por ahí, aún lo conservo, donde guarda en Arduino UNO r3 una o dos imágenes pequeñas en su memoria flash, y lo puedes pasar al PC.

Si quieren lo adjunto aquí para que hagan pruebas.

Ahí si que tardaba pasar bytes, jeeje y tipo Write.

Mirando bien el código. Poner equals o startWith en esta ocasión. No parece importante. Se comporta igual.

¿No será mejor hacerlo de otra manera?

Por ejemplo:

Pondría un if que detecte por ejemplo este carácter #, luego el comando. Quedaría así:
#Luz_ON.

Si detecta en el if principal el #, salta a los if anidados para verificar los comandos Led_ON y Led_OFF ya con equals. Si no detacta ningún #, ignora los demás comandos, pongo un ejemplo abajo.

C:
// Sólo si detecta el # entra a la espera en otros if
// anidados los comandos, en caso contrario no entrará.
if (comando.startswith((F"#")) == true)
{
    // Si los carácteres es recibido y verdadero.
  if (comando.equals(F("Luz_ON")) == true)
  {
    digitalWrite(Led, HIGH);                 // Enciende el Led 13.
    Serial.print(F("ON - Led encendido."));  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Luz ON.         "));        // Mostrar en el LCD.
  }

    if (comando.equals(F("Luz_OFF")) == true)
  {
    digitalWrite(Led, LOW);                  // Apaga el Led 13.
    Serial.print(F("OFF - Led apagado. "));  // Envía este mensaje a C++.
    lcd.setCursor(0, 1);
    lcd.print(F("Luz OFF.        "));        // Mostrar en el LCD.
  }
}

¿Se entiende lo que quiero decir?

Ya que si detecta en una trama normal de bytes algo como esto.
C:
"Quiero que envíes el comando Led_ON haber que pasa"

Desde que Arduino lea la parte Led_ON en medio de una trama, ejecuta la acción y así no interesa.

Tiene que haber por medio esto #, luego salta al if anidado con su comando y usando el Trim() Led_ON, para que ejecute la acción que es cuando realmente quieres.

¿Qué les parece?

Saludos.
 
Yo jamás enviaría ni envío cadenas como comandos.
Lo que suelo enviar es una trama de bytes con cabecera, datos y checksum.
Compruebo la cabecera y realizo el cálculo del checksum, si coincide con el enviado entonces proceso los datos.
 
Hace años, casi 20, hice un sistema que tenía dos modos, el modo "humano" en el que los comandos eran nemotécnicas y había eco en la comunicación, y el modo "máquina" de el que los comandos eran bytes y no había eco.

Habían comandos con checksum y otros que no, el sistema respondía ok o algo así como a los comandos AT.
 
Atrás
Arriba