Pasar el código de consola a MFC

Iniciado por Meta, 4 Febrero 2016, 21:43 PM

0 Miembros y 1 Visitante están viendo este tema.

Meta

Hola:

Tengo un código que encontré sobre el puerto serie, recibir y enviar datos hechos en C++.
Código (cpp) [Seleccionar]
// Comunicación a través del puerto serie
// usando el API de Windows
// Modo consola.
// (C) Enero de 2013, Salvador Pozo Coronado
// Con Clase: http://www.conclase.net
// salvador@conclase.net

#include <iostream>
#include <cstring>
#include <windows.h>

using namespace std;

// Tipos de datos:
typedef struct
{
    char Puerto[5];
    int Baudios;
    int BitsDatos;
    int BitsStop;
    char Paridad[25];
} tipoOpciones;

bool ocupado;
// Prototipos:
HANDLE InicioComunicacion(tipoOpciones*);
bool FinComunicacion(HANDLE);
DWORD Hilo(LPDWORD lpdwParam);
void EscribirSerie(HANDLE, char *);

int main(int argc, char *argv[])
{
    bool salir=false;
    DWORD id;
    char cad[80];
    tipoOpciones Ops;         // Opciones
    HANDLE idComDev;
    HANDLE hHilo;             // Hilo del puerto serie

    ocupado = true;
    // Inicializar opciones del puerto serie:
    strcpy(Ops.Puerto, "COM4");
    Ops.Baudios = 115200;
    Ops.BitsDatos = 8;
    Ops.BitsStop = 2;
    strcpy(Ops.Paridad, "Sin paridad");

    // No se ha establecido comunicación:
    idComDev = InicioComunicacion(&Ops);
    if(idComDev == INVALID_HANDLE_VALUE) {
        cout << "Inicialización puerto serie" << endl;
        cout << "ERROR: No se puede acceder al puerto serie." << endl;
        return 1;
    }
    // Lanzar hilo de lectura del puerto serie:
    hHilo = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Hilo, (LPDWORD)&idComDev, 0, &id);
    if(!hHilo) cout << "Error" << endl;
    // Bucle principal:
    ocupado = false;
    while(!salir) {
        // Leer un comando:
        cin.getline(cad, 80);
        // Si es "salir", abandonar el bucle:
        if(!strcmp(cad, "salir")) salir = true;
        else {
            // Si no, enviar cadena por el puerto serie:
            strcat(cad, "\r");
            EscribirSerie(idComDev, cad);
        }
    }
    // Liberar hilo:
    CloseHandle(hHilo);
    // Liberar puerto serie:
    FinComunicacion(idComDev);
    return 0;
}

// Iniciar el puerto serie:
HANDLE InicioComunicacion(tipoOpciones *Ops)
{
    bool fSuccess;
    HANDLE idComDev;
    DCB dcb;                  // Puerto serie

    // Abrir el fichero asociado al puerto:
    idComDev = CreateFile(Ops->Puerto, GENERIC_READ | GENERIC_WRITE,
        0, NULL, OPEN_EXISTING, 0, NULL);
    if(idComDev == INVALID_HANDLE_VALUE) {
        cout << "ERROR: CreateFile. Inicialización puerto serie" << endl;
        return INVALID_HANDLE_VALUE;
    }
    PurgeComm(idComDev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

    // Leer estructura de control del puerto serie, cdb:
    fSuccess = GetCommState(idComDev, &dcb);
    if(!fSuccess) {
        cout << "ERROR: GetCommState. Inicialización puerto serie" << endl;
        // Cerrar el puerto, regresar con 0.
        CloseHandle(idComDev);
        return INVALID_HANDLE_VALUE;
    }

    // Modificar el dcb según las opciones definidas:
    dcb.BaudRate = Ops->Baudios;
    dcb.ByteSize = Ops->BitsDatos;

    if(!strcmp(Ops->Paridad, "Sin paridad")) dcb.Parity = NOPARITY;
    if(!strcmp(Ops->Paridad, "Paridad par")) dcb.Parity = EVENPARITY;
    if(!strcmp(Ops->Paridad, "Paridad impar")) dcb.Parity = ODDPARITY;

    switch(Ops->BitsStop) {
        case 1:
            dcb.StopBits = ONESTOPBIT;
            break;
        case 2:
            dcb.StopBits = TWOSTOPBITS;
            break;
    }

    // Modificar la estructura de control del puerto serie:
    fSuccess = SetCommState(idComDev, &dcb);
    if(!fSuccess) {
        cout << "ERROR: SetCommStatus. Inicialización puerto serie" << endl;
        // Cerrar el puerto, regresar con 0.
        CloseHandle(idComDev);
        return INVALID_HANDLE_VALUE;
    }

    //// ASIGNAR TIMOUTS!!!

    return idComDev;
}

// Finalizar comunicación por puerto serie:
bool FinComunicacion(HANDLE idComDev)
{
    // Cerrar el puerto serie:
    CloseHandle(idComDev);
    return true;
}

// Hilo de escucha del puerto serie:
DWORD Hilo(LPDWORD lpdwParam)
{
    DWORD leidos;
    COMSTAT cs;
    char *cad;
    DWORD dwCommEvent;
    HANDLE idComDev = *((HANDLE*)lpdwParam);

    if(!SetCommMask(idComDev, EV_RXCHAR)) {
        cout << "Error al iniciar captura de evento" << endl;
        return 0;
    }
    do {
        if(WaitCommEvent(idComDev, &dwCommEvent, NULL)) {
            SetCommMask(idComDev, EV_RXCHAR);
            while(ocupado);
            ocupado = true;
            if(dwCommEvent & EV_RXCHAR) {
                ClearCommError(idComDev, &leidos, &cs);
                leidos=0;
                cout << "Detectados " << cs.cbInQue << " caracteres" << endl;
                /* Leer buffer desde puerto serie */
                if(cs.cbInQue) {
                    cad = new char[cs.cbInQue+3]; // Caracteres en buffer, más retorno de línea, más nulo
                    ReadFile(idComDev, cad, cs.cbInQue, &leidos, NULL);
                    cad[leidos] = '\n'; // Terminar cadena con salto de línea y nulo
                    cad[leidos+1] = '\r';
                    cad[leidos+2] = 0;
                    cout << cad;
                    delete[] cad;
                }
            } else {
                cout << "Evento: EV_BREAK o EV_ERR" << endl;
                 ClearCommBreak(idComDev);
            }
            ocupado = false;
        } else {
            cout << "Error en WaitCommEvent" << endl;
            ClearCommError(idComDev, NULL, NULL);
        }
        Sleep(10);
    } while(true);
    return 0;
}

void EscribirSerie(HANDLE idComDev, char *buf)
{
    char oBuffer[256];  /* Buffer de salida */
    DWORD iBytesWritten;

    iBytesWritten = 0;
    strcpy(oBuffer, buf);
    while(ocupado);
    ocupado = true;
    WriteFile(idComDev, oBuffer, strlen(oBuffer), &iBytesWritten, NULL);
    ocupado = false;
}


Fuente:
http://articulos.conclase.net/?tema=comunicacion&art=serie&pag=000

Por supuesto, debo modificarlo. Creo una interfaz MFC del C++ bajo Visual Studio Community 2015 indicado en este documento a partir de la página 30.

En el MFC de Visual Studio, hay que incluir dos botones y un richTextBox.


Imagen, Arduino debe recibir datos desde el puerto serie y enviar que ha sido recibido.


Solo quiero que con MFC sea capaz de apagar y encender un Led, tal como lo hago con otro lenguaje, C#, Visual Basic pero este MFC de C++ me cuesta muchísimo.
[youtube=640,360]https://www.youtube.com/watch?v=Ra2PBfLFuHk[/youtube]

Si les pica la curiosidad, el código de Arduino es este.
/*
* Electrónica PIC.
*
* Ejemplo:
* Encender y apagar un Led con Arduino y Visual Studio 2015.
*/

int pinLed =  13;   // Declaramos la variable pin del Led.
char caracter;
String comando;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  pinMode(pinLed, OUTPUT);  // Inicializa el pin del Led 1 como salida.
  /* Voy leyendo carácter a carácter lo que se recibe por el canal
   *  serie (mientras llegue algún dato allí), y los voy concatenando
   *  uno tras otro en una cadena. En la práctica, si usamos el
   *  "Serial monitor" el bucle while acabará cuando pulsemos Enter.
   *  El delay es conveniente para no saturar el canal serie y que la
   *  concatenación se haga de forma ordenada.
   */
  while (Serial.available() > 0)
  {
    caracter= Serial.read();
    comando.concat(caracter);
    delay(10);
  }

  /* Unavez ya tengo la cadena "acabada", compruebo su valor y hago
   * que la placa Arduino reaccione según sea este. Aquí podríamos
   * hacer lo que quiesiéramos: si el comando es "tal", enciende
   * un Led, si es cual, mueve un motor... y así.
   */
  if (comando.equals("ON") == true)  // Led_ON.
  {
        digitalWrite(pinLed, HIGH); // Enciende el Led.
        Serial.println("Led 13 encendido.");
  }
       
  if (comando.equals("OFF") == true) // Led_OFF.
  {
        digitalWrite(pinLed, LOW); // Apaga el Led.
        Serial.println("Led 13 apagado.");
  }
 
  // Limpiamos la cadena para volver a recibir el siguiente comando.
  comando="";
}


En resumen,  a partir del código de C++ para consola, adaptarlo a modo Visual MFC C++, solo enviar ON y OFF y recibir datos de respuesta.

Espero resolver este problema de una vez. C++ me vuelve loco.

Un cordial saludos.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/