none
Pasar este código de consola a visual MFC C++ RRS feed

  • Pregunta

  • Hola:

    Tengo un código que encontré sobre el puerto serie, recibir y enviar datos hechos en C++.
    Código
    1. // Comunicación a través del puerto serie
    2. // usando el API de Windows
    3. // Modo consola.
    4. // (C) Enero de 2013, Salvador Pozo Coronado
    5. // Con Clase: http://www.conclase.net
    6. // salvador@conclase.net
    7.  
    8. #include <iostream>
    9. #include <cstring>
    10. #include <windows.h>
    11.  
    12. using namespace std;
    13.  
    14. // Tipos de datos:
    15. typedef struct
    16. {
    17.    char Puerto[5];
    18.    int Baudios;
    19.    int BitsDatos;
    20.    int BitsStop;
    21.    char Paridad[25];
    22. } tipoOpciones;
    23.  
    24. bool ocupado;
    25. // Prototipos:
    26. HANDLE InicioComunicacion(tipoOpciones*);
    27. bool FinComunicacion(HANDLE);
    28. DWORD Hilo(LPDWORD lpdwParam);
    29. void EscribirSerie(HANDLE, char *);
    30.  
    31. int main(int argc, char *argv[])
    32. {
    33.    bool salir=false;
    34.    DWORD id;
    35.    char cad[80];
    36.    tipoOpciones Ops;         // Opciones
    37.    HANDLE idComDev;
    38.    HANDLE hHilo;             // Hilo del puerto serie
    39.  
    40.    ocupado = true;
    41.    // Inicializar opciones del puerto serie:
    42.    strcpy(Ops.Puerto, "COM4");
    43.    Ops.Baudios = 115200;
    44.    Ops.BitsDatos = 8;
    45.    Ops.BitsStop = 2;
    46.    strcpy(Ops.Paridad, "Sin paridad");
    47.  
    48.    // No se ha establecido comunicación:
    49.    idComDev = InicioComunicacion(&Ops);
    50.    if(idComDev == INVALID_HANDLE_VALUE) {
    51.        cout << "Inicialización puerto serie" << endl;
    52.        cout << "ERROR: No se puede acceder al puerto serie." << endl;
    53.        return 1;
    54.    }
    55.    // Lanzar hilo de lectura del puerto serie:
    56.    hHilo = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Hilo, (LPDWORD)&idComDev, 0, &id);
    57.    if(!hHilo) cout << "Error" << endl;
    58.    // Bucle principal:
    59.    ocupado = false;
    60.    while(!salir) {
    61.        // Leer un comando:
    62.        cin.getline(cad, 80);
    63.        // Si es "salir", abandonar el bucle:
    64.        if(!strcmp(cad, "salir")) salir = true;
    65.        else {
    66.            // Si no, enviar cadena por el puerto serie:
    67.            strcat(cad, "\r");
    68.            EscribirSerie(idComDev, cad);
    69.        }
    70.    }
    71.    // Liberar hilo:
    72.    CloseHandle(hHilo);
    73.    // Liberar puerto serie:
    74.    FinComunicacion(idComDev);
    75.    return 0;
    76. }
    77.  
    78. // Iniciar el puerto serie:
    79. HANDLE InicioComunicacion(tipoOpciones *Ops)
    80. {
    81.    bool fSuccess;
    82.    HANDLE idComDev;
    83.    DCB dcb;                  // Puerto serie
    84.  
    85.    // Abrir el fichero asociado al puerto:
    86.    idComDev = CreateFile(Ops->Puerto, GENERIC_READ | GENERIC_WRITE,
    87.        0, NULL, OPEN_EXISTING, 0, NULL);
    88.    if(idComDev == INVALID_HANDLE_VALUE) {
    89.        cout << "ERROR: CreateFile. Inicialización puerto serie" << endl;
    90.        return INVALID_HANDLE_VALUE;
    91.    }
    92.    PurgeComm(idComDev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
    93.  
    94.    // Leer estructura de control del puerto serie, cdb:
    95.    fSuccess = GetCommState(idComDev, &dcb);
    96.    if(!fSuccess) {
    97.        cout << "ERROR: GetCommState. Inicialización puerto serie" << endl;
    98.        // Cerrar el puerto, regresar con 0.
    99.        CloseHandle(idComDev);
    100.        return INVALID_HANDLE_VALUE;
    101.    }
    102.  
    103.    // Modificar el dcb según las opciones definidas:
    104.    dcb.BaudRate = Ops->Baudios;
    105.    dcb.ByteSize = Ops->BitsDatos;


    http://electronica-pic.blogspot.com

    jueves, 4 de febrero de 2016 20:49

Todas las respuestas

    1.  
    2.    if(!strcmp(Ops->Paridad, "Sin paridad")) dcb.Parity = NOPARITY;
    3.    if(!strcmp(Ops->Paridad, "Paridad par")) dcb.Parity = EVENPARITY;
    4.    if(!strcmp(Ops->Paridad, "Paridad impar")) dcb.Parity = ODDPARITY;
    5.  
    6.    switch(Ops->BitsStop) {
    7.        case 1:
    8.            dcb.StopBits = ONESTOPBIT;
    9.            break;
    10.        case 2:
    11.            dcb.StopBits = TWOSTOPBITS;
    12.            break;
    13.    }
    14.  
    15.    // Modificar la estructura de control del puerto serie:
    16.    fSuccess = SetCommState(idComDev, &dcb);
    17.    if(!fSuccess) {
    18.        cout << "ERROR: SetCommStatus. Inicialización puerto serie" << endl;
    19.        // Cerrar el puerto, regresar con 0.
    20.        CloseHandle(idComDev);
    21.        return INVALID_HANDLE_VALUE;
    22.    }
    23.  
    24.    //// ASIGNAR TIMOUTS!!!
    25.  
    26.    return idComDev;
    27. }
    28.  
    29. // Finalizar comunicación por puerto serie:
    30. bool FinComunicacion(HANDLE idComDev)
    31. {
    32.    // Cerrar el puerto serie:
    33.    CloseHandle(idComDev);
    34.    return true;
    35. }
    36.  
    37. // Hilo de escucha del puerto serie:
    38. DWORD Hilo(LPDWORD lpdwParam)
    39. {
    40.    DWORD leidos;
    41.    COMSTAT cs;
    42.    char *cad;
    43.    DWORD dwCommEvent;
    44.    HANDLE idComDev = *((HANDLE*)lpdwParam);
    45.  
    46.    if(!SetCommMask(idComDev, EV_RXCHAR)) {
    47.        cout << "Error al iniciar captura de evento" << endl;
    48.        return 0;
    49.    }
    50.    do {
    51.        if(WaitCommEvent(idComDev, &dwCommEvent, NULL)) {
    52.            SetCommMask(idComDev, EV_RXCHAR);
    53.            while(ocupado);
    54.            ocupado = true;
    55.            if(dwCommEvent & EV_RXCHAR) {
    56.                ClearCommError(idComDev, &leidos, &cs);
    57.                leidos=0;
    58.                cout << "Detectados " << cs.cbInQue << " caracteres" << endl;
    59.                /* Leer buffer desde puerto serie */
    60.                if(cs.cbInQue) {
    61.                    cad = new char[cs.cbInQue+3]; // Caracteres en buffer, más retorno de línea, más nulo
    62.                    ReadFile(idComDev, cad, cs.cbInQue, &leidos, NULL);
    63.                    cad[leidos] = '\n'; // Terminar cadena con salto de línea y nulo
    64.                    cad[leidos+1] = '\r';
    65.                    cad[leidos+2] = 0;
    66.                    cout << cad;
    67.                    delete[] cad;
    68.                }
    69.            } else {
    70.                cout << "Evento: EV_BREAK o EV_ERR" << endl;
    71.                 ClearCommBreak(idComDev);
    72.            }
    73.            ocupado = false;
    74.        } else {
    75.            cout << "Error en WaitCommEvent" << endl;
    76.            ClearCommError(idComDev, NULL, NULL);
    77.        }
    78.        Sleep(10);
    79.    } while(true);
    80.    return 0;
    81. }
    82.  
    83. void EscribirSerie(HANDLE idComDev, char *buf)
    84. {
    85.    char oBuffer[256];  /* Buffer de salida */
    86.    DWORD iBytesWritten;
    87.  
    88.    iBytesWritten = 0;
    89.    strcpy(oBuffer, buf);
    90.    while(ocupado);
    91.    ocupado = true;
    92.    WriteFile(idComDev, oBuffer, strlen(oBuffer), &iBytesWritten, NULL);
    93.    ocupado = false;
    94. }

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

    http://electronica-pic.blogspot.com

    jueves, 4 de febrero de 2016 20:50
  • 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.


    Si les pica la curiosidad, el código de Arduino es este.
    Código
    1. /*
    2.  * Electrónica PIC.
    3.  *
    4.  * Ejemplo:
    5.  * Encender y apagar un Led con Arduino y Visual Studio 2015.
    6.  */
    7.  
    8. int pinLed =  13;   // Declaramos la variable pin del Led.
    9. char caracter;
    10. String comando;
    11.  
    12. void setup()
    13. {
    14.  Serial.begin(9600);
    15. }
    16.  
    17. void loop()
    18. {
    19.  pinMode(pinLed, OUTPUT);  // Inicializa el pin del Led 1 como salida.
    20.  /* Voy leyendo carácter a carácter lo que se recibe por el canal
    21.    *  serie (mientras llegue algún dato allí), y los voy concatenando
    22.    *  uno tras otro en una cadena. En la práctica, si usamos el
    23.    *  "Serial monitor" el bucle while acabará cuando pulsemos Enter.
    24.    *  El delay es conveniente para no saturar el canal serie y que la
    25.    *  concatenación se haga de forma ordenada.
    26.    */
    27.  while (Serial.available() > 0)
    28.  {
    29.    caracter= Serial.read();
    30.    comando.concat(caracter);
    31.    delay(10);
    32.  }
    33.  
    34.  /* Unavez ya tengo la cadena "acabada", compruebo su valor y hago
    35.    * que la placa Arduino reaccione según sea este. Aquí podríamos
    36.    * hacer lo que quiesiéramos: si el comando es "tal", enciende
    37.    * un Led, si es cual, mueve un motor... y así.
    38.    */
    39.  if (comando.equals("ON") == true)  // Led_ON.
    40.  {
    41.        digitalWrite(pinLed, HIGH); // Enciende el Led.
    42.        Serial.println("Led 13 encendido.");
    43.  }
    44.  
    45.  if (comando.equals("OFF") == true) // Led_OFF.
    46.  {
    47.        digitalWrite(pinLed, LOW); // Apaga el Led.
    48.        Serial.println("Led 13 apagado.");
    49.  }
    50.  
    51.  // Limpiamos la cadena para volver a recibir el siguiente comando.
    52.  comando="";
    53. }

    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.

    http://electronica-pic.blogspot.com

    jueves, 4 de febrero de 2016 20:50