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
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. SerialPort/Stress problem

SerialPort/Stress problem

Scheduled Pinned Locked Moved C#
beta-testinghelp
7 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.
  • S Offline
    S Offline
    Snowjim
    wrote on last edited by
    #1

    Hey! Intruduction: I am using Framework 2.0(beta 2) and the System.IO.Ports.SerialPort class to communicat with serialport/USB devices. I have built my serialport communication with Events, like this: #region Create Connection serialPort = new SerialPort(serialPortSettings.getPort, serialPortSettings.getBoudRate, serialPortSettings.getParity, serialPortSettings.getDataBits, serialPortSettings.getStopBit); serialPort.DtrEnable = true; serialPort.RtsEnable = true; serialPort.ReceivedBytesThreshold = 4; serialPort.Open(); #endregion serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_ReceivedEvent); SerialPort Settings that I use Baud rate: 115200 Data bits: 8 Parity: None Stop bit(s): 1 This is done by a special serialport thred, this to make sure that the main thread(the one that redraws the GUI and so on) not will be involved in the event firing of this serialport. In serialPort_ReceivedEvent you can finde the folowing code: lock (this) { if (RUNNING) { ThreadPool.QueueUserWorkItem(new WaitCallback(onDataReceived)); currentRunningThreads++; // keep track of amount of thread currently working } } This function will be fired as soon as 4 bytes(ReceivedBytesThreshold) have been written to the serialport. As you can see, it will place a work in the ThreadPool and then make the current thread available for next event. The onDataReceived looks like this. if (RUNNING) { lock (this) { if (serialPort.BytesToRead > 0) { string data = serialPort.ReadExisting(); if (data != null && data.Length > 0) { RemovePortHandlerRAW.Write(data); //writes data to file, just to have something to compare with RemovePortHandlerRAW.Flush(); data = toolHandler.costmizeString(data, timeStamp, showCR_LFOnIncomingData); streamHandler.writeData(data); //ourData if(SAVEDATATOFILE) rows = toolHandler.stringToArray(data); if (rows != null) { if (SAVEDATATOFILE)

    S 1 Reply Last reply
    0
    • S Snowjim

      Hey! Intruduction: I am using Framework 2.0(beta 2) and the System.IO.Ports.SerialPort class to communicat with serialport/USB devices. I have built my serialport communication with Events, like this: #region Create Connection serialPort = new SerialPort(serialPortSettings.getPort, serialPortSettings.getBoudRate, serialPortSettings.getParity, serialPortSettings.getDataBits, serialPortSettings.getStopBit); serialPort.DtrEnable = true; serialPort.RtsEnable = true; serialPort.ReceivedBytesThreshold = 4; serialPort.Open(); #endregion serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_ReceivedEvent); SerialPort Settings that I use Baud rate: 115200 Data bits: 8 Parity: None Stop bit(s): 1 This is done by a special serialport thred, this to make sure that the main thread(the one that redraws the GUI and so on) not will be involved in the event firing of this serialport. In serialPort_ReceivedEvent you can finde the folowing code: lock (this) { if (RUNNING) { ThreadPool.QueueUserWorkItem(new WaitCallback(onDataReceived)); currentRunningThreads++; // keep track of amount of thread currently working } } This function will be fired as soon as 4 bytes(ReceivedBytesThreshold) have been written to the serialport. As you can see, it will place a work in the ThreadPool and then make the current thread available for next event. The onDataReceived looks like this. if (RUNNING) { lock (this) { if (serialPort.BytesToRead > 0) { string data = serialPort.ReadExisting(); if (data != null && data.Length > 0) { RemovePortHandlerRAW.Write(data); //writes data to file, just to have something to compare with RemovePortHandlerRAW.Flush(); data = toolHandler.costmizeString(data, timeStamp, showCR_LFOnIncomingData); streamHandler.writeData(data); //ourData if(SAVEDATATOFILE) rows = toolHandler.stringToArray(data); if (rows != null) { if (SAVEDATATOFILE)

      S Offline
      S Offline
      S Senthil Kumar
      wrote on last edited by
      #2

      The problem is with you using ThreadPool threads to write to the file. I'm pretty sure you expect the contents of the file to be in the same order as you sent. But using threads to write to the file will surely result in data misordering. When you call ThreadPool.QueueUserWorkItem, the system assigns a thread to run the function. There is no guarantee that the function would complete before you get another serialPort_Received event. Imagine the case when the first thread has read the contents but before it writes to the file, there is another serialPort_Received event and that thread writes to the file first. Your file wouldn't have the contents in the right order then. I suspect that's why you're getting strange results when the CPU is busy. When the CPU is relatively idle, it probably schedules your threads in such a way that each DataReceived event occurs after the ThreadPool thread has completed. Regards Senthil _____________________________ My Blog | My Articles | WinMacro

      S 1 Reply Last reply
      0
      • S S Senthil Kumar

        The problem is with you using ThreadPool threads to write to the file. I'm pretty sure you expect the contents of the file to be in the same order as you sent. But using threads to write to the file will surely result in data misordering. When you call ThreadPool.QueueUserWorkItem, the system assigns a thread to run the function. There is no guarantee that the function would complete before you get another serialPort_Received event. Imagine the case when the first thread has read the contents but before it writes to the file, there is another serialPort_Received event and that thread writes to the file first. Your file wouldn't have the contents in the right order then. I suspect that's why you're getting strange results when the CPU is busy. When the CPU is relatively idle, it probably schedules your threads in such a way that each DataReceived event occurs after the ThreadPool thread has completed. Regards Senthil _____________________________ My Blog | My Articles | WinMacro

        S Offline
        S Offline
        Snowjim
        wrote on last edited by
        #3

        Yes i understand what you mean, but thats why i am using lock so there will hofully be a sort av queue that executes the threads in the right order? I have also tried to place the code that writes to file in the ReceivedEvent event direcly and take away the ThreadPool Thing. Like this: lock (this) { if (RUNNING) { FILEHANDLING CODE HERE //ThreadPool.QueueUserWorkItem(new WaitCallback(onDataReceived)); //currentRunningThreads++; // keep track of amount of thread currently working } } but this is not helping? I have as a mentioned, tried to switch from event to a Thread Loop, and then the data cant be read in wrong order. But this results in same dataloses as with event and Threadpool. If i understand you right, then the data will be in the file but on a diffrent place? The CompareIt program that i am using to compare files, will show if data is moved to other parts of the txt file. And in thes cases when i have lost data, there is simply data missing from the recived file(it also got a smaller size then it would have if its contained all the data). BestRegards SnowJim

        S 1 Reply Last reply
        0
        • S Snowjim

          Yes i understand what you mean, but thats why i am using lock so there will hofully be a sort av queue that executes the threads in the right order? I have also tried to place the code that writes to file in the ReceivedEvent event direcly and take away the ThreadPool Thing. Like this: lock (this) { if (RUNNING) { FILEHANDLING CODE HERE //ThreadPool.QueueUserWorkItem(new WaitCallback(onDataReceived)); //currentRunningThreads++; // keep track of amount of thread currently working } } but this is not helping? I have as a mentioned, tried to switch from event to a Thread Loop, and then the data cant be read in wrong order. But this results in same dataloses as with event and Threadpool. If i understand you right, then the data will be in the file but on a diffrent place? The CompareIt program that i am using to compare files, will show if data is moved to other parts of the txt file. And in thes cases when i have lost data, there is simply data missing from the recived file(it also got a smaller size then it would have if its contained all the data). BestRegards SnowJim

          S Offline
          S Offline
          S Senthil Kumar
          wrote on last edited by
          #4

          If that doesn't help, I'm not sure what the problem is. Are you sure you always get the ReceivedEvent in the first place? Also, are you sure there is nothing wrong with the code sending the messages and that it actually has sent the messages? Regards Senthil _____________________________ My Blog | My Articles | WinMacro

          S 1 Reply Last reply
          0
          • S S Senthil Kumar

            If that doesn't help, I'm not sure what the problem is. Are you sure you always get the ReceivedEvent in the first place? Also, are you sure there is nothing wrong with the code sending the messages and that it actually has sent the messages? Regards Senthil _____________________________ My Blog | My Articles | WinMacro

            S Offline
            S Offline
            Snowjim
            wrote on last edited by
            #5

            Even if i shold not get the event one time, the next time it will readExisting on port, so this shold not be a problem. And the sendingsoftware shold be working. I have used it in stress test of other serialport programs that i have downloaded, and there are no data lost? I dont eather know way it is losing data when i am moving around window? Cant u try det same thing? if you got a nullmodem cable? BestRegards SnowJim

            S 1 Reply Last reply
            0
            • S Snowjim

              Even if i shold not get the event one time, the next time it will readExisting on port, so this shold not be a problem. And the sendingsoftware shold be working. I have used it in stress test of other serialport programs that i have downloaded, and there are no data lost? I dont eather know way it is losing data when i am moving around window? Cant u try det same thing? if you got a nullmodem cable? BestRegards SnowJim

              S Offline
              S Offline
              Sebastian Schneider
              wrote on last edited by
              #6

              If you depend on the data arriving in the exact same order it was sent, there is no easy way other than using one (1) hand-crafted thread to "listen" on the serial port. Locking simply means that threads will not interfere with each other, it does not assure the order in which the threads will gain access. You COULD try and use a ResetEvent in the main "queue", which is then reset in the worker-thread. I still suggest that you try and design a single "listening worker" which should be written in a way that has it handle the events "one by one". That will cost you some speed, but is easy to understand and maintain. Cheers, Sebastian -- Contra vim mortem non est medicamen in hortem.

              S 1 Reply Last reply
              0
              • S Sebastian Schneider

                If you depend on the data arriving in the exact same order it was sent, there is no easy way other than using one (1) hand-crafted thread to "listen" on the serial port. Locking simply means that threads will not interfere with each other, it does not assure the order in which the threads will gain access. You COULD try and use a ResetEvent in the main "queue", which is then reset in the worker-thread. I still suggest that you try and design a single "listening worker" which should be written in a way that has it handle the events "one by one". That will cost you some speed, but is easy to understand and maintain. Cheers, Sebastian -- Contra vim mortem non est medicamen in hortem.

                S Offline
                S Offline
                Snowjim
                wrote on last edited by
                #7

                Thanks for your advaice! I have rebuilt it to one Thread like this: RUNNING = true; currentRunningThreads = 0; dataCollector = new DataCollector(); #region Create Connection serialPort = new SerialPort(serialPortSettings.getPort, serialPortSettings.getBoudRate, serialPortSettings.getParity, serialPortSettings.getDataBits, serialPortSettings.getStopBit); serialPort.DtrEnable = true; serialPort.RtsEnable = true; serialPort.WriteBufferSize = 102480; serialPort.ReadBufferSize = 102480; serialPort.Open(); #endregion //serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_ReceivedEvent); while (RUNNING) { if (serialPort.BytesToRead > 0) { onDataReceived(); } else Thread.Sleep(1); } But the main part is that i have encreased the writeBuffersize but mainly the ReadBufferSize to 102480. And with this settings i have now runned 4 stress tests that results in perfect matching files! Proberly the reading buffert on 4048 was to small to handle the stress. This software may be runned on laptops later on, and there need to be some extra buffert for these. What do you think of the new buffert size? is it maby to big? or can i increase it more to be more safe? Best Regards SnowJim

                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