Autor
Tema: Puerto serie C++. Mejorar el programa. (Leído 27,895 veces)
Meta
La cosa rara que hace es no volver a la opción principal si no pones un 1 o un 2, desde que pongas otra cosa, no sale de ahí. La cuestión es como se hace. Sigo investigando...
En línea
ivancea96
Desconectado
Mensajes: 3.412
ASMático
En primer lugar, yo separaría estoa una función:
while ( true ) {
int n = Puerto- > ReadData( lectura, 49 ) ;
if ( n > 0 ) {
lectura[ n + 1 ] = '\0 ' ;
break ;
}
Sleep( 1 ) ;
}
Una función que espere a que el Arduino envíe datos, y los retorne.
Lo de esperar datos solo lo vas a hacer si pulsan 1 o 2, así que llamas a esa función en cada case. Es cierto que los 2 case son idénticos salvo por la constante que envías. Podrías poner algo como:
const char * luz[ 2 ] = { "Luz_ON" , "Luz_OFF" } ;
switch ( opc) {
case 1 :
case 2 :
cout << "Enviando: " << luz[ opc- 1 ] << endl;
Puerto- > WriteData( luz[ opc- 1 ] , strlen ( luz[ opc- 1 ] ) ) ;
cout << "Respuesta: " << obtenerRespuestaArduino( ) << endl;
break ;
default :
// ...
}
De ese modo, solo esperará entrada del Arduino cuando sea necesario hacerlo. Al terminar el switch, puedes poner, si quieres, para leer datos del Arduino (sin esperar indefinidamente, eso sí, para que vuelva al inicio del bucle while y siga preguntando)
El problema es eso, el cómo está estructurado el código. Lo dicho: si tienes más experiencia en C#, puedes tratar de hacerlo ahí primero.
En línea
Meta
Hola:
A pesar de tener más experiencia con C#, con la idea de pasarlo a C++, he hecho esto.
Código 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 ( "Enviado: {0}" , miBuffer1) ; // Muestra en pantala el mensaje enviado, en este caso, Luz_ON.
break ;
case ConsoleKey. D2 :
case ConsoleKey. NumPad2 :
byte [ ] miBuffer2 = Encoding. ASCII . GetBytes ( "Luz_OFF" ) ;
Puerto_serie. Write ( miBuffer2, 0 , miBuffer2. Length ) ;
//Console.WriteLine("Enviado: {0}", miBuffer2);
break ;
default :
Console. WriteLine ( "Tecla el 1, el 2 y Escape para salir." ) ;
break ;
}
}
// Pulsa Escape para salir del menú.
while ( tecla != ConsoleKey. Escape ) ;
Console. WriteLine ( "Presione cualquier tecla para continuar..." ) ;
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.
}
}
}
Es este último código que me funciona mejor, también he intentado que me muestre el valor enviado y me diga en pantalla:
Enviado: Luz_ONHe usado esto para que muestre lo que envía:
Console. WriteLine ( "Enviado: {0}" , miBuffer1) ;
Su resultado fue este:
Enviado: system.Byte[] ¿Pero qué es esto?
Concretamente aquí:
case ConsoleKey. D1 :
case ConsoleKey. NumPad1 :
byte [ ] miBuffer1 = Encoding. ASCII . GetBytes ( "Luz_ON" ) ;
Puerto_serie. Write ( miBuffer1, 0 , miBuffer1. Length ) ;
Console. WriteLine ( "Enviado: {0}" , miBuffer1) ;
break ;
Lo bueno que también ya recibo el ON y OFF si pulso el pulsador dede Arduino directamente. Funciona todo menos lo indicado justo arriba.
Debe aparecer de esta manera:
Luz_ON Aparece en hexadecimales.
Console. WriteLine ( "Enviado: {0}" , BitConverter. ToString ( miBuffer1) ) ;
Cuando esté listo todo C#, ya se podrá hacer el C++ de una vez por todas, jaaaj ajajajja. Eso espero y se las debo a todos.
PD:
No me había dado cuenta que tienes un blog , no sabía que eres un profesional de C++.
« Última modificación: 24 Marzo 2017, 10:08 am por Meta »
En línea
ivancea96
Desconectado
Mensajes: 3.412
ASMático
Prueba con:
Encoding. ASCII . GetString ( miBuffer1) ;
En línea
Meta
Buenas:
Lo había probado, da este error:
no se puede convertir de 'byte[]' a 'char[]'
Bueno, como no es importante, pues lo que tenemos arriba con C# ya se puede hacer una idea de como se puede hacer en C++. Mira que da guerra el C++ de las narices, no me extraña que Java junto con C# desbanque a C++ Win32 como lenguaje principal para un informático.
Empezando otra vez con las grandes aventuras con el C++ de Win32,
Como se puede ver en el código de C# arriba, hay que usar un do while.
https://msdn.microsoft.com/es-es/library/b0kk5few.aspx Tutorial:
VIDEO Saludos.
« Última modificación: 24 Marzo 2017, 14:46 pm por Meta »
En línea
Meta
Lo más parecido que he hecho es esto.
#include <iostream>
#include <fstream>
#include <Windows.h>
#include <stdio.h>
#include "SerialClass.h"
using namespace std;
void main( )
{
// Título de la ventana
SetConsoleTitle( "Control Led Arduino." ) ;
// Puerto serie.
Serial* Puerto = new Serial( "COM4" ) ;
// Comandos para Arduino.
char Luz_ON[ ] = "Luz_ON" ; // Envía "Luz_ON" al puerto serie.
char Luz_OFF[ ] = "Luz_OFF" ;
char lectura[ 50 ] = "\0 " ; // Guardan datos de entrada del puerto.
int tecla; // Guarda las teclas pulsadas.
cout << "Introduzca la opcion deseada: " << endl << endl;
cin >> tecla; // Aquí introduces un número, el 1 o el 2.
do
{
while ( tecla)
{
case 1 :
// Encener luz.
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".
break ;
case 2 :
// Apagar luz.
cout << "Enviando: " << Luz_OFF << endl;
Puerto- > WriteData( Luz_OFF, sizeof ( Luz_OFF) - 1 ) ;
break ;
default : // Si haz pulsado otro número distinto del 1 y 2, muestra
cout << "Puse del 1 al 2." ; // este mensaje.
}
} while ( tecla ! = 0 ) ;
}
while ( true ) {
int n = Puerto- > ReadData( lectura, 49 ) ;
if ( n > 0 ) {
lectura[ n + 1 ] = '\0 ' ;
break ;
}
Sleep( 1 ) ;
}
En línea
ivancea96
Desconectado
Mensajes: 3.412
ASMático
Parecido sí, pero de forma incorrecta:
En C# tienes esto:
do
{
tecla = Console. ReadKey ( true ) . Key ; // Espera pulsación de teclas.
En C++ tienes esto otro:
cin >> tecla; // Aquí introduces un número, el 1 o el 2.
do
{
La diferencia entre uno y otro es que el C++ va a quedarse en un bucle infinito.
Y pusiste:
while ( tecla)
{
case 1 :
._.
En línea
Meta
Buenas:
#include <iostream>
#include <fstream>
#include <Windows.h>
#include <stdio.h>
#include "SerialClass.h"
using namespace std;
void main( )
{
// Título de la ventana
SetConsoleTitle( "Control Led Arduino." ) ;
// Puerto serie.
Serial* Puerto = new Serial( "COM4" ) ;
// Comandos para Arduino.
char Luz_ON[ ] = "Luz_ON" ; // Envía "Luz_ON" al puerto serie.
char Luz_OFF[ ] = "Luz_OFF" ;
char lectura[ 50 ] = "\0 " ; // Guardan datos de entrada del puerto.
int tecla; // Guarda las teclas pulsadas.
cout << "Introduzca la opcion deseada: " << endl << endl;
do
{
cin >> tecla; // Aquí introduces un número, el 1 o el 2.
while ( tecla)
{
case 1 :
// Encener luz.
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".
break ;
case 2 :
// Apagar luz.
cout << "Enviando: " << Luz_OFF << endl;
Puerto- > WriteData( Luz_OFF, sizeof ( Luz_OFF) - 1 ) ;
break ;
default : // Si haz pulsado otro número distinto del 1 y 2, muestra
cout << "Puse del 1 al 2." ; // este mensaje.
}
} while ( tecla ! = 0 ) ;
while ( true ) {
int n = Puerto- > ReadData( lectura, 49 ) ;
if ( n > 0 ) {
lectura[ n + 1 ] = '\0 ' ;
break ;
}
Sleep( 1 ) ;
}
}
Como no se como se llaman las cosas en C++, ya me atasqué. En C# funciona todo bien.
Ahora si necesito ayuda bien ayuda para sacar esto de una vez. A parte que tengo otro proyecto en mente con lo mismo pero en MFC C++.
Saludos.
En línea
ivancea96
Desconectado
Mensajes: 3.412
ASMático
Parecido sí, pero de forma incorrecta:
En C# tienes esto:
do
{
tecla = Console. ReadKey ( true ) . Key ; // Espera pulsación de teclas.
En C++ tienes esto otro:
cin >> tecla; // Aquí introduces un número, el 1 o el 2.
do
{
La diferencia entre uno y otro es que el C++ va a quedarse en un bucle infinito.
Y pusiste:
while ( tecla)
{
case 1 :
._.
Línea 29.
while ( tecla)
No es while, es switch.
En línea
Mensajes similares
Asunto
Iniciado por
Respuestas
Vistas
Último mensaje
Adaptador de puerto de serie a ps2?
Electrónica
jaciga
1
3,935
18 Abril 2005, 11:38 am
por + enrique ZP
manejo puerto serie
Programación Visual Basic
rulodlb
4
2,211
12 Noviembre 2005, 13:57 pm
por rulodlb
Ejercicio del puerto SERIE
Electrónica
renga73
1
2,579
17 Julio 2006, 07:46 am
por D1e6o!
Puerto serie con C#
.NET (C#, VB.NET, ASP)
Meta
0
8,480
6 Agosto 2008, 18:43 pm
por Meta
Puerto serie con F#
.NET (C#, VB.NET, ASP)
Meta
4
3,923
9 Diciembre 2015, 10:39 am
por Meta