Autor
|
Tema: Puerto serie C++. Mejorar el programa. (Leído 28,002 veces)
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
El caso es que, este mismo código en C#, también dará problema. No es cosa del lenguaje, sinó de la lógica. Si tu switch va por el default, le estás obligando igualmente a leer datos del Arduino (que no tiene por qué haber).
Si lo que quieres es enviarle datos y leerlos a la vez, necesitarás threads.
|
|
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Con hilos se complica un poco. Debes estar seguro de no recibir y emitir al mismo tiempo.
Pero si el arduino solo contesta a los comandos que recibe en el mismo case se emite el comando y se espera la respuesta.
Otra forma sería emulando la forma de trabajar de un PLC: se mira si hay algo de comunicación externa; se controlan las entradas; se calcula lo que se deba, se escriben las salidas; se escriben las comunicaciones externas.
|
|
|
En línea
|
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
Con hilos se complica un poco. Debes estar seguro de no recibir y emitir al mismo tiempo.
Pero si el arduino solo contesta a los comandos que recibe en el mismo case se emite el comando y se espera la respuesta.
Otra forma sería emulando la forma de trabajar de un PLC: se mira si hay algo de comunicación externa; se controlan las entradas; se calcula lo que se deba, se escriben las salidas; se escriben las comunicaciones externas.
Uy uy, que catastrofista Realmente, utilizando GetAsyncKeyState() y 2 mutex (uno para la salida por consola y otro para el Serial), está sincronizado. O al menos lo estaría si el protocolo PC-Arduino fuera más preciso, vaya. Porque como escriba el PC al Arduino y el Arduino al PC a la vez, el PC se tomará lo del Arduino como respuesta xD
|
|
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Si fuera puerto serie puro se podrían usar las líneas CTS y RTS, pero al ser emulado no sé si existen.
|
|
|
En línea
|
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
O directamente, poniendole un "header" a los mensjaes: ~~ Arduino -> PC
<msg_type:1 byte>
(msg_type=1){ ~~ Botón pulsado <datos:string> } (msg_type=2){ ~~ Respuesta al PC <datos:string> }
|
|
|
En línea
|
|
|
|
Meta
|
Hola: Probando con C# se funciona la recepción de datos, en C++ con Win32 no tengo idea como se hace. using System; 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#"; // 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; // Detecta cualquier dato recibido. Puerto_serie .DataReceived += new SerialDataReceivedEventHandler (DataReceivedHandler ); Puerto_serie.Open(); // Abrir puerto. Console.WriteLine("Presione cualquier tecla para continuar..."); Console.WriteLine(); Console.ReadKey(); // Espera pulsar una tecla cualquiera. Puerto_serie.Close(); // Cierra el puerto serie. } private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; string indata = sp.ReadExisting(); // Almacena los datos recibidos en la variable tipo string. Console.WriteLine("Dato recibido desde Arduino: " + indata); // Muestra en pantalla los datos recibidos. } } }
Para enviar datos si el puerto en C# es así: byte[] mBuffer = Encoding.ASCII.GetBytes("Hola mundo"); serialPort1.Write(mBuffer, 0, mBuffer.Length)
En C# lo hago rápido, deja acabarlo por completo y luego haber si es posible traducirlo al C++. Sigo investigando...
|
|
|
En línea
|
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
El problema es la estructura del programa. Si te es más cómodo, hazlo en C#, y ya luego traduces.
De todos modos, trata de no usar handles. Maneja tú el flujo del programa. Sinó luego, al pasarlo a C++, va a ser más complicado.
|
|
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Claro que el evento te controla el puerto pero eso lo debes hacer a mano. Podrías crear un hilo que vaya monitorizando si el puerto ha recibido algo y te disparara una función, ese sería tu evento.
|
|
|
En línea
|
|
|
|
Meta
|
Hola: Viendo lo visto, no he digo capaz, al menos por ahora, hacer un menú con fundamento para que me salga en C#, sigo con ello en paralelo ha este por si acaso. Me centraré en que si pulsas una tecla, directamente envía datos al puerto serie. // Para crear conexión con los puertos COM1 - COM9. // Serial* Arduino = new Serial("COM7"); // Para crear conexión con los puertos COM10 en adelante. // Serial* Arduino = new Serial("\\\\.\\COM10"); #include <iostream> #include <fstream> #include <Windows.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 opc; // Guarda un 1 o 2 tipo entero queintroduces desde la consola. while (Puerto->IsConnected()) { cout << endl; // Dejamos un retorno. cout << "Introduzca la opcion deseada: " << endl << endl; // Muestra texto en pantalla. cin >> opc; // Aquí introduces un número, el 1 o el 2. switch (opc) // Espera recibir un 1 o un 2. { 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 (true) { int n = Puerto->ReadData(lectura, 49); if (n > 0) { lectura[n + 1] = '\0'; break; } Sleep(1); } cout << "Recibido: " << lectura << endl; cout << "-------------------" << endl; } }
Habías comentado algo así: // Tecla 'B' pulsada if (GetAsyncKeyState('B') & 0x8000) { // Apagar luz. cout << "Enviando: " << Luz_OFF << endl; Puerto->WriteData(Luz_OFF, sizeof(Luz_OFF) - 1); }
Pero no funcionaba, daba cosas raras. Me conformo lo de enviar datos al puerto serie y acto seguido responde desde Arduino, hasta ahí bien, solo falta pulsar una tecla, desde que detecta la tecla, a enviar datos, no que primero pulse una tecla, luego Enter para enviar datos como hasta ahora.
|
|
|
En línea
|
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
Pero no funcionaba, daba cosas raras. "Cosas raras" xD El problema de ponerlo directamente así, es que si pulsas una letra, mientras la tengas pulsada, va a ser true ese if, con lo que entrará muchas veces seguidas.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Adaptador de puerto de serie a ps2?
Electrónica
|
jaciga
|
1
|
3,938
|
18 Abril 2005, 11:38 am
por + enrique ZP
|
|
|
manejo puerto serie
Programación Visual Basic
|
rulodlb
|
4
|
2,217
|
12 Noviembre 2005, 13:57 pm
por rulodlb
|
|
|
Ejercicio del puerto SERIE
Electrónica
|
renga73
|
1
|
2,586
|
17 Julio 2006, 07:46 am
por D1e6o!
|
|
|
Puerto serie con C#
.NET (C#, VB.NET, ASP)
|
Meta
|
0
|
8,488
|
6 Agosto 2008, 18:43 pm
por Meta
|
|
|
Puerto serie con F#
.NET (C#, VB.NET, ASP)
|
Meta
|
4
|
3,940
|
9 Diciembre 2015, 10:39 am
por Meta
|
|