Hola:
Estoy probando y modificando este código en C++ con Visual Studio Community 2017. En el C++ CLR.
Sigo este enlace.
https://msdn.microsoft.com/es-es/library/system.io.ports.serialport.datareceived(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-2
El codigo nuevo que he indicado es este.
// Envio_y_recepcion_puerto_serie_cpp.cpp: archivo de proyecto principal.
#include "stdafx.h"
#using <System.dll>
using namespace System;
using namespace System::Text;
using namespace System::IO::Ports;
// array<System::String ^> ^args
ref class PortDataReceived
{
public:
static void Main()
{
// Título de la ventana.
Console::Title = "Recibir datos desde Arduino con C++ CLR";
// Tamaño ventana consola.
Console::WindowWidth = 55; // X. Ancho.
Console::WindowHeight = 18; // Y. Alto.
SerialPort^ Puerto_serie = gcnew SerialPort("COM4");
Puerto_serie->BaudRate = 115200;
Puerto_serie->Parity = Parity::None;
Puerto_serie->StopBits = StopBits::One;
Puerto_serie->DataBits = 8;
Puerto_serie->Handshake = Handshake::None;
Puerto_serie->RtsEnable = true;
Puerto_serie->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
Puerto_serie->Open();
ConsoleKey tecla;
Console::WriteLine("Pulse tecla 1 para encender y 2 para apagar:");
do
{
tecla = Console::ReadKey(true).Key; // Espera pulsación de teclas.
switch (tecla)
{
case ConsoleKey::D1: // Tecla 1 del teclado estandar.
case ConsoleKey::NumPad1: // Tecla 1 del número del pad.
array<Byte> ^miBuffer1 = Encoding::ASCII->GetBytes("Luz_ON"); // Codificación ASCII y guarda en la variable array tipo byte.
Puerto_serie->Write(miBuffer1, 0, miBuffer1->Length); // Envía los datos del buffer todo su contenido.
Console::WriteLine("Comando \"Luz_ON\" enviado."); // Muestra en pantalla comandos enviado.
break;
case ConsoleKey::D2:
case ConsoleKey::NumPad2:
array<Byte> ^miBuffer2 = Encoding::ASCII->GetBytes("Luz_OFF");
Puerto_serie->Write(miBuffer2, 0, miBuffer2->Length);
Console::WriteLine("Comando \"Luz_OFF\" enviado.");
break;
default:
Console::WriteLine("Tecla el 1, el 2 y Escape para salir.");
break;
}
} while (tecla != ConsoleKey::Escape); // Pulsa Escape para salir del menú.
Console::WriteLine("Presione cualquier tecla para terminar...");
Console::WriteLine();
Console::ReadKey(); // Espera pulsar una tecla cualquiera.
Puerto_serie->Close(); // Cierra el puerto serie.
}
// Detecta cualquier dato entrante.
private:
static void DataReceivedHandler(Object^ sender, SerialDataReceivedEventArgs^ e)
{
SerialPort^ sp = (SerialPort^)sender;
String^ entradaDatos = sp->ReadExisting(); // Almacena los datos recibidos en la variable tipo string.
Console::WriteLine("Dato recibido desde Arduino: " + entradaDatos); // Muestra en pantalla los datos recibidos.;
}
};
int main(array<System::String ^> ^args)
{
PortDataReceived::Main();
}
En apariencia no parece tener errores, al compilar me suelta estos 5 errrores.
Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido
Error C1854 no se puede sobrescribir la información realizada durante la creación del encabezado precompilado en el archivo objeto: 'c:\users\meta\documents\visual studio 2017\projects\envio_y_recepcion_puerto_serie_cpp\envio_y_recepcion_puerto_serie_cpp\debug\stdafx.obj' Envio_y_recepcion_puerto_serie_cpp C:\Users\Meta\documents\visual studio 2017\Projects\Envio_y_recepcion_puerto_serie_cpp\Envio_y_recepcion_puerto_serie_cpp\stdafx.cpp 5
Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido
Error C2361 la inicialización de 'miBuffer2' se omite en la etiqueta 'default' Envio_y_recepcion_puerto_serie_cpp C:\Users\Meta\documents\visual studio 2017\Projects\Envio_y_recepcion_puerto_serie_cpp\Envio_y_recepcion_puerto_serie_cpp\Envio_y_recepcion_puerto_serie_cpp.cpp 64
¿Cómo lo soluciono?
Saludos.
Trata de no declarar variables directamente dentro del ámbito de un switch.
Si realmente lo necesitas, entonces colócale llaves al código del case.
Y si aun tuvieras problemas, mira la documentación del código de error.
https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/fatal-error-c1854 (https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/fatal-error-c1854)
Cita de: ivancea96 en 31 Julio 2017, 19:14 PM
Trata de no declarar variables directamente dentro del ámbito de un switch.
Si realmente lo necesitas, entonces colócale llaves al código del case.
Resuelto un problema.
(http://www.subeimagenes.com/img/64-1761205.png)
En cuando al Switch.
https://docs.microsoft.com/en-us/cpp/cpp/switch-statement-cpp?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DES-ES%26k%3Dk(switch_CPP)%3Bk(switch)%3Bk(TargetFrameworkMoniker-.NETFramework%2CVersion%3Dv4.6.2)%3Bk(TargetFrameworkMoniker-.NETFramework%2CVersion%3Dv4.6.2)%3Bk(DevLang-C%2B%2B)%3Bk(TargetOS-Windows)%3Bk(TargetFrameworkMoniker-.NETFramework%2CVersion%3Dv4.6.2)%26rd%3Dtrue
Si no lo hago como lo hice en en C# y VB .net me funciona.
¿Cómo se hace en C++?
En C#:
using System;
using System.Text;
using System.IO.Ports;
namespace Envio_y_recepcion_puerto_serie_cs
{
class Program
{
static void Main(string[] args)
{
// Título de la ventana.
Console.Title = "Recibir datos desde Arduino con C#";
// Tamaño ventana consola.
Console.WindowWidth = 55; // X. Ancho.
Console.WindowHeight = 18; // Y. Alto.
// Cree un nuevo objeto SerialPort con la configuración predeterminada.
SerialPort Puerto_serie = new SerialPort("COM4");
Puerto_serie.BaudRate = 115200;
Puerto_serie.Parity = Parity.None;
Puerto_serie.StopBits = StopBits.One;
Puerto_serie.DataBits = 8;
Puerto_serie.Handshake = Handshake.None;
Puerto_serie.RtsEnable = true;
// Establecer los tiempos de espera de lectura / escritura.
Puerto_serie.ReadTimeout = 500; // Milisegundos.
Puerto_serie.WriteTimeout = 500;
// Detecta cualquier dato recibido.
Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
Puerto_serie.Open(); // Abrir puerto.
ConsoleKey tecla;
Console.WriteLine("Pulse tecla 1 para encender y 2 para apagar:");
do
{
tecla = Console.ReadKey(true).Key; // Espera pulsación de teclas.
switch (tecla)
{
case ConsoleKey.D1: // Tecla 1 del teclado estandar.
case ConsoleKey.NumPad1: // Tecla 1 del número del pad.
byte[] miBuffer1 = Encoding.ASCII.GetBytes("Luz_ON"); // Codificación ASCII y guarda en la variable array tipo byte.
Puerto_serie.Write(miBuffer1, 0, miBuffer1.Length); // Envía los datos del buffer todo su contenido.
Console.WriteLine("Comando \"Luz_ON\" enviado."); // Muestra en pantalla comandos enviado.
break;
case ConsoleKey.D2:
case ConsoleKey.NumPad2:
byte[] miBuffer2 = Encoding.ASCII.GetBytes("Luz_OFF");
Puerto_serie.Write(miBuffer2, 0, miBuffer2.Length);
Console.WriteLine("Comando \"Luz_OFF\" enviado.");
break;
default:
Console.WriteLine("Tecla el 1, el 2 y Escape para salir.");
break;
}
} while (tecla != ConsoleKey.Escape); // Pulsa Escape para salir del menú.
Console.WriteLine("Presione cualquier tecla para terminar...");
Console.WriteLine();
Console.ReadKey(); // Espera pulsar una tecla cualquiera.
Puerto_serie.Close(); // Cierra el puerto serie.
}
// Detecta cualquier dato entrante.
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string entradaDatos = sp.ReadExisting(); // Almacena los datos recibidos en la variable tipo string.
Console.WriteLine("Dato recibido desde Arduino: " + entradaDatos); // Muestra en pantalla los datos recibidos.
}
}
}
Visual Basic .net:
Imports System.IO.Ports
Imports System.Text
Module Module1
Sub Main()
' Título de la ventana.
Console.Title = "Recibir datos desde Arduino con Visual Basic .net"
' Tamaño ventana consola.
Console.WindowWidth = 55 ' X. Ancho.
Console.WindowHeight = 18 ' Y. Alto.
' Cree un nuevo objeto SerialPort con la configuración predeterminada.
Dim Puerto_serie As New SerialPort("COM4")
Puerto_serie.BaudRate = 115200
Puerto_serie.Parity = Parity.None
Puerto_serie.StopBits = StopBits.One
Puerto_serie.DataBits = 8
Puerto_serie.Handshake = Handshake.None
Puerto_serie.RtsEnable = True
' Establecer los tiempos de espera de lectura / escritura.
Puerto_serie.ReadTimeout = 500
' Milisegundos.
Puerto_serie.WriteTimeout = 500
' Detecta cualquier dato recibido.
AddHandler Puerto_serie.DataReceived, AddressOf DataReceivedHandler
Puerto_serie.Open() ' Abrir puerto.
Dim tecla As ConsoleKey
Console.WriteLine("Pulse tecla 1 para encender y 2 para apagar:")
Do
tecla = Console.ReadKey(True).Key ' Espera pulsación de teclas.
Select Case tecla
' Tecla 1 del teclado estandar.
Case ConsoleKey.D1, ConsoleKey.NumPad1 ' Tecla 1 del número del pad.
Dim miBuffer1 As Byte() = Encoding.ASCII.GetBytes("Luz_ON") ' Codificación ASCII y guarda en la variable array tipo byte.
Puerto_serie.Write(miBuffer1, 0, miBuffer1.Length) ' Envía los datos del buffer todo su contenido.
Console.WriteLine("Comando ""Luz_ON"" enviado.") ' Muestra en pantalla comandos enviado.
Exit Select
Case ConsoleKey.D2, ConsoleKey.NumPad2
Dim miBuffer2 As Byte() = Encoding.ASCII.GetBytes("Luz_OFF")
Puerto_serie.Write(miBuffer2, 0, miBuffer2.Length)
Console.WriteLine("Comando ""Luz_OFF"" enviado.")
Exit Select
Case Else
Console.WriteLine("Tecla el 1, el 2 y Escape para salir.")
Exit Select
End Select
Loop While tecla <> ConsoleKey.Escape ' Pulsa Escape para salir del menú.
Console.WriteLine("Presione cualquier tecla para terminar...")
Console.WriteLine()
Console.ReadKey() ' Espera pulsar una tecla cualquiera.
Puerto_serie.Close() ' Cierra el puerto serie.
End Sub
Private Sub DataReceivedHandler(sender As Object, e As SerialDataReceivedEventArgs)
Dim sp As SerialPort = DirectCast(sender, SerialPort)
Dim entradaDatos As String = sp.ReadExisting() ' Almacena los datos recibidos en la variable tipo string.
Console.WriteLine(Convert.ToString("Dato recibido desde Arduino: ") & entradaDatos) ' Muestra en pantalla los datos recibidos.
End Sub
End Module
Que majadero trabajar en C++- Con razón que hoy en día solo lo hacen los que se acostumbraron en el pasado.
Edito:Ya funciona al 100 %.
Muchas gracias mi muy distinguido amigo. Dejo el código por si alguien lo necesita.
#include "stdafx.h"
#using <System.dll>
using namespace System;
using namespace System::Text;
using namespace System::IO::Ports;
ref class PortDataReceived
{
public:
static void Main()
{
// Título de la ventana.
Console::Title = "Recibir datos desde Arduino con C++ CLR";
// Tamaño ventana consola.
Console::WindowWidth = 55; // X. Ancho.
Console::WindowHeight = 18; // Y. Alto.
SerialPort^ Puerto_serie = gcnew SerialPort("COM4");
Puerto_serie->BaudRate = 115200;
Puerto_serie->Parity = Parity::None;
Puerto_serie->StopBits = StopBits::One;
Puerto_serie->DataBits = 8;
Puerto_serie->Handshake = Handshake::None;
Puerto_serie->RtsEnable = true;
Puerto_serie->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
Puerto_serie->Open();
ConsoleKey tecla;
Console::WriteLine("Pulse tecla 1 para encender y 2 para apagar:");
do
{
tecla = Console::ReadKey(true).Key; // Espera pulsación de teclas.
switch (tecla)
{
{
case ConsoleKey::D1: // Tecla 1 del teclado estandar.
case ConsoleKey::NumPad1: // Tecla 1 del número del pad.
array<Byte> ^miBuffer1 = Encoding::ASCII->GetBytes("Luz_ON"); // Codificación ASCII y guarda en la variable array tipo byte.
Puerto_serie->Write(miBuffer1, 0, miBuffer1->Length); // Envía los datos del buffer todo su contenido.
Console::WriteLine("Comando \"Luz_ON\" enviado."); // Muestra en pantalla comandos enviado.
break;
}
{
case ConsoleKey::D2:
case ConsoleKey::NumPad2:
array<Byte> ^miBuffer2 = Encoding::ASCII->GetBytes("Luz_OFF");
Puerto_serie->Write(miBuffer2, 0, miBuffer2->Length);
Console::WriteLine("Comando \"Luz_OFF\" enviado.");
break;
}
{
default:
Console::WriteLine("Tecla el 1, el 2 y Escape para salir.");
break;
}
}
}
while (tecla != ConsoleKey::Escape); // Pulsa Escape para salir del menú.
Console::WriteLine("Presione cualquier tecla para terminar...");
Console::WriteLine();
Console::ReadKey(); // Espera pulsar una tecla cualquiera.
Puerto_serie->Close(); // Cierra el puerto serie.
}
// Detecta cualquier dato entrante.
private:
static void DataReceivedHandler(Object^ sender, SerialDataReceivedEventArgs^ e)
{
SerialPort^ sp = (SerialPort^)sender;
String^ entradaDatos = sp->ReadExisting(); // Almacena los datos recibidos en la variable tipo string.
Console::WriteLine("Dato recibido desde Arduino: " + entradaDatos); // Muestra en pantalla los datos recibidos.;
}
};
int main(array<System::String ^> ^args)
{
PortDataReceived::Main();
}
Cita de: Meta en 31 Julio 2017, 20:51 PM
Que majadero trabajar en C++- Con razón que hoy en día solo lo hacen los que se acostumbraron en el pasado.
Con todo el respeto, no saber C++ no hace C++ un mal lenguaje.
Y bueno, es mala prácctica meter los case dentro de las llaves. Debería ser:
switch(a){
case 1:
{
// Código
}
}
Funciona igual.
Lo dejo aquí por si acaso.
#include "stdafx.h"
#using <System.dll>
using namespace System;
using namespace System::Text;
using namespace System::IO::Ports;
ref class PortDataReceived
{
public:
static void Main()
{
// Título de la ventana.
Console::Title = "Recibir datos desde Arduino con C++ CLR";
// Tamaño ventana consola.
Console::WindowWidth = 55; // X. Ancho.
Console::WindowHeight = 18; // Y. Alto.
SerialPort^ Puerto_serie = gcnew SerialPort("COM4");
Puerto_serie->BaudRate = 115200;
Puerto_serie->Parity = Parity::None;
Puerto_serie->StopBits = StopBits::One;
Puerto_serie->DataBits = 8;
Puerto_serie->Handshake = Handshake::None;
Puerto_serie->RtsEnable = true;
Puerto_serie->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
Puerto_serie->Open(); // Abrir puerto.
ConsoleKey tecla;
Console::WriteLine("Pulse tecla 1 para encender y 2 para apagar:");
do
{
tecla = Console::ReadKey(true).Key; // Espera pulsación de teclas.
switch (tecla)
{
case ConsoleKey::D1: // Tecla 1 del teclado estandar.
case ConsoleKey::NumPad1: // Tecla 1 del número del pad.
{
array<Byte> ^miBuffer1 = Encoding::ASCII->GetBytes("Luz_ON"); // Codificación ASCII y guarda en la variable array tipo byte.
Puerto_serie->Write(miBuffer1, 0, miBuffer1->Length); // Envía los datos del buffer todo su contenido.
Console::WriteLine("Comando \"Luz_ON\" enviado."); // Muestra en pantalla comandos enviado.
break;
}
case ConsoleKey::D2:
case ConsoleKey::NumPad2:
{
array<Byte> ^miBuffer2 = Encoding::ASCII->GetBytes("Luz_OFF");
Puerto_serie->Write(miBuffer2, 0, miBuffer2->Length);
Console::WriteLine("Comando \"Luz_OFF\" enviado.");
break;
}
default:
{
Console::WriteLine("Tecla el 1, el 2 y Escape para salir.");
break;
}
}
}
while (tecla != ConsoleKey::Escape); // Pulsa Escape para salir del menú.
Console::WriteLine("Presione cualquier tecla para terminar...");
Console::WriteLine();
Console::ReadKey(); // Espera pulsar una tecla cualquiera.
Puerto_serie->Close(); // Cierra el puerto serie.
}
// Detecta cualquier dato entrante.
private:
static void DataReceivedHandler(Object^ sender, SerialDataReceivedEventArgs^ e)
{
SerialPort^ sp = (SerialPort^)sender;
String^ entradaDatos = sp->ReadExisting(); // Almacena los datos recibidos en la variable tipo string.
Console::WriteLine("Dato recibido desde Arduino: " + entradaDatos); // Muestra en pantalla los datos recibidos.;
}
};
int main(array<System::String ^> ^args)
{
PortDataReceived::Main();
}
Saludos.
No he dicho que fuera a funcionar diferente (...)