Thread: RS232 (serial/comm) communication

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    85

    RS232 (serial/comm) communication

    Does anyone has around a working example of comunication via RS232? I have made a PIC-based device that I controlled via Hyperterminal, and now I want a standalone application for it.

    I couldn't find a working example anywhere. And when using windows API calls, my source file kept deleting itself, plus i got a circular reference in my object file.

    It should work on windowsXP and use modern functions (not some antiquated borland inpout functions). I'm using devc++ but I can adapt.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Just search these boards (and google) for "Serial Communications" etc...

    You could also read Serial Communications in Win32, but since your source files are deleting themselves, you may have bigger problems to deal with.

    gg

  3. #3
    Registered User
    Join Date
    Aug 2007
    Posts
    85
    I started everything in another project. Still got the circular reference, switched to code::blocks and it solved. Meh..

    Anyway. I've been searching for a few days now, and I haven't found anything of use. I've looked on this board, too, but all examples use old dos/borland functions. I've read the MSDN article, but it's not really helping me build even a demo app. So i'm basically looking for a class/function-set that will allow me to do something like open, read, close, buffer, etc. I really don't want to get any deeper than that into windows functions.

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    under linux this should be pretty easy: open the rs232 device file and work with it like with a regulary binary file (read, write, close). mabey you want to give it a try

  5. #5
    Registered User
    Join Date
    Aug 2007
    Posts
    11

    work with java

    If you are using java as your programming language the comm is the package for you to work
    easily with RS232 Serial communication port

  6. #6
    Registered User
    Join Date
    Aug 2007
    Posts
    85
    well, i'm under windows XD
    it would be an idea to try it under cygwin. Still, i'd prefer doing it with a wrapper around the API for speed.

    The device is a four channel scope with Analog-Digital converter, so I do care about speed

  7. #7

  8. #8
    Registered User
    Join Date
    Aug 2007
    Posts
    85
    Hey, thanks a ton, codeplug! That class works great!
    Do i need any other postquitmessage() or some deletion method for it? The exe keeps getting locked after it's terminated and I can't compile again without changing the output's file name.

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    If you just have a simple console app like the example in the linked post, then you only need to return from main() for you application to exit.

    You're having to change the EXE name each time means that the EXE is still running in the background. Until you get your exit strategy in place, you can kill the process manually by running "taskmgr" via Start -> Run.

    If you need further help with an exit strategy, you'll have to post some code.

    gg

  10. #10
    Registered User
    Join Date
    Aug 2007
    Posts
    85
    This is my current code.
    It waits for a number of ms, then it says how many samples it received

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    #include <string>
    #include <windows.h>
    #include <stdio.h>
    #include "SFile.h"
    
    
    using namespace std;
    vector<short int> buffer;
    DWORD start = 0;
    DWORD res = 0;
    
    bool Keypress(char &Key)
    {
        INPUT_RECORD Event;
        DWORD NumberOfEvents, EventsRead, EventCounter;
    
        GetNumberOfConsoleInputEvents(GetStdHandle(STD_INPUT_HANDLE), &NumberOfEvents);
    
        if (NumberOfEvents == 0)
            return false;
    
        for (EventCounter = 0; EventCounter < NumberOfEvents; EventCounter++)
        {
            PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &Event, 1, &EventsRead);
            if ((Event.EventType == KEY_EVENT) && ((Event.Event.KeyEvent.bKeyDown)))
            {
                ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &Event, 1, &EventsRead);
                Key = Event.Event.KeyEvent.wVirtualKeyCode;
                if (!(FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE))))
                    exit(0);
                return true;
            }
            else
                ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &Event, 1, &EventsRead);
        }
    
        return false;
    }
    
    
    int main() {
    
       SFile sf;
    
        // open COM1 at 115200, settings 8N1
        if (!sf.Open(1, 115200))
        {
            cerr << "Failed to open COM1, ec = " << GetLastError() << endl;
            system("pause");
            return 1;
        }//if
    
        sf.WriteByte(0xFF);
    
        // read a byte at a time and display it
        // (this should loop forever)
        BYTE b;
        char key = 0;
        while (sf.ReadByte(b))
        {
        if (Keypress(key))
        {
            if (key == VK_ESCAPE)
            {
                PostQuitMessage(0);
                Sleep(0);
                return 1;
            }
        }
            
        buffer.push_back ((short int)(b));
    
        if ( buffer.size() == 1) start = GetTickCount();
        if ( (GetTickCount() - start) > 1000 ) break;
        }//while
    
        cout << buffer.size() << " samples in " << (GetTickCount() - start) << " ms." << endl;
        
        int k;
        sf.Close();
    
        system("pause");
        PostQuitMessage(EXIT_SUCCESS);
        Sleep(0);
        return(EXIT_SUCCESS);
    
    
    
    }

  11. #11
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    By default, sf.ReadByte() will not return until a byte is read from the port. This behavior can be changed by calling SetReadTimeOut(). Here's a sample loop that reads a byte at a time while checking for a keystroke 4 times a second:
    Code:
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    #include <windows.h>
    #include "SFile.h"
    #include <conio.h>
    
    int ConsumeKeystroke()
    {
        if (_kbhit())
        {
            int k = _getch();
            if (k == 0 || k == 0xe0)
                return _getch();
            return k;
        }//while
    
        return 0;
    }//ConsumeKeystroke
    
    int main()
    {
        SFile sf;
    
        // open COM1 at 115200, settings 8N1
        if (!sf.Open(1, 115200))
        {
            cerr << "Failed to open COM1, ec = " << ::GetLastError() << endl;
            system("pause");
            return 1;
        }//if
    
        // this will allow us to check for a keypress 4 times a second
        sf.SetReadTimeOut(250);
    
        if (!sf.WriteByte(0xFF))
        {
            cerr << "Failed to write to port, ec = " << ::GetLastError() << endl;
            system("pause");
            return 1;
        }//if
    
        for (;;)
        {
            BYTE b;
            if (!sf.ReadByte(b))
            {
                DWORD le = ::GetLastError();
                if (le != ERROR_IO_PENDING)
                {
                    cout << "Error while reading from port - ec = " << le << endl;
                    system("pause");
                    return 1;
                }//if
            }//if
            else
            {
                cout << "Read a byte: 0x" << setfill('0') << setw(2)
                     << hex << int(b) << endl;
            }//else
    
            int k = ConsumeKeystroke();
            if (k == 'q' || k == 'Q' || k == 'e' || k == 'E' || k == VK_ESCAPE)
                break;
        }//for
    
        sf.Close();
    
        system("pause");
        return 0;
    }//main
    gg

  12. #12
    Registered User
    Join Date
    Aug 2007
    Posts
    85
    It's ok, since this is a test environment, and i'll always make sure i get the bytes.
    my problem is not waiting for the bytes - since they always come. my problem is that the program doesn't end in a "right' way for the windows kernel, although i'm doing a PostQuitMessage.

    thanks for the example, but it behaves the same - permission denied after the first compile.

  13. #13
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    The code I posted exits cleanly if you hit Q, E, or ESC - followed by another keypress due to the system("pause") call.

    PostQuitMessage() is only useful if you have a message loop. Which these console applications do not have.

    gg

  14. #14
    Registered User
    Join Date
    Aug 2007
    Posts
    85
    Okay. Then, how can I make the program exit cleanly when it's done computing (i.e. by itself) ?

  15. #15
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Return from main().

    Remove system("pause") calls if you want it to exit cleanly without any user interaction.

    gg
    Last edited by Codeplug; 09-06-2007 at 05:48 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. codes for com port Rs232 in serial communication
    By justinwandji in forum C++ Programming
    Replies: 1
    Last Post: 06-05-2009, 01:33 AM
  2. Unkown Hang
    By Bladactania in forum C Programming
    Replies: 31
    Last Post: 04-22-2009, 09:33 AM
  3. Communication using RS232 port
    By edesign in forum C Programming
    Replies: 27
    Last Post: 03-26-2008, 03:06 AM
  4. Looking for communication lib
    By BrownB in forum C Programming
    Replies: 3
    Last Post: 04-27-2005, 10:01 AM
  5. RS232 Communication in C++
    By Hankyaku in forum C++ Programming
    Replies: 2
    Last Post: 03-23-2003, 03:48 PM