Announcement

Collapse
No announcement yet.

Problem with hs.OpenComPort and grabbing serial data

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Problem with hs.OpenComPort and grabbing serial data

    I've used a com port serial device for years to read a serial message, but a recent change in provider meant I had to update the
    hardware. Originally I used hs.OpenComPortTerm in Startup.vb, in rawmode (as some characters are non-ascii) and the serial device sent a
    termination character that I could detect.
    This meant I could buffer the whole message and then process the data in a vb.net script.

    Unfortunately the new hardware does not send a termination character or a fixed length message. It also sends a checksum at the
    end of the message so I can't check for a particular byte or anything specific.

    An example c# code snippet supplied with the new hardware unit simply uses a timeout exception of one second to get the entire message.
    Its only 30 or so bytes at 1200 baud.
    I've only a limited knowledge of c# but in case it helps the relavent section of code looks like this:

    Code:
            
    --SNIP--
    
    private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                try {
                    // Read all the current buffer into the array
                    for (int c = 0; c != serialPort.BytesToRead; c++)
                    {
                        buffer[pointer] = serialPort.ReadByte();
                        pointer++;
                    }
    
                // If no more bytes then a timeout will occur
                } catch (TimeoutException x) {
    
                    // Now parse the received data
    		...
    		...
    --SNIP--
    When I now use OpenComPort in statup.vb my vb.net script is called for every read character instead of filling its buffer and then calling
    my script only once. Again my script is not in C#
    Sure, I can buffer these characters in to a string or an array however very regularly I keep missing the start of the message, or
    sometimes get multiple characters or corrupted messages.
    I suspect that the script sometimes doesn't execute quickly enough to grab everything as it used to do with hs.OpenComPortTerm

    I figured I could use System.IO.Ports in some fashion but don't know how to pick up the event of data arriving
    on the comport....or is there a timeout or a better way of solving this problem?

    Open to ideas, as this one has me truly stumped?
    Last edited by reggs11; June 27, 2018, 09:20 AM.

    #2
    What is the source of the message? How frequently is a new message sent? Is there any way to get it to send data in response to a request rather than just passively waiting for a message to arrive?

    I have not had to deal with the issue you are facing for a long time, and never with HS. What I would try is to have the script that is called by OpenComPort just record the buffer count. In a separate event with a recurring trigger, and the condition that the buffer count is >0, if the count has not increased since the last check, assume the message is complete and read the buffer.
    Mike____________________________________________________________ __________________
    HS3 Pro Edition 3.0.0.548, NUC i3

    HW: Stargate | NX8e | CAV6.6 | Squeezebox | PCS | WGL 800RF | RFXCOM | Vantage Pro | Green-Eye | Edgeport/8 | Way2Call | Ecobee3 | EtherRain | Ubiquiti

    Comment


      #3
      Originally posted by Uncle Michael View Post
      What is the source of the message? How frequently is a new message sent? Is there any way to get it to send data in response to a request rather than just passively waiting for a message to arrive?

      I have not had to deal with the issue you are facing for a long time, and never with HS. What I would try is to have the script that is called by OpenComPort just record the buffer count. In a separate event with a recurring trigger, and the condition that the buffer count is >0, if the count has not increased since the last check, assume the message is complete and read the buffer.
      Its just UK caller ID. I moved over to UK Sky as a phone line provider and they use a different format to BT but the old decoder box that I used to use, also sent an "OFF-LINE" string when the phone rang which I was able to use as a terminator.
      The new box doesn't send any terminator, just the decoded message data. There is an embedded length in the message but again I can't grab it quickly enough to reliably read the rest of the message.

      Your solution is actually similar to what I do already. I just buffer the message one character at a time and use another event to do the 'work' on the message when I get to the end.
      The only thing I have to do is read in the length and then only read that amount of remaining characters.

      Unfortunately it is still not fast enough to catch the opening byte reliably and still often misses characters when HS3 is busy doing other stuff.

      Comment


        #4
        One thing I could probably do is expand the C# example which reliably gets all of the data and displays it in a DOS\Console window on Windows 10 but how do I transfer the data back in to HS3?

        I'm not even sure how you run a C# script and what extension its saved with.
        The HS3 docs are a bit rubbish when it comes to C#.
        I guess its just .cs?

        Is there no way of using System.IO.Ports as that does have a timeout?

        Comment


          #5
          Originally posted by reggs11 View Post
          Your solution is actually similar to what I do already. I just buffer the message one character at a time and use another event to do the 'work' on the message when I get to the end.
          What I'm proposing is to leave the buffer alone until its length stops increasing, then read it just once.
          Mike____________________________________________________________ __________________
          HS3 Pro Edition 3.0.0.548, NUC i3

          HW: Stargate | NX8e | CAV6.6 | Squeezebox | PCS | WGL 800RF | RFXCOM | Vantage Pro | Green-Eye | Edgeport/8 | Way2Call | Ecobee3 | EtherRain | Ubiquiti

          Comment


            #6
            Big thanks for the suggestion Uncle Michael, I tried implementing what I believe you're suggesting but hit a snag.
            Namely that using hs.ComPortCount to see if the buffer has stopped receiving more characters isn't possible because at the receipt of the last character the event reading the comport isn't called back.

            This may not be what you meant so apologies in advance.

            Comment


              #7
              Originally posted by reggs11 View Post
              . . .using hs.ComPortCount to see if the buffer has stopped receiving more characters isn't possible because at the receipt of the last character the event reading the comport isn't called back.
              I understand. I didn't really flesh out my idea - even in my own mind - so let me try to elaborate.
              If you create a virtual device and store the buffer size in it each time you read it, you should be able to have an event that has:
              • a recurring trigger of once per second and
              • a condition that the buffer length (the value of your virtual device) is greater than zero and
              • a condition that the buffer length has not changed in __ seconds

              The event actions would be:
              • to call your script to read the buffer and process its contents and
              • to reset the virtual device value to zero.

              Does that make sense?

              (If you need faster processing than allowed by a recurring trigger, you might have to start a script with an idle loop that tests for the buffer length to stop changing, but that seems unlikely for caller ID.)
              Mike____________________________________________________________ __________________
              HS3 Pro Edition 3.0.0.548, NUC i3

              HW: Stargate | NX8e | CAV6.6 | Squeezebox | PCS | WGL 800RF | RFXCOM | Vantage Pro | Green-Eye | Edgeport/8 | Way2Call | Ecobee3 | EtherRain | Ubiquiti

              Comment


                #8
                Yes that makes a lot of sense thank you.

                Frustration since yesterday however, inspired me to get to grips with Moskus's easy plugin sample, as I gain a hell of a lot more control over the com port.

                With my own modified plugin based on one posted by 'Davros', I've managed to read the data in to a device string and timeout successfully after x milliseconds. I should have it all fully resolved shortly as I can just pick up the device change.

                Cheers anyway, this issue got me in to plugin development!
                Awesome

                Comment

                Working...
                X