Announcement

Collapse
No announcement yet.

DoMore: Terminating STREAMIN Function

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


  • DoMore: Terminating STREAMIN Function

    HI,
    I have an application where I need to monitor a serial line for an inbound alarm signal over the on-board serial port. I need to monitor 24/7 so I'm using the STREAMIN block terminating on a delimiter character with no timeout. When the alarm string comes in the block processes the string and exits setting the on_success bit, I can then post-process the string and re-enable the STREAMIN block to wait for the next alarm.

    My problem is, occasionally, I need to send a message. According to the documentation, de-asserting the enable input to the STREAMIN block will not release the COM port. The block will asynchronously complete its receive based on its settings, in my case until it receives a delimiter character which could be hours/days. Is there any way to force the port to be released so I can use the STREAMOUT block?

    Thanks.


  • #2
    This is where Stage can help. Create a PROGRAM code-block called MonitorAlarms

    In the first stage SG S0, stick your current STREAMIN instruction, and OnSuccess, JMP to Stage S1 (and OnError, JMP to Stage S99).

    In Stage SG S1, do your string processing, and set any Bit that you may want $Main/HMI to be monitoring or whatever. Then JMP back unconditionally to SG S0. This will re-arm your STREAMIN.

    Go back to Stage SG S0, and after your STREAMIN instruction, have a contact driving a JMP to Stage S2. This contact contains the "I want to SEND a message" bit. This will cause a transition FROM S0 to S2, TERMINATING the STREAMIN instruction in S0. When you JMP FROM one Stage to anther stage, this DISABLES the SOURCE stage and ENABLES the DESTINATION stage. When a Stage is DISABLEd any OUT coils are turned OFF, and other instructions that have "Terminating" logic will "terminate", i.e. STREAMIN will terminate and "release" its serial device.

    Then in Stage SG S2, have your STREAMOUT that JMPs to SG S3 OnSuccess where S3 does any post-message-sending processing, then unconditionally JMP back to SG S0 (make sure you RESET your "I want to SEND a message" bit.). This will re-arm the STREAMIN in S0. You can also JMP to SG S99 OnError from STREAMOUT.

    Finally, in Stage S99, increment an error counter or whatever "error" handling you might want to do (you should never see these), then unconditionally JMP to SG S0 to re-arm the STREAMIN.

    In $Main, you need to RUN MonitorAlarms unconditionally (ST1 driving RUN instruction). MonitorAlarms NEVER terminates (it has no EXIT instruction), but you still need to initially "run" it from $Main (which is ALWAYS running when in RUN mode).

    I hope this makes sense. Stage is very powerful tool for sequencing and branching.
    There are 10 kinds of people in this world, those who know binary, and those who do not.

    Comment



    • #3
      Attached is a picture of the MonitorAlarms logic described below (it clipped S99, which just incremented a MsgErrorCount D register then JMPed back to S0).

      You will need to tweak the logic (I stubbed in my own "ProcessAlarmMsg" behavior), but it's "shape" and basic "flow" should work.

      Remember to add the RUN MonitorAlarms in $Main.

      See the code-blocks, rungs, Stages, comments, and nicknames below the Control Logic tree in the Project Browser for a good overview of the logic.
      Attached Files
      Last edited by franji1; 05-13-2014, 08:14 AM. Reason: Had wrong SG number in STREAMIN OnError JMP stage (needed to be S99)
      There are 10 kinds of people in this world, those who know binary, and those who do not.

      Comment



      • #4
        I would consider doing it differently, but still using stage. This is an overly simplistic example, but should convey the concept. Create 3 stages: WAIT, READ, and WRITE. WAIT is your initial stage.

        From WAIT use a relational contact to determine when the serial port device structure's .InQueue member is non-zero. When .InQueue != 0 JMP to READ.

        READ does your STREAMIN...with a reasonable timeout...and jumps back to WAIT. Use the stage jump option in STREAMIN.

        Add another rung to WAIT that checks to see if you want to send. When true, do a JMP to WRITE.

        WRITE does a STREAMOUT and jumps back to WAIT. As with READ, use the stage jump option.

        The termination mechanism Franj referenced works, but it is kinda harsh and is really designed for forcible termination during a program shutdown, rather than normal program flow. The better way is to wait until you have work to do, do it using a short timeout, then resume waiting.
        Last edited by BobO; 05-13-2014, 08:22 AM.

        Comment



        • #5
          Originally posted by BobO View Post
          The termination mechanism Franj referenced is works, but it is kinda harsh. The better way is to wait until you have work to do, do it using a short timeout, then resume waiting.
          Even Better!
          There are 10 kinds of people in this world, those who know binary, and those who do not.

          Comment



          • #6
            Thank you both, I think I'm getting it.

            Franji, that all makes sense. I have had "stage fright" up to now, but I think I may jump in and give it a shot.

            What about If STREAMIN is in a task? Will killing the task release the com port?

            Bob, If I understand you correctly, your example only goes to the READ stage when directed by the logic in WAIT when a message is expected. My issue is that the message could come in at any time and I have no way of knowing when its coming. That is the reason that I had STREAMIN always receiving so it could "listen" for the alarm message. I could have a timeout set in STREAMIN and bounce back to WAIT to check if a message needs to be sent, if not go back to READ and so on. My concern is that I would miss a message during the READ>WAIT>READ transition.

            Perhaps I'm missing a basic understanding of the serial port device; Will it buffer inbound data if STREAMIN is not active which will be collected when STREAMIN goes active? or does the message get lost? The transmitting equipment has no flow control, it just sends the messages once with no confirmation that it was received.

            Thanks.

            Comment



            • #7
              Fully queued, both directions...won't miss a thing.

              Stage is your friend for this type of application. Use it.

              Don't use a task. This is precisely why we created programs and stage. It doesn't get any cleaner than a simple program with a handful of stages.

              Comment



              • #8
                Originally posted by BobO View Post
                Fully queued, both directions...won't miss a thing.

                Stage is your friend for this type of application. Use it.

                Don't use a task. This is precisely why we created programs and stage. It doesn't get any cleaner than a simple program with a handful of stages.
                I'll go give stage It a shot. It all makes sense now that I understand that the receive buffer is independent of the STREAMIN function.

                Thanks again.

                Comment



                • #9
                  Originally posted by northwind View Post
                  I'll go give stage It a shot.
                  I've spent much of my career writing comm code, and when we started doing the communications boxes for Do-more, I realized that we had a big hole. Even though we had made the decision early on to *not* do Stage, we realized after much discussion that Stage was the most correct answer for creating sequences of asynchronous operations. It gives many folks the willies, but mostly because it is misused. Use it the right way, to solve the right problem, and you'll never fear it again.

                  Comment



                  • #10
                    One more question...
                    Using the STREAMIN function, if it is set to terminate on a delimiter OR a network timeout; does a timeout cause the OnSuccess or OnError stage jump?

                    Thanks.

                    Comment



                    • #11
                      Originally posted by northwind View Post
                      One more question...
                      Using the STREAMIN function, if it is set to terminate on a delimiter OR a network timeout; does a timeout cause the OnSuccess or OnError stage jump?

                      Thanks.
                      OnError. If you need to distinguish it from other errors (maybe it is expected) you can test the error code stored in a DST location.

                      Comment

                      Working...
                      X