Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. SetTimer() in Serial Comm Program Question

SetTimer() in Serial Comm Program Question

Scheduled Pinned Locked Moved C / C++ / MFC
questionc++help
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    CNewbie
    wrote on last edited by
    #1

    Question on How SetTimer() Works: When the Timer goes off and it calls the OnTimer() function, does it wait until that function ends and the program returns to the OS before the Timer starts its countdown again or does it automatically restart the countdown once the OnTimer() function is called? My Reason for asking is this: I made a Multithreaded MFC serial communication program where the flow of data is continuous. Thus the way I have it is I use an Infinite loop of (Read data, do something with data and loopback to read more data), however this causes the cpu time to be completely used (99-100%). Now since the program is much faster then the flow of data what I want to do is: Read data, do something with it, then return to the OS then go back to the read routine and do it again so the cpu is used as minimally as possible. This is where my question comes in: How could I go about being able to recall the read function once I return to the OS. As per my first question I was thinking of using SetTimer() but I dont know if it is the best possible solution to the problem. Maybe some type of event could work, but I dont think it could be monitored if the program control is with the OS. Does anyone have any advice or answers to my 2 questions? Thanks

    L J 2 Replies Last reply
    0
    • C CNewbie

      Question on How SetTimer() Works: When the Timer goes off and it calls the OnTimer() function, does it wait until that function ends and the program returns to the OS before the Timer starts its countdown again or does it automatically restart the countdown once the OnTimer() function is called? My Reason for asking is this: I made a Multithreaded MFC serial communication program where the flow of data is continuous. Thus the way I have it is I use an Infinite loop of (Read data, do something with data and loopback to read more data), however this causes the cpu time to be completely used (99-100%). Now since the program is much faster then the flow of data what I want to do is: Read data, do something with it, then return to the OS then go back to the read routine and do it again so the cpu is used as minimally as possible. This is where my question comes in: How could I go about being able to recall the read function once I return to the OS. As per my first question I was thinking of using SetTimer() but I dont know if it is the best possible solution to the problem. Maybe some type of event could work, but I dont think it could be monitored if the program control is with the OS. Does anyone have any advice or answers to my 2 questions? Thanks

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      A simple test - put an AfxMessageBox() in the OnTimer() funtion, set the timer period to say 3 seconds, let the message box stay open for say 2 seconds. Elaine :rose: The tigress is here :-D

      1 Reply Last reply
      0
      • C CNewbie

        Question on How SetTimer() Works: When the Timer goes off and it calls the OnTimer() function, does it wait until that function ends and the program returns to the OS before the Timer starts its countdown again or does it automatically restart the countdown once the OnTimer() function is called? My Reason for asking is this: I made a Multithreaded MFC serial communication program where the flow of data is continuous. Thus the way I have it is I use an Infinite loop of (Read data, do something with data and loopback to read more data), however this causes the cpu time to be completely used (99-100%). Now since the program is much faster then the flow of data what I want to do is: Read data, do something with it, then return to the OS then go back to the read routine and do it again so the cpu is used as minimally as possible. This is where my question comes in: How could I go about being able to recall the read function once I return to the OS. As per my first question I was thinking of using SetTimer() but I dont know if it is the best possible solution to the problem. Maybe some type of event could work, but I dont think it could be monitored if the program control is with the OS. Does anyone have any advice or answers to my 2 questions? Thanks

        J Offline
        J Offline
        John R Shaw
        wrote on last edited by
        #3

        ONTIMER: (this all most application need) Since the the data received (using Windows serial communication) is received/sent in the background, you can use the SetTimer() function and just check if any new data has arrived in your OnTimer() event function. How often you need to check depends on the size of the receive buffer you specified when you setup communication (See SetupComm()). To detemine if any data has been received just call ClearCommError(). MULTITHREADING: Of course you could use a seperate thread that uses shared data buffers, protected by critical sections so your threads will not step on each others toes. What I mean by shared buffers is one or more buffers you and the Rx thread both share, when you're reading from a buffer, the RX thread cann't write to it and when the RX thread is writing to it, you cann't read from it. Then all you need to do is calculate approximatly how long it should take to receive X-number of characters and go to sleep for that period of time in your RX thread; when the thread wakes up it then reads the data into the buffer and goes back to sleep (that takes care of the CPU usage problem). You could use two buffers so that the RX thread could be writing into one while you are reading the other one. OR you could use a ring buffer so that you can read from the tail end while the receiver is writing to the head end. (this can be a bit more tricky). The RX thread can inform you that new data has arrived by posting (not sending) a message back to your main thread or by setting an event flag that you must check for every now and then, either in an OnTimer() event function or in the main message loop. FINALY: That should be enough to help solve your problems. FYI: There are some articles at CP (CSerial) and in the MSDN library that use multiple threading for serial communication. GOOD LUCK! INTP "The more help VB provides VB programmers, the more miserable your life as a C++ programmer becomes." Andrew W. Troelsen

        C 1 Reply Last reply
        0
        • J John R Shaw

          ONTIMER: (this all most application need) Since the the data received (using Windows serial communication) is received/sent in the background, you can use the SetTimer() function and just check if any new data has arrived in your OnTimer() event function. How often you need to check depends on the size of the receive buffer you specified when you setup communication (See SetupComm()). To detemine if any data has been received just call ClearCommError(). MULTITHREADING: Of course you could use a seperate thread that uses shared data buffers, protected by critical sections so your threads will not step on each others toes. What I mean by shared buffers is one or more buffers you and the Rx thread both share, when you're reading from a buffer, the RX thread cann't write to it and when the RX thread is writing to it, you cann't read from it. Then all you need to do is calculate approximatly how long it should take to receive X-number of characters and go to sleep for that period of time in your RX thread; when the thread wakes up it then reads the data into the buffer and goes back to sleep (that takes care of the CPU usage problem). You could use two buffers so that the RX thread could be writing into one while you are reading the other one. OR you could use a ring buffer so that you can read from the tail end while the receiver is writing to the head end. (this can be a bit more tricky). The RX thread can inform you that new data has arrived by posting (not sending) a message back to your main thread or by setting an event flag that you must check for every now and then, either in an OnTimer() event function or in the main message loop. FINALY: That should be enough to help solve your problems. FYI: There are some articles at CP (CSerial) and in the MSDN library that use multiple threading for serial communication. GOOD LUCK! INTP "The more help VB provides VB programmers, the more miserable your life as a C++ programmer becomes." Andrew W. Troelsen

          C Offline
          C Offline
          CNewbie
          wrote on last edited by
          #4

          thank you for the detailed response. In my original post I failed to mention that I am using shared buffers and as you mentioned it is much better then using one buffer. I have been doing some debugging of the cpu hogging problem and it has come down to be either the infinite for loop that is causing it or the actual worker thread itself. I call the worker thread like this: AfxBeginThread(Read,this); Read() is a static menber function declared as: afx_msg static UINT Read(LPVOID param); As I was told this was how it was supposed to be declared. Here is the Read() function minus the background work: UINT CprogramDlg::Read(LPVOID param) { for( ;; ) {} return 0; } Reason I am not including the code within the "for" loop is because after testing I have concluded that even with just the code like this when the Read() function is called from AfxBeginThread() the cpu immediately shoots up to 99% and stays there. So from this I have to conclude that it is either the "infinite for loop" that is causing it or it is the actual thread call that is doing it. It was pointed out to me that an infinite loop in a worker thread "should not" cause the cpu usage to jump up completely like that, but I dont know how true that is. I just want to make sure that it is the infinite loop before I move onto fix the problem by using a timer. Thanks

          J 1 Reply Last reply
          0
          • C CNewbie

            thank you for the detailed response. In my original post I failed to mention that I am using shared buffers and as you mentioned it is much better then using one buffer. I have been doing some debugging of the cpu hogging problem and it has come down to be either the infinite for loop that is causing it or the actual worker thread itself. I call the worker thread like this: AfxBeginThread(Read,this); Read() is a static menber function declared as: afx_msg static UINT Read(LPVOID param); As I was told this was how it was supposed to be declared. Here is the Read() function minus the background work: UINT CprogramDlg::Read(LPVOID param) { for( ;; ) {} return 0; } Reason I am not including the code within the "for" loop is because after testing I have concluded that even with just the code like this when the Read() function is called from AfxBeginThread() the cpu immediately shoots up to 99% and stays there. So from this I have to conclude that it is either the "infinite for loop" that is causing it or it is the actual thread call that is doing it. It was pointed out to me that an infinite loop in a worker thread "should not" cause the cpu usage to jump up completely like that, but I dont know how true that is. I just want to make sure that it is the infinite loop before I move onto fix the problem by using a timer. Thanks

            J Offline
            J Offline
            John R Shaw
            wrote on last edited by
            #5

            The worker thread is causing the cpu usage problem, it must go to sleep part of the time if you want it to stop doing that. Even just using WaitCommEvent(...,EV_RXCHAR,...) inside your loop might reduce cpu usage (how much depends on baudrate). I would just use SetupComm(...,dwInQueue,dwOutQueue) and go to sleep for a short time, before reading the data from the rx-buffer. INTP "The more help VB provides VB programmers, the more miserable your life as a C++ programmer becomes." Andrew W. Troelsen

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups