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#
  4. Problem with DataReceived handler in serialport

Problem with DataReceived handler in serialport

Scheduled Pinned Locked Moved C#
helpdatabasesysadminquestion
5 Posts 2 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.
  • B Offline
    B Offline
    blackhattrick
    wrote on last edited by
    #1

    Im using a SerialPort in order to connect a client and a server through modem. I write some AT commands in the servers' modem buffer, and the client makes the handshaking correctly. The AT commands are written when the DataReceived Handler is triggered. The problem is that when handshaking finishes and communication is established, I cant use the handler to detect new data , I have to do a loop, reading the serialport input buffer constantly. Is there a way to trigger the event handler and read data instead of using a loop? Any help would be apreciated and excuse my english if I made a mistake :) Ivan

    M 1 Reply Last reply
    0
    • B blackhattrick

      Im using a SerialPort in order to connect a client and a server through modem. I write some AT commands in the servers' modem buffer, and the client makes the handshaking correctly. The AT commands are written when the DataReceived Handler is triggered. The problem is that when handshaking finishes and communication is established, I cant use the handler to detect new data , I have to do a loop, reading the serialport input buffer constantly. Is there a way to trigger the event handler and read data instead of using a loop? Any help would be apreciated and excuse my english if I made a mistake :) Ivan

      M Offline
      M Offline
      Moreno Airoldi
      wrote on last edited by
      #2

      I often use serial ports and other similar way of communicating to instruments and devices, and personally I prefer to write a thread for reading incoming data. You can have the thread loop and check on incoming data and if any, read it all up (or up to a maximum of "n" bytes), and insert a Thread.Sleep(1) in the loop or similar to avoid using up all the CPU time. You can use events to break the thread on closing the serial port and cleaning up, or even a simple boolean. You must of course use some locking to ensure thread-safe access to the serial port object. I've been using this technique for quite a few years, and it works quite nice IMO. Hope this can help, if you need it I can give you some code snippets, just let me know. :)

      2+2=5 for very large amounts of 2 (always loved that one hehe!)

      B 1 Reply Last reply
      0
      • M Moreno Airoldi

        I often use serial ports and other similar way of communicating to instruments and devices, and personally I prefer to write a thread for reading incoming data. You can have the thread loop and check on incoming data and if any, read it all up (or up to a maximum of "n" bytes), and insert a Thread.Sleep(1) in the loop or similar to avoid using up all the CPU time. You can use events to break the thread on closing the serial port and cleaning up, or even a simple boolean. You must of course use some locking to ensure thread-safe access to the serial port object. I've been using this technique for quite a few years, and it works quite nice IMO. Hope this can help, if you need it I can give you some code snippets, just let me know. :)

        2+2=5 for very large amounts of 2 (always loved that one hehe!)

        B Offline
        B Offline
        blackhattrick
        wrote on last edited by
        #3

        Thanks for your suggestion Moreno! Yeah, I think thats the best way to do this task, but... Im using GUI to report and show the status of each serialport (Im using 60 instances of it, I have 60 COM ports). For example, report if CD is on, CTS, if its reading, writing and so on... so I would have to make 60 threads for each serialport, plus main thread which manages all the GUI stuff, so I think I would have to use some sort of thread cross communication, and I'm not good at that topic ;P. However, I'm googling that. BTW if someone have any good resource about threads communication (sharing data between them), it would be very useful. Thanks! Ivan

        M 1 Reply Last reply
        0
        • B blackhattrick

          Thanks for your suggestion Moreno! Yeah, I think thats the best way to do this task, but... Im using GUI to report and show the status of each serialport (Im using 60 instances of it, I have 60 COM ports). For example, report if CD is on, CTS, if its reading, writing and so on... so I would have to make 60 threads for each serialport, plus main thread which manages all the GUI stuff, so I think I would have to use some sort of thread cross communication, and I'm not good at that topic ;P. However, I'm googling that. BTW if someone have any good resource about threads communication (sharing data between them), it would be very useful. Thanks! Ivan

          M Offline
          M Offline
          Moreno Airoldi
          wrote on last edited by
          #4

          I understand your doubts: threading can be a pain if you're not used to it, but it pays off. My best suggestions is you create a wrapper class which includes all the serial port functionality, for example:

          using System.IO.Ports;

          internal class MySerialPortClass
          {
          ...
          // *** Incapsulated serial port object ***
          private SerialPort MySerialPort = null;
          ...
          // *** Routines to handle the serial port ***
          internal void Open()
          ...
          internal void Close()
          ....
          internal void Send(string Message)
          }

          The class will also contain your thread and start/stop it automatically, for example upon creation/distruction or upon opening/closing the serial port. To handle thread-safety you can simply use locking on the serial port object every time you access it, since that's the only shared resource. For example:

          internal class MySerialPortClass
          {
          private object MySerialPortLock = new object();
          ...
          internal void Open()
          {
          ...
          lock (MySerialPortLock)
          {
          MySerialPort.Open()
          }
          ...
          }
          ...
          }

          And the same technique must be used on any other property in your class that will be accessed by the read thread. For example, if you store the communication results in some variable and then access it from other threads, then you must use locking on it. Finally, you can set up events for anything you want notification about. End of communications by either reading the answer from the device or timing out is the basic event you will need, but you can also add others depending on your needs. For example:

          internal class MySerialPortClass
          {
          internal delegate void CommEndDelegate(string Result);
          internal delegare void CommErrorDelegate(string ErrorMessage);

          internal event CommEndDelegate OnCommEnd;
          internal event CommErrorDelegate OnCommError;
          

          ...
          private void DoOnCommEnd(string Result)
          {
          if (OnCommEnd != null) OnCommEnd(Result);
          }
          ...
          private void DoOnCommError(string ErrorMessage)
          {
          if (OnCommError != null) OnCommError(ErrorMessage);
          }
          ...
          internal void MyReadThreadRoutine()
          {
          ...
          // *** Received a correct answer from the device, signal end of communications ***
          DoOnCommEnd(Result);
          ...
          // *** Timeout waiting for response from device, signal error ***
          DoOnCommError("Timeout");
          ...
          }
          ...
          }

          This will make it

          B 1 Reply Last reply
          0
          • M Moreno Airoldi

            I understand your doubts: threading can be a pain if you're not used to it, but it pays off. My best suggestions is you create a wrapper class which includes all the serial port functionality, for example:

            using System.IO.Ports;

            internal class MySerialPortClass
            {
            ...
            // *** Incapsulated serial port object ***
            private SerialPort MySerialPort = null;
            ...
            // *** Routines to handle the serial port ***
            internal void Open()
            ...
            internal void Close()
            ....
            internal void Send(string Message)
            }

            The class will also contain your thread and start/stop it automatically, for example upon creation/distruction or upon opening/closing the serial port. To handle thread-safety you can simply use locking on the serial port object every time you access it, since that's the only shared resource. For example:

            internal class MySerialPortClass
            {
            private object MySerialPortLock = new object();
            ...
            internal void Open()
            {
            ...
            lock (MySerialPortLock)
            {
            MySerialPort.Open()
            }
            ...
            }
            ...
            }

            And the same technique must be used on any other property in your class that will be accessed by the read thread. For example, if you store the communication results in some variable and then access it from other threads, then you must use locking on it. Finally, you can set up events for anything you want notification about. End of communications by either reading the answer from the device or timing out is the basic event you will need, but you can also add others depending on your needs. For example:

            internal class MySerialPortClass
            {
            internal delegate void CommEndDelegate(string Result);
            internal delegare void CommErrorDelegate(string ErrorMessage);

            internal event CommEndDelegate OnCommEnd;
            internal event CommErrorDelegate OnCommError;
            

            ...
            private void DoOnCommEnd(string Result)
            {
            if (OnCommEnd != null) OnCommEnd(Result);
            }
            ...
            private void DoOnCommError(string ErrorMessage)
            {
            if (OnCommError != null) OnCommError(ErrorMessage);
            }
            ...
            internal void MyReadThreadRoutine()
            {
            ...
            // *** Received a correct answer from the device, signal end of communications ***
            DoOnCommEnd(Result);
            ...
            // *** Timeout waiting for response from device, signal error ***
            DoOnCommError("Timeout");
            ...
            }
            ...
            }

            This will make it

            B Offline
            B Offline
            blackhattrick
            wrote on last edited by
            #5

            :omg: This is really useful. Thanks a lot Moreno!, I'll try this... :-D

            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