Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Meta en 31 Julio 2017, 18:38 pm



Título: No me funciona este código
Publicado por: Meta en 31 Julio 2017, 18:38 pm
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.
Código
  1. // Envio_y_recepcion_puerto_serie_cpp.cpp: archivo de proyecto principal.
  2.  
  3. #include "stdafx.h"
  4. #using <System.dll>
  5.  
  6. using namespace System;
  7. using namespace System::Text;
  8. using namespace System::IO::Ports;
  9.  
  10. // array<System::String ^> ^args
  11.  
  12. ref class PortDataReceived
  13. {
  14. public:
  15. static void Main()
  16. {
  17. // Título de la ventana.
  18. Console::Title = "Recibir datos desde Arduino con C++ CLR";
  19.  
  20. // Tamaño ventana consola.
  21. Console::WindowWidth = 55; // X. Ancho.
  22. Console::WindowHeight = 18; // Y. Alto.
  23.  
  24. SerialPort^ Puerto_serie = gcnew SerialPort("COM4");
  25.  
  26. Puerto_serie->BaudRate = 115200;
  27. Puerto_serie->Parity = Parity::None;
  28. Puerto_serie->StopBits = StopBits::One;
  29. Puerto_serie->DataBits = 8;
  30. Puerto_serie->Handshake = Handshake::None;
  31. Puerto_serie->RtsEnable = true;
  32.  
  33. Puerto_serie->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
  34.  
  35. Puerto_serie->Open();
  36.  
  37. ConsoleKey tecla;
  38. Console::WriteLine("Pulse tecla 1 para encender y 2 para apagar:");
  39.  
  40. do
  41. {
  42. tecla = Console::ReadKey(true).Key; // Espera pulsación de teclas.
  43.  
  44. switch (tecla)
  45. {
  46. case ConsoleKey::D1: // Tecla 1 del teclado estandar.
  47. case ConsoleKey::NumPad1: // Tecla 1 del número del pad.
  48.  
  49. array<Byte> ^miBuffer1 = Encoding::ASCII->GetBytes("Luz_ON"); // Codificación ASCII y guarda en la variable array tipo byte.
  50. Puerto_serie->Write(miBuffer1, 0, miBuffer1->Length); // Envía los datos del buffer todo su contenido.
  51. Console::WriteLine("Comando \"Luz_ON\" enviado."); // Muestra en pantalla comandos enviado.
  52. break;
  53.  
  54. case ConsoleKey::D2:
  55. case ConsoleKey::NumPad2:
  56. array<Byte> ^miBuffer2 = Encoding::ASCII->GetBytes("Luz_OFF");
  57. Puerto_serie->Write(miBuffer2, 0, miBuffer2->Length);
  58. Console::WriteLine("Comando \"Luz_OFF\" enviado.");
  59. break;
  60.  
  61. default:
  62. Console::WriteLine("Tecla el 1, el 2 y Escape para salir.");
  63. break;
  64. }
  65. } while (tecla != ConsoleKey::Escape); // Pulsa Escape para salir del menú.
  66.  
  67. Console::WriteLine("Presione cualquier tecla para terminar...");
  68. Console::WriteLine();
  69. Console::ReadKey(); // Espera pulsar una tecla cualquiera.
  70. Puerto_serie->Close(); // Cierra el puerto serie.
  71.  
  72. }
  73.   // Detecta cualquier dato entrante.
  74.  
  75. private:
  76. static void DataReceivedHandler(Object^ sender, SerialDataReceivedEventArgs^ e)
  77. {
  78. SerialPort^ sp = (SerialPort^)sender;
  79. String^ entradaDatos = sp->ReadExisting(); // Almacena los datos recibidos en la variable tipo string.
  80. Console::WriteLine("Dato recibido desde Arduino: " + entradaDatos); // Muestra en pantalla los datos recibidos.;
  81. }
  82. };
  83.  
  84. int main(array<System::String ^> ^args)
  85. {
  86. PortDataReceived::Main();
  87. }

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.


Título: Re: No me funciona este código
Publicado por: 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.


Título: Re: No me funciona este código
Publicado por: ivancea96 en 31 Julio 2017, 19:26 pm
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)


Título: Re: No me funciona este código
Publicado por: Meta en 31 Julio 2017, 20:51 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#:
Código
  1. using System;
  2. using System.Text;
  3. using System.IO.Ports;
  4.  
  5. namespace Envio_y_recepcion_puerto_serie_cs
  6. {
  7.    class Program
  8.    {
  9.        static void Main(string[] args)
  10.        {
  11.            // Título de la ventana.
  12.            Console.Title = "Recibir datos desde Arduino con C#";
  13.  
  14.            // Tamaño ventana consola.
  15.            Console.WindowWidth = 55; // X. Ancho.
  16.            Console.WindowHeight = 18; // Y. Alto.
  17.  
  18.            // Cree un nuevo objeto SerialPort con la configuración predeterminada.
  19.            SerialPort Puerto_serie = new SerialPort("COM4");
  20.  
  21.            Puerto_serie.BaudRate = 115200;
  22.            Puerto_serie.Parity = Parity.None;
  23.            Puerto_serie.StopBits = StopBits.One;
  24.            Puerto_serie.DataBits = 8;
  25.            Puerto_serie.Handshake = Handshake.None;
  26.            Puerto_serie.RtsEnable = true;
  27.  
  28.            // Establecer los tiempos de espera de lectura / escritura.
  29.            Puerto_serie.ReadTimeout = 500; // Milisegundos.
  30.            Puerto_serie.WriteTimeout = 500;
  31.  
  32.            // Detecta cualquier dato recibido.
  33.            Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
  34.  
  35.            Puerto_serie.Open(); // Abrir puerto.
  36.  
  37.            ConsoleKey tecla;
  38.            Console.WriteLine("Pulse tecla 1 para encender y 2 para apagar:");
  39.  
  40.            do
  41.            {
  42.                tecla = Console.ReadKey(true).Key; // Espera pulsación de teclas.
  43.  
  44.                switch (tecla)
  45.                {
  46.                    case ConsoleKey.D1: // Tecla 1 del teclado estandar.
  47.                    case ConsoleKey.NumPad1: // Tecla 1 del número del pad.
  48.                        byte[] miBuffer1 = Encoding.ASCII.GetBytes("Luz_ON"); // Codificación ASCII y guarda en la variable array tipo byte.
  49.                        Puerto_serie.Write(miBuffer1, 0, miBuffer1.Length); // Envía los datos del buffer todo su contenido.
  50.                        Console.WriteLine("Comando \"Luz_ON\" enviado."); // Muestra en pantalla comandos enviado.
  51.                        break;
  52.  
  53.                    case ConsoleKey.D2:
  54.                    case ConsoleKey.NumPad2:
  55.                        byte[] miBuffer2 = Encoding.ASCII.GetBytes("Luz_OFF");
  56.                        Puerto_serie.Write(miBuffer2, 0, miBuffer2.Length);
  57.                        Console.WriteLine("Comando \"Luz_OFF\" enviado.");
  58.                        break;
  59.  
  60.                    default:
  61.                        Console.WriteLine("Tecla el 1, el 2 y Escape para salir.");
  62.                        break;
  63.                }
  64.            } while (tecla != ConsoleKey.Escape); // Pulsa Escape para salir del menú.
  65.  
  66.            Console.WriteLine("Presione cualquier tecla para terminar...");
  67.            Console.WriteLine();
  68.            Console.ReadKey(); // Espera pulsar una tecla cualquiera.
  69.            Puerto_serie.Close(); // Cierra el puerto serie.
  70.        }
  71.  
  72.    // Detecta cualquier dato entrante.
  73.    private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
  74.        {
  75.            SerialPort sp = (SerialPort)sender;
  76.            string entradaDatos = sp.ReadExisting(); // Almacena los datos recibidos en la variable tipo string.
  77.            Console.WriteLine("Dato recibido desde Arduino: " + entradaDatos); // Muestra en pantalla los datos recibidos.
  78.        }
  79.    }
  80. }

Visual Basic .net:
Código
  1. Imports System.IO.Ports
  2. Imports System.Text
  3.  
  4. Module Module1
  5.  
  6.    Sub Main()
  7.        ' Título de la ventana.
  8.        Console.Title = "Recibir datos desde Arduino con Visual Basic .net"
  9.  
  10.        ' Tamaño ventana consola.
  11.        Console.WindowWidth = 55 ' X. Ancho.
  12.        Console.WindowHeight = 18 ' Y. Alto.
  13.        ' Cree un nuevo objeto SerialPort con la configuración predeterminada.
  14.        Dim Puerto_serie As New SerialPort("COM4")
  15.  
  16.        Puerto_serie.BaudRate = 115200
  17.        Puerto_serie.Parity = Parity.None
  18.        Puerto_serie.StopBits = StopBits.One
  19.        Puerto_serie.DataBits = 8
  20.        Puerto_serie.Handshake = Handshake.None
  21.        Puerto_serie.RtsEnable = True
  22.  
  23.        ' Establecer los tiempos de espera de lectura / escritura.
  24.        Puerto_serie.ReadTimeout = 500
  25.        ' Milisegundos.
  26.        Puerto_serie.WriteTimeout = 500
  27.  
  28.        ' Detecta cualquier dato recibido.
  29.        AddHandler Puerto_serie.DataReceived, AddressOf DataReceivedHandler
  30.  
  31.        Puerto_serie.Open() ' Abrir puerto.
  32.        Dim tecla As ConsoleKey
  33.        Console.WriteLine("Pulse tecla 1 para encender y 2 para apagar:")
  34.  
  35.        Do
  36.            tecla = Console.ReadKey(True).Key ' Espera pulsación de teclas.
  37.            Select Case tecla
  38.        ' Tecla 1 del teclado estandar.
  39.                Case ConsoleKey.D1, ConsoleKey.NumPad1 ' Tecla 1 del número del pad.
  40.                    Dim miBuffer1 As Byte() = Encoding.ASCII.GetBytes("Luz_ON") ' Codificación ASCII y guarda en la variable array tipo byte.
  41.                    Puerto_serie.Write(miBuffer1, 0, miBuffer1.Length) ' Envía los datos del buffer todo su contenido.
  42.                    Console.WriteLine("Comando ""Luz_ON"" enviado.") ' Muestra en pantalla comandos enviado.
  43.                    Exit Select
  44.  
  45.                Case ConsoleKey.D2, ConsoleKey.NumPad2
  46.                    Dim miBuffer2 As Byte() = Encoding.ASCII.GetBytes("Luz_OFF")
  47.                    Puerto_serie.Write(miBuffer2, 0, miBuffer2.Length)
  48.                    Console.WriteLine("Comando ""Luz_OFF"" enviado.")
  49.                    Exit Select
  50.                Case Else
  51.  
  52.                    Console.WriteLine("Tecla el 1, el 2 y Escape para salir.")
  53.                    Exit Select
  54.            End Select
  55.        Loop While tecla <> ConsoleKey.Escape ' Pulsa Escape para salir del menú.
  56.  
  57.        Console.WriteLine("Presione cualquier tecla para terminar...")
  58.        Console.WriteLine()
  59.        Console.ReadKey() ' Espera pulsar una tecla cualquiera.
  60.  
  61.        Puerto_serie.Close() ' Cierra el puerto serie.
  62.  
  63.    End Sub
  64.  
  65.    Private Sub DataReceivedHandler(sender As Object, e As SerialDataReceivedEventArgs)
  66.  
  67.        Dim sp As SerialPort = DirectCast(sender, SerialPort)
  68.        Dim entradaDatos As String = sp.ReadExisting() ' Almacena los datos recibidos en la variable tipo string.
  69.  
  70.        Console.WriteLine(Convert.ToString("Dato recibido desde Arduino: ") & entradaDatos) ' Muestra en pantalla los datos recibidos.
  71.  
  72.    End Sub
  73.  
  74. End Module
  75.  

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.
Código
  1. #include "stdafx.h"
  2. #using <System.dll>
  3.  
  4. using namespace System;
  5. using namespace System::Text;
  6. using namespace System::IO::Ports;
  7.  
  8. ref class PortDataReceived
  9. {
  10. public:
  11. static void Main()
  12. {
  13. // Título de la ventana.
  14. Console::Title = "Recibir datos desde Arduino con C++ CLR";
  15.  
  16. // Tamaño ventana consola.
  17. Console::WindowWidth = 55; // X. Ancho.
  18. Console::WindowHeight = 18; // Y. Alto.
  19.  
  20. SerialPort^ Puerto_serie = gcnew SerialPort("COM4");
  21.  
  22. Puerto_serie->BaudRate = 115200;
  23. Puerto_serie->Parity = Parity::None;
  24. Puerto_serie->StopBits = StopBits::One;
  25. Puerto_serie->DataBits = 8;
  26. Puerto_serie->Handshake = Handshake::None;
  27. Puerto_serie->RtsEnable = true;
  28.  
  29. Puerto_serie->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
  30.  
  31. Puerto_serie->Open();
  32.  
  33. ConsoleKey tecla;
  34. Console::WriteLine("Pulse tecla 1 para encender y 2 para apagar:");
  35.  
  36. do
  37. {
  38. tecla = Console::ReadKey(true).Key; // Espera pulsación de teclas.
  39.  
  40. switch (tecla)
  41. {
  42. {
  43. case ConsoleKey::D1: // Tecla 1 del teclado estandar.
  44. case ConsoleKey::NumPad1: // Tecla 1 del número del pad.
  45.  
  46. array<Byte> ^miBuffer1 = Encoding::ASCII->GetBytes("Luz_ON"); // Codificación ASCII y guarda en la variable array tipo byte.
  47. Puerto_serie->Write(miBuffer1, 0, miBuffer1->Length); // Envía los datos del buffer todo su contenido.
  48. Console::WriteLine("Comando \"Luz_ON\" enviado."); // Muestra en pantalla comandos enviado.
  49. break;
  50. }
  51.  
  52. {
  53. case ConsoleKey::D2:
  54. case ConsoleKey::NumPad2:
  55. array<Byte> ^miBuffer2 = Encoding::ASCII->GetBytes("Luz_OFF");
  56. Puerto_serie->Write(miBuffer2, 0, miBuffer2->Length);
  57. Console::WriteLine("Comando \"Luz_OFF\" enviado.");
  58. break;
  59. }
  60. {
  61. default:
  62. Console::WriteLine("Tecla el 1, el 2 y Escape para salir.");
  63. break;
  64. }
  65. }
  66. }
  67.  
  68. while (tecla != ConsoleKey::Escape); // Pulsa Escape para salir del menú.
  69.  
  70. Console::WriteLine("Presione cualquier tecla para terminar...");
  71. Console::WriteLine();
  72. Console::ReadKey(); // Espera pulsar una tecla cualquiera.
  73. Puerto_serie->Close(); // Cierra el puerto serie.
  74.  
  75. }
  76.  
  77. // Detecta cualquier dato entrante.
  78. private:
  79. static void DataReceivedHandler(Object^ sender, SerialDataReceivedEventArgs^ e)
  80. {
  81. SerialPort^ sp = (SerialPort^)sender;
  82. String^ entradaDatos = sp->ReadExisting(); // Almacena los datos recibidos en la variable tipo string.
  83. Console::WriteLine("Dato recibido desde Arduino: " + entradaDatos); // Muestra en pantalla los datos recibidos.;
  84. }
  85. };
  86.  
  87. int main(array<System::String ^> ^args)
  88. {
  89. PortDataReceived::Main();
  90. }


Título: Re: No me funciona este código
Publicado por: ivancea96 en 31 Julio 2017, 21:44 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:

Código
  1. switch(a){
  2.    case 1:
  3.    {
  4.        // Código
  5.    }
  6. }


Título: Re: No me funciona este código
Publicado por: Meta en 1 Agosto 2017, 03:07 am
Funciona igual.

Lo dejo aquí por si acaso.
Código
  1. #include "stdafx.h"
  2. #using <System.dll>
  3.  
  4. using namespace System;
  5. using namespace System::Text;
  6. using namespace System::IO::Ports;
  7.  
  8. ref class PortDataReceived
  9. {
  10. public:
  11. static void Main()
  12. {
  13. // Título de la ventana.
  14. Console::Title = "Recibir datos desde Arduino con C++ CLR";
  15.  
  16. // Tamaño ventana consola.
  17. Console::WindowWidth = 55; // X. Ancho.
  18. Console::WindowHeight = 18; // Y. Alto.
  19.  
  20. SerialPort^ Puerto_serie = gcnew SerialPort("COM4");
  21.  
  22. Puerto_serie->BaudRate = 115200;
  23. Puerto_serie->Parity = Parity::None;
  24. Puerto_serie->StopBits = StopBits::One;
  25. Puerto_serie->DataBits = 8;
  26. Puerto_serie->Handshake = Handshake::None;
  27. Puerto_serie->RtsEnable = true;
  28.  
  29. Puerto_serie->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
  30.  
  31. Puerto_serie->Open(); // Abrir puerto.
  32.  
  33. ConsoleKey tecla;
  34. Console::WriteLine("Pulse tecla 1 para encender y 2 para apagar:");
  35.  
  36. do
  37. {
  38. tecla = Console::ReadKey(true).Key; // Espera pulsación de teclas.
  39.  
  40. switch (tecla)
  41. {
  42.  
  43. case ConsoleKey::D1: // Tecla 1 del teclado estandar.
  44. case ConsoleKey::NumPad1: // Tecla 1 del número del pad.
  45. {
  46. array<Byte> ^miBuffer1 = Encoding::ASCII->GetBytes("Luz_ON"); // Codificación ASCII y guarda en la variable array tipo byte.
  47. Puerto_serie->Write(miBuffer1, 0, miBuffer1->Length); // Envía los datos del buffer todo su contenido.
  48. Console::WriteLine("Comando \"Luz_ON\" enviado."); // Muestra en pantalla comandos enviado.
  49. break;
  50. }
  51.  
  52.  
  53. case ConsoleKey::D2:
  54. case ConsoleKey::NumPad2:
  55. {
  56. array<Byte> ^miBuffer2 = Encoding::ASCII->GetBytes("Luz_OFF");
  57. Puerto_serie->Write(miBuffer2, 0, miBuffer2->Length);
  58. Console::WriteLine("Comando \"Luz_OFF\" enviado.");
  59. break;
  60. }
  61.  
  62. default:
  63. {
  64. Console::WriteLine("Tecla el 1, el 2 y Escape para salir.");
  65. break;
  66. }
  67. }
  68. }
  69.  
  70. while (tecla != ConsoleKey::Escape); // Pulsa Escape para salir del menú.
  71.  
  72. Console::WriteLine("Presione cualquier tecla para terminar...");
  73. Console::WriteLine();
  74. Console::ReadKey(); // Espera pulsar una tecla cualquiera.
  75. Puerto_serie->Close(); // Cierra el puerto serie.
  76.  
  77. }
  78.  
  79. // Detecta cualquier dato entrante.
  80. private:
  81. static void DataReceivedHandler(Object^ sender, SerialDataReceivedEventArgs^ e)
  82. {
  83. SerialPort^ sp = (SerialPort^)sender;
  84. String^ entradaDatos = sp->ReadExisting(); // Almacena los datos recibidos en la variable tipo string.
  85. Console::WriteLine("Dato recibido desde Arduino: " + entradaDatos); // Muestra en pantalla los datos recibidos.;
  86. }
  87. };
  88.  
  89. int main(array<System::String ^> ^args)
  90. {
  91. PortDataReceived::Main();
  92. }

Saludos.


Título: Re: No me funciona este código
Publicado por: ivancea96 en 1 Agosto 2017, 09:44 am
No he dicho que fuera a funcionar diferente (...)