# Reading/Writing Multiple Serial Inputs and Outputs using NMEA protocol

**URL:** <https://forum.inductiveautomation.com/t/reading-writing-multiple-serial-inputs-and-outputs-using-nmea-protocol/19600>\
**Category:** Ignition\
**Created:** [September 10, 2018, 5:37am UTC](https://forum.inductiveautomation.com/t/reading-writing-multiple-serial-inputs-and-outputs-using-nmea-protocol/19600 "2018-09-10T05:37:39Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![edwinnch](https://avatars.discourse-cdn.com/v4/letter/e/ecae2f/32.png) [@edwinnch](https://forum.inductiveautomation.com/u/edwinnch)\
**Post date:** [September 10, 2018, 5:37am UTC](https://forum.inductiveautomation.com/t/reading-writing-multiple-serial-inputs-and-outputs-using-nmea-protocol/19600/1 "2018-09-10T05:37:39Z")

</div>

Hi,

We have a project which requires to read 16 serial inputs in NMEA string and displays the information from each input onto a mimic page. We are also required to process these information and output them to 42 equipment in NMEA string. Each on the input and output has to be configurable for selection on the com port no. , baud rate, message type and update frequency.

As we are using ignition for the mimic pages as well as the back-end works (ie configuring the serial ports, scripts for reading and writing nmea strings), we would like to understand what are the constraints and limitations to achieve our requirement.

For the configuration on the comport, we have attached the scripts in the text file and the mimic of the configuration page. We would appreciate if anyone could suggest a better way to make the scripts much more elegant.

![](https://cdck-file-uploads-us1.s3.dualstack.us-west-2.amazonaws.com/inductiveautomation/original/2X/a/ae81d5aee7064790a04e2eaf89dac82f058d88d1.PNG) ![](https://cdck-file-uploads-us1.s3.dualstack.us-west-2.amazonaws.com/inductiveautomation/original/2X/5/53a7b3883d47e2b2c2b4d7587bc4e8b7e385e04c.PNG)[Script for InputConfiguration.txt](https://cdck-file-uploads-us1.s3.dualstack.us-west-2.amazonaws.com/inductiveautomation/original/2X/9/9ac17ca0377f053cd2defed40561967235f9ac4c.txt) (9.3 KB)

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 10, 2018, 1:32pm UTC](https://forum.inductiveautomation.com/t/reading-writing-multiple-serial-inputs-and-outputs-using-nmea-protocol/19600/2 "2018-09-10T13:32:46Z")

</div>

You might find this post helpful:

> [@How to listen serial data without interruption](http://forum.inductiveautomation.com/t/how-to-listen-serial-data-without-interruption/15709/2):
>
> This is actually a rather challenging task, requiring a background thread constantly listening to the serial port. You might find inspiration in this example: [clientserial.py](https://www.automation-pros.com/ignition/clientserial.py).

---

<div class="post-metadata">

**Author:** ![edwinnch](https://avatars.discourse-cdn.com/v4/letter/e/ecae2f/32.png) [@edwinnch](https://forum.inductiveautomation.com/u/edwinnch)\
**Post date:** [October 18, 2018, 1:22am UTC](https://forum.inductiveautomation.com/t/reading-writing-multiple-serial-inputs-and-outputs-using-nmea-protocol/19600/3 "2018-10-18T01:22:57Z")

</div>

I have a few clarification on the below script from clientserial.py:

if otherThreadName:  
tcEstimate = Thread.currentThread().threadGroup.activeCount()  
threads = jarray.zeros(tcEstimate\*2, Thread)  
threadCount = Thread.enumerate(threads)

1. What does it do ?
2. What is the rationale of multiplying tcEstimate by 2 ?
3. Is there a good reference to understand the threading concept used here ?

The monitorToledo(ctPath, myThread) function has 2 arguments but are not called anywhere in the clientserial.py script. I wonder why is it so and how will then clientserial.py works.

I have tried to run the script by using a button component with the following script in the actionperformed event handler:

**system.tag.write("[Client]SerialThread/Port", ‘COM11’)**  
**project.clientserial.background(project.clientserial.monitorToledo, “SerialThread”)**

The moment i clicked onto it in preview mode, ignition seems not responding. However, my task manager shows that it is still running.

Any idea why is it so 😕?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [October 18, 2018, 1:57am UTC](https://forum.inductiveautomation.com/t/reading-writing-multiple-serial-inputs-and-outputs-using-nmea-protocol/19600/4 "2018-10-18T01:57:00Z")

</div>

> [@edwinnch](#):
>
> Is there a good reference to understand the threading concept used here ?

See the Java documentation for [Thread.enumerate()](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#enumerate-java.lang.Thread:A-). The purpose is to relatively reliably iterate through other threads looking for a matching name. So it can be killed off.

> [@edwinnch](#):
>
> The monitorToledo(ctPath, myThread) function has 2 arguments but are not called anywhere

It is called from background as `callable`. You should expect to write a suitable monitor\*() function that suites your protocol requirements.

> [@edwinnch](#):
>
> The moment i clicked onto it in preview mode, ignition seems not responding

That's because background() must be called from a background thread, such as from invokeAsynchronous(). I should document that a bit better. In my actual usage of this code, I use the callAsync() function from later.py to wrap that for me:

> [@Update GUI via Asynchronous thread](http://forum.inductiveautomation.com/t/update-gui-via-asynchronous-thread/9666/3):
>
> Since this sort of thing pops up often, I created a set of wrappers that simplify this stuff, and allows you to directly use functions in your script modules. The wrappers take care of stuffing the arguments you supply into a temporary fuction’s default argument. For your case, try assignLater(). Nick’s example becomes: # In a script module in your project: import shutil def fileTransfer(label): path = system.file.openFile() newPath = "F:\NewFolder" shutil.copy2(path, newPath) sh…
