elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Puerto serie C++. Mejorar el programa.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] 3 4 5 6 7 8 Ir Abajo Respuesta Imprimir
Autor Tema: Puerto serie C++. Mejorar el programa.  (Leído 27,889 veces)
ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #10 en: 18 Marzo 2017, 01:24 am »

Para empezar, es interesante saber qué hace exactamente ReadData: Retorna el número de caracteres leídos (y -1 si hubo un error o si leyó 0 caracteres). Dicho esto, ten en cuenta que las cadenas en C++ no son como en C#. De esos 50 caracteres, si solo lees 10, quedarán 40 como basura. Para evitar leerlos, basta poner un '\0' en el undécimo caracter:

Código
  1. int n = Puerto->ReadData(lectura, 49);
  2. lectura[n + 1] = '\0';

Eso en primer lugar. Luego, si el retorno de ReadData es -1, no deberías mostrar el Recibido (deberías esperar primero a que haya bytes para leer, pues no tienen por qué trabajar a la vez el Arduino y el PC (viene siendo como sincronizar varios threads, vaya))

Y bueno, hecho eso, a ver qué problemas te da.


En línea

Meta


Desconectado Desconectado

Mensajes: 3.499



Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #11 en: 18 Marzo 2017, 01:47 am »

Hola:

Enviar me envia todo bien, Arduino lo lee.

Recibir, seguí tu consejo, creo que no lo seguí como debería. C++ no lee nada. Seguro que hice algo pero muy mal.
Código
  1. #include <iostream>
  2. #include <fstream>
  3. #include <Windows.h>
  4. #include "SerialClass.h"
  5. using namespace std;
  6.  
  7. void main()
  8. {
  9. // Título de la ventana
  10. SetConsoleTitle("Control Led Arduino.");
  11.  
  12. // Puerto serie.
  13. Serial* Puerto = new Serial("COM4");
  14.  
  15. // Comandos para Arduino.
  16. char Luz_ON[] = "Luz_ON"; // Envía "Luz_ON" al puerto serie.
  17. char Luz_OFF[] = "Luz_OFF";
  18. char lectura[50] = "\0"; // Guardan datos de entrada del puerto.
  19.  
  20. int opc; // Guarda un 1 o 2 tipo entero queintroduces desde la consola.
  21.  
  22. while (Puerto->IsConnected())
  23. {
  24. cout << endl; // Dejamos un retorno.
  25. cout << "Introduzca la opcion deseada: " << endl << endl; // Muestra texto en pantalla.
  26.  
  27. cin >> opc; // Aquí introduces un número, el 1 o el 2.
  28.  
  29. switch (opc) // Espera recibir un 1 o un 2.
  30. {
  31. case 1:
  32. // Mensaje saludar.
  33. cout << "Enviando: " << Luz_ON << endl; // Muestra en pantalla textos.
  34. Puerto->WriteData(Luz_ON, sizeof(Luz_ON) - 1); // Envía al puerto el texto "Luz_ON".
  35. break;
  36.  
  37. case 2:
  38. // Mensaje saludar.
  39. cout << "Enviando: " << Luz_OFF << endl;
  40. Puerto->WriteData(Luz_OFF, sizeof(Luz_OFF) - 1);
  41. break;
  42.  
  43. default: // Si haz pulsado otro número distinto del 1 y 2, muestra
  44. cout << "Puse del 1 al 2."; // este mensaje.
  45. }
  46.  
  47. cout << endl; // Dejamos un retorno.
  48. int n = Puerto->ReadData(lectura, 49); // Recibe datos desde el puerto y lo almacena en la variable "lectura".
  49. lectura[n + 1] = '\0';
  50. cout << "Recibido: " << lectura << endl; // Muestra en pantalla el texto o datos almacenado en la variable "lectura".
  51. cout << "-------------------" << endl;
  52. }
  53. }

Lo que hace es, que si pulso uno, no lee nada. Si vuelvo a pulsar el 1, lee y lo indica bien. Eso si, por segunda vez.

Reinicio la aplicación. Pulso 1, no lee nada, ahora pulso el 2, me lee como si hubiera pulsado el 1.

Tiene que verse Luz OFF cuando pulso el 2.



:)


« Última modificación: 18 Marzo 2017, 01:54 am por Meta » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #12 en: 18 Marzo 2017, 02:16 am »

Pero, lo dicho. Desde que pulsas enter y escribes al arduino hasta que lees del arduino... ¿Crees que le da tiempo al Arduino a procesar y responder?
Vamos a comprobar que no sea eso. Coloca un Sleep(100); antes del ReadData.
En línea

Meta


Desconectado Desconectado

Mensajes: 3.499



Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #13 en: 18 Marzo 2017, 03:07 am »

Va, me olvidé lo del Sleep. Jajajajjaaja.

Por cierto. No me funciona en 100, si en 500.
Código
  1. cout << endl; // Dejamos un retorno.
  2. Sleep(500);
  3. int n = Puerto->ReadData(lectura, 49); // Recibe datos desde el puerto y lo almacena en la variable "lectura".
  4. lectura[n + 1] = '\0';
  5. cout << "Recibido: " << lectura << endl; // Muestra en pantalla el texto o datos almacenado en la variable "lectura".
  6. cout << "-------------------" << endl;
El Sleep a 150 funciona bien. Aunque hay gente que lo dejan a 500 pero se ve un poco lento. ;)

Código
  1. #include <iostream>
  2. #include <fstream>
  3. #include <Windows.h>
  4. #include "SerialClass.h"
  5. using namespace std;
  6.  
  7. void main()
  8. {
  9. // Título de la ventana
  10. SetConsoleTitle("Control Led Arduino.");
  11.  
  12. // Puerto serie.
  13. Serial* Puerto = new Serial("COM4");
  14.  
  15. // Comandos para Arduino.
  16. char Luz_ON[] = "Luz_ON"; // Envía "Luz_ON" al puerto serie.
  17. char Luz_OFF[] = "Luz_OFF";
  18. char lectura[50] = "\0"; // Guardan datos de entrada del puerto.
  19.  
  20. int opc; // Guarda un 1 o 2 tipo entero queintroduces desde la consola.
  21.  
  22. while (Puerto->IsConnected())
  23. {
  24. cout << endl; // Dejamos un retorno.
  25. cout << "Introduzca la opcion deseada: " << endl << endl; // Muestra texto en pantalla.
  26.  
  27. cin >> opc; // Aquí introduces un número, el 1 o el 2.
  28.  
  29. switch (opc) // Espera recibir un 1 o un 2.
  30. {
  31. case 1:
  32. // Mensaje saludar.
  33. cout << "Enviando: " << Luz_ON << endl; // Muestra en pantalla textos.
  34. Puerto->WriteData(Luz_ON, sizeof(Luz_ON) - 1); // Envía al puerto el texto "Luz_ON".
  35. break;
  36.  
  37. case 2:
  38. // Mensaje saludar.
  39. cout << "Enviando: " << Luz_OFF << endl;
  40. Puerto->WriteData(Luz_OFF, sizeof(Luz_OFF) - 1);
  41. break;
  42.  
  43. default: // Si haz pulsado otro número distinto del 1 y 2, muestra
  44. cout << "Puse del 1 al 2."; // este mensaje.
  45. }
  46.  
  47. cout << endl; // Dejamos un retorno.
  48. Sleep(150);
  49. int n = Puerto->ReadData(lectura, 49); // Recibe datos desde el puerto y lo almacena en la variable "lectura".
  50. lectura[n + 1] = '\0';
  51. cout << "Recibido: " << lectura << endl; // Muestra en pantalla el texto o datos almacenado en la variable "lectura".
  52. cout << "-------------------" << endl;
  53. }
  54. }

Por lo que se ve, ahora toca lo del botón. He hace esto y no devuelve nada.


Código de ahora C++:
Código
  1. #include <iostream>
  2. #include <fstream>
  3. #include <Windows.h>
  4. #include "SerialClass.h"
  5. using namespace std;
  6.  
  7. void main()
  8. {
  9. // Título de la ventana.
  10. SetConsoleTitle("Control Led 13 de Arduino UNO y saludos.");
  11.  
  12. // Nombre del puerto selecconado.
  13. Serial* Puerto = new Serial("COM4");
  14.  
  15. // Comandos para Arduino.
  16. char Luz_ON[] = "Luz_ON"; // Envía "Luz_ON" al puerto serie.
  17. char Luz_OFF[] = "Luz_OFF";
  18. char lectura[50] = "\0"; // Guardan datos de entrada del puerto.
  19.  
  20. // Mostrar texto en pantalla.
  21. cout << "Pulse letra 'A' para endender Led y 'B' para apagar: " << endl;
  22.  
  23. while (Puerto->IsConnected())
  24. {
  25. // Tecla 'A' pulsada
  26. if (GetAsyncKeyState('A') & 0x8000)
  27. {
  28. // Encener luz.
  29. cout << "Enviando: " << Luz_ON << endl; // Muestra en pantalla textos.
  30. Puerto->WriteData(Luz_ON, sizeof(Luz_ON) - 1); // Envía al puerto el texto "Luz_ON".
  31. }
  32.  
  33. // Tecla 'B' pulsada
  34. if (GetAsyncKeyState('B') & 0x8000)
  35. {
  36. // Apagar luz.
  37. cout << "Enviando: " << Luz_OFF << endl;
  38. Puerto->WriteData(Luz_OFF, sizeof(Luz_OFF) - 1);
  39. }
  40. }
  41.  
  42. cout << endl; // Dejamos un retorno.
  43. Sleep(500); // Funciona a 150 para asegurarme en estas pruebas lo dejo a 500 por ahora.
  44. int n = Puerto->ReadData(lectura, 49); // Recibe datos desde el puerto y lo almacena en la variable "lectura".
  45. lectura[n + 1] = '\0';
  46. cout << "Recibido: " << lectura << endl; // Muestra en pantalla el texto o datos almacenado en la variable "lectura".
  47. cout << "-------------------" << endl;
  48. }

Saludos.
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #14 en: 18 Marzo 2017, 13:01 pm »

Bien. De todos modos, un Sleep es un parche para testear, pero no es correcto. Lo que quieres no es esperar 500 milisegundos; lo que quieres es esperar hasta que el Arduino te contexte (o si tarda mucho, poner un timeout, pero esto ya más adelante).
Podrías hacer un while hasta recibir la respuesta completa del Arduino. Un while con un Sleep(1) si tal, para no sobrecargar. Y en el while, pues eso, leer hasta recibirlo todo.
En línea

Meta


Desconectado Desconectado

Mensajes: 3.499



Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #15 en: 18 Marzo 2017, 17:58 pm »

Buenas:

Sleep(1) como que no. ;)

Código
  1. #include <iostream>
  2. #include <fstream>
  3. #include <Windows.h>
  4. #include "SerialClass.h"
  5. using namespace std;
  6.  
  7. void main()
  8. {
  9. // Título de la ventana
  10. SetConsoleTitle("Control Led Arduino.");
  11.  
  12. // Puerto serie.
  13. Serial* Puerto = new Serial("COM4");
  14.  
  15. // Comandos para Arduino.
  16. char Luz_ON[] = "Luz_ON"; // Envía "Luz_ON" al puerto serie.
  17. char Luz_OFF[] = "Luz_OFF";
  18. char lectura[50] = "\0"; // Guardan datos de entrada del puerto.
  19.  
  20. int opc; // Guarda un 1 o 2 tipo entero queintroduces desde la consola.
  21. while (1)
  22. {
  23. while (Puerto->IsConnected())
  24. {
  25. cout << endl; // Dejamos un retorno.
  26. cout << "Introduzca la opcion deseada: " << endl << endl; // Muestra texto en pantalla.
  27.  
  28. cin >> opc; // Aquí introduces un número, el 1 o el 2.
  29.  
  30. switch (opc) // Espera recibir un 1 o un 2.
  31. {
  32. case 1:
  33. // Encener luz.
  34. cout << "Enviando: " << Luz_ON << endl; // Muestra en pantalla textos.
  35. Puerto->WriteData(Luz_ON, sizeof(Luz_ON) - 1); // Envía al puerto el texto "Luz_ON".
  36. break;
  37.  
  38. case 2:
  39. // Apagar luz.
  40. cout << "Enviando: " << Luz_OFF << endl;
  41. Puerto->WriteData(Luz_OFF, sizeof(Luz_OFF) - 1);
  42. break;
  43.  
  44. default: // Si haz pulsado otro número distinto del 1 y 2, muestra
  45. cout << "Puse del 1 al 2."; // este mensaje.
  46. }
  47.  
  48.  
  49. cout << endl; // Dejamos un retorno.
  50. Sleep(500);
  51. int n = Puerto->ReadData(lectura, 49); // Recibe datos desde el puerto y lo almacena en la variable "lectura".
  52. lectura[n + 1] = '\0';
  53. cout << "Recibido: " << lectura << endl; // Muestra en pantalla el texto o datos almacenado en la variable "lectura".
  54. cout << "-------------------" << endl;
  55. }
  56. }
  57. }

Acordarse que Arduino tiene un botón, si lo pulso, envía un ON o un OFF. Por ahora no me aparece en pantalla. C++ lo ignora. Pero nos estamos centrando en que si envío un 1 o un 2, responde Arduino también.

;)
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #16 en: 18 Marzo 2017, 18:17 pm »

No. Hablo de un while a la hora de recibir datos. No sirve solo "enviar y luego recibir". En un protocolo, hay que asegurarse de que se completa la comunicación. Si tratas de leer datos del puerto y no recibes nada, hay un problema. El Arduino no es instantáneo, probablemente trabajará mucho más lento que tu PC. Hay que esperar los datos:

Código
  1. while(true){
  2.    int n = Puerto->ReadData(lectura, 49);
  3.    if(n > 0){
  4.        lectura[n + 1] = '\0';
  5.        break;
  6.    }
  7.    Sleep(1);
  8. }
  9. cout << "Recibido: " << lectura << endl;
  10. cout << "-------------------" << endl;
  11.  

Por ejemplo.
« Última modificación: 18 Marzo 2017, 21:05 pm por ivancea96 » En línea

Meta


Desconectado Desconectado

Mensajes: 3.499



Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #17 en: 18 Marzo 2017, 18:35 pm »

Funciona bien mientras ocurre una cosa rara.
Código
  1. #include <iostream>
  2. #include <fstream>
  3. #include <Windows.h>
  4. #include "SerialClass.h"
  5. using namespace std;
  6.  
  7. void main()
  8. {
  9. // Título de la ventana
  10. SetConsoleTitle("Control Led Arduino.");
  11.  
  12. // Puerto serie.
  13. Serial* Puerto = new Serial("COM4");
  14.  
  15. // Comandos para Arduino.
  16. char Luz_ON[] = "Luz_ON"; // Envía "Luz_ON" al puerto serie.
  17. char Luz_OFF[] = "Luz_OFF";
  18. char lectura[50] = "\0"; // Guardan datos de entrada del puerto.
  19.  
  20. int opc; // Guarda un 1 o 2 tipo entero queintroduces desde la consola.
  21.  
  22. while (Puerto->IsConnected())
  23. {
  24. cout << endl; // Dejamos un retorno.
  25. cout << "Introduzca la opcion deseada: " << endl << endl; // Muestra texto en pantalla.
  26.  
  27. cin >> opc; // Aquí introduces un número, el 1 o el 2.
  28.  
  29. switch (opc) // Espera recibir un 1 o un 2.
  30. {
  31. case 1:
  32. // Encener luz.
  33. cout << "Enviando: " << Luz_ON << endl; // Muestra en pantalla textos.
  34. Puerto->WriteData(Luz_ON, sizeof(Luz_ON) - 1); // Envía al puerto el texto "Luz_ON".
  35. break;
  36.  
  37. case 2:
  38. // Apagar luz.
  39. cout << "Enviando: " << Luz_OFF << endl;
  40. Puerto->WriteData(Luz_OFF, sizeof(Luz_OFF) - 1);
  41. break;
  42.  
  43. default: // Si haz pulsado otro número distinto del 1 y 2, muestra
  44. cout << "Puse del 1 al 2."; // este mensaje.
  45. }
  46.  
  47.  
  48. while (true) {
  49. int n = Puerto->ReadData(lectura, 49);
  50. if (n > 0) {
  51. lectura[n + 1] = '\0';
  52. break;
  53. }
  54. Sleep(1);
  55. }
  56. cout << "Recibido: " << lectura << endl;
  57. cout << "-------------------" << endl;
  58. }
  59.  
  60. }

Si pulso una tecla que no está en el Switch, se queda el programa bloqueado. Hablando de pulsar números, porque si pulsas letras se vuelve loco, ya que la variable de entrada es tipo entero, pero esto, ya es otra historia.

;)
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #18 en: 18 Marzo 2017, 21:09 pm »

¡Desde luego!
Si no envías nada al Arduino, intuyo que el Arduino, en principio, no le envía nada al PC. por tanto, se va a quedar esperando.
Everything as expected
Tendrás que cambiar el flujo del programa si quieres que eso no ocurra. Además, imagínate que agregas una opción que envía datos al Arduino pero no los recibe. ¿Para qué esperar la salida del Arduino?
En fin, eso ya no es un error, solo un flujo incorrecto. Depende de cómo quieras ampliar el programa, modifícalo como más te convenga.
En línea

Meta


Desconectado Desconectado

Mensajes: 3.499



Ver Perfil WWW
Re: Puerto serie C++. Mejorar el programa.
« Respuesta #19 en: 19 Marzo 2017, 01:01 am »

Hola:

El programa que quiero es:

1. Si pulso un número 1 o un 2 en C++, envía un mensaje a Aduino, luego Arduino le devuelve un mensaje.

2. Si pulso otro número que no está en el Switch Case, te salta elmensaje Default inficando que solo hay dos opciones para pulsar, tecla 1 y 2.

3. Si no se pulsa nada desde C++, Arduino tiene un botón, que al pulsarlo, envía mensajes llamado, ON o un OFF, C++ debe leer.

Por eso en C++ Win32 me cuesta mucho, en .net de C++ del CLI no cuesta tanto, más fácil pero no tiene ejecutable nativo, el Win32 si. Hay ventajas enuno y en la otra. ;)

Saludos.
En línea

Páginas: 1 [2] 3 4 5 6 7 8 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Adaptador de puerto de serie a ps2?
Electrónica
jaciga 1 3,935 Último mensaje 18 Abril 2005, 11:38 am
por + enrique ZP
manejo puerto serie
Programación Visual Basic
rulodlb 4 2,211 Último mensaje 12 Noviembre 2005, 13:57 pm
por rulodlb
Ejercicio del puerto SERIE
Electrónica
renga73 1 2,578 Último mensaje 17 Julio 2006, 07:46 am
por D1e6o!
Puerto serie con C#
.NET (C#, VB.NET, ASP)
Meta 0 8,480 Último mensaje 6 Agosto 2008, 18:43 pm
por Meta
Puerto serie con F#
.NET (C#, VB.NET, ASP)
Meta 4 3,921 Último mensaje 9 Diciembre 2015, 10:39 am
por Meta
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines