Click here to Skip to main content
15,883,938 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello Everybody!
I am new to Serial programming, And I have to make a programm that receives data from a microcontroler. The problem is that the number that it receives are a little diferent from the ones I sent. For example, i send 1 every 0.1, it receives and prints 1.. 10... 1... 10... How do I solve this?
Any hint would be helpful!

I used a timer to sincronize receiving events;

CODE:

[...]

C++
int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

//    CREATES WINDOW!


    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /
}



LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//Caso o botao1 seja apertado;//
int     gwtstat = 0;
int I;
char *  t = &textSaved[0];
char pcCommPort[50] = "COM4";
char SuceText[] = {"Connected"};
char stopedcon[]= {"Connection Stoped"};
char ErrorText[] = {"Error Connecting"};
char ConnectionError[] = {"Port Not Connected"};
int x[300]={0},y[300]={0},z[300]={0},v[300]={0};
int vetor1[500],vetor2[500];

/*--- Estrutura para quando pintar a tela ---*/
PAINTSTRUCT ps;
HDC         hdc;
TEXTMETRIC  tm;     //Decide o tamanho das letras
TCHAR       teste[]={"Exame:"};
/*--------------SERIAL------------------*/
int tx;
DWORD num;
byte in[2]={0};
/*-------------------------------------------*/


    switch (message)                  /* handle the messages */
    {
    case WM_CREATE:

        AddMenus(hwnd);//Adiciona Menus a janela

        TextBox = CreateWindow("EDIT",
                              "",
                              WS_BORDER | WS_CHILD | WS_VISIBLE,
                              10, 40,400,20,
                              hwnd,NULL,NULL,NULL);

        CreateWindow("BUTTON",
                     "SAVE",
                     WS_VISIBLE | WS_CHILD | WS_BORDER,
                     420, 40, 70, 20,
                     hwnd, (HMENU) 1, NULL, NULL);

        CreateWindow("BUTTON",
                     "START",
                     WS_VISIBLE | WS_CHILD | WS_BORDER,
                     420, 80, 70, 20,
                     hwnd, (HMENU) 2, NULL, NULL);

        CreateWindow("BUTTON",
                     "STOP",
                     WS_VISIBLE | WS_CHILD | WS_BORDER,
                     300, 80, 70, 20,
                     hwnd, (HMENU) 6, NULL, NULL);
                break;


    case WM_PAINT:
                hdc = BeginPaint(hwnd,&ps);
                FillRect(hdc,&ps.rcPaint,(HBRUSH)(COLOR_WINDOW+1)); 
                Rectangle(hdc,10,110,500,300);
                for (I=0;I<50;I++){
                    SetPixel(hdc,I,I,RGB(255,0,0));
                }
                TextOut(hdc,1,1,teste,strlen(teste));    
                EndPaint(hwnd,&ps);
                break;

    case WM_TIMER:
                // To do: invalidar apenas uma pequena regiao
                tx = ReadFile(hCom,&in,1,&num,NULL);
                printf("%x\t",(in[0]));
                 hdc = GetDC(hwnd);
                       SetPixel(hdc,i,in[0],RGB(255,0,0));
                       ReleaseDC(hwnd,hdc);
                i++;




                //InvalidateRect (hwnd, NULL, FALSE) ;
               /* for(i=0;i<1000;i){
                       hdc = GetDC(hwnd);
                       SetPixel(hdc,i,in[i],RGB(255,0,0));
                       ReleaseDC(hwnd,hdc);*/
                //}


                break;
    case WM_COMMAND:
        switch (LOWORD(wParam)){
            case BUTTON1:
                gwtstat = GetWindowText(TextBox,t, 20);
                ::MessageBox(hwnd,textSaved,textSaved,MB_OK);
                fopen("info.txt","a+");
                fwrite(teste,1,sizeof(teste),fp);
                break;

            case BUTTON2:
                hCom = CreateFile( pcCommPort,
                                GENERIC_READ | GENERIC_WRITE,
                                0,    // must be opened with exclusive-access
                                NULL, // no security attributes
                                OPEN_EXISTING, // must use OPEN_EXISTING
                                0,    // not overlapped I/O
                                NULL  // hTemplate must be NULL for comm devices
                    );


                if (hCom == INVALID_HANDLE_VALUE)
                {
                    ::MessageBox(hwnd,ConnectionError,ConnectionError,MB_OK);
                   return (1);
                }


               fSuccess = GetCommState(hCom, &dcb);

               if (!fSuccess)
               {
                    return (2);
               }

                dcb.BaudRate = CBR_9600;     // set the baud rate
                dcb.ByteSize = 8;             // data size, xmit, and rcv
                dcb.Parity = ODDPARITY;        // no parity bit
                dcb.StopBits = ONESTOPBIT;    // one stop bit

                fSuccess = SetCommState(hCom, &dcb);

                if (!fSuccess)
                {
                ::MessageBox(hwnd,ConnectionError,ConnectionError,MB_OK);
                  return (3);
                }
                ::MessageBox(hwnd,SuceText,SuceText,MB_OK);

                SetTimer(hwnd,1,0x1,NULL);
                /*
                if (tx == TRUE) {
                    printf("%d",in[0]);
                }
                else{
                    ::MessageBox(hwnd,ConnectionError,ConnectionError,MB_OK);
                }*/

                break;
            case IDM_FILE_NEW:
                Beep(100, 100);
                break;
            case IDM_FILE_OPEN:
                Beep(50, 100);
                break;
            case IDM_FILE_QUIT:
                SendMessage(hwnd,WM_CLOSE,0,0);
                break;
            case STOP:
                KillTimer(hwnd,1);
                if (CloseHandle(hCom)==0){
                ::MessageBox(hwnd,ErrorText,NULL,MB_OK);
                }
                else{
                ::MessageBox(hwnd,stopedcon,stopedcon,MB_OK);
                }
                break;
        }

    /*case WM_DESTROY:
            PostQuitMessage (0);       //send a WM_QUIT to the message queue
            KillTimer (hwnd, 1) ;
            break;*/

            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
            }

    return 0;
}
Posted
Updated 6-Sep-15 1:19am
v2
Comments
Sergey Alexandrovich Kryukov 13-Mar-15 16:56pm    
Why would you assume that the microcontroller should send back the same number? It just does what it does...
—SA

1 solution

Take a look at this line:

C++
tx = ReadFile(hCom,&in,1,&num,NULL);


tx is declared as int but ReadFile returns BOOL. Your code should check the call for success / failure.

num will have the number of characters read (eg. 0 or 1). Your code should check this before attempting to print characters from the "in" buffer.

Your code reads one character for each WM_TIMER. Your call to SetTimer specifies a delay of 1 ms but SetTimer's smallest delay is 10 ms so you will poll for characters 100 times per second. If the microcontroller sends characters faster than that (9600 baud can send 960 characters per second) - you will loose data.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644906%28v=vs.85%29.aspx[^]

Use SetCommTimeouts to control how long your program waits on each call to ReadFile.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa363437%28v=vs.85%29.aspx[^]

Use a larger buffer to read multiple characters to tolerate a burst of data from the microcontroller.

You may want to consider creating a separate thread to call CreateFile and call ReadFile in a loop to avoid blocking the UI.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900