JScripts and Serial Communications – Scales

Ah, the joys of trying to catch up on over 12 months of patching and upgrading servers, sadly between it and working through the finer details of our DR Plan there has been very little time for me to really invest much time in jscripts recently.

A few weeks ago I had an interesting conversation with a friend of mine. He asked me about whether or not it was possible to read values from a set of scales over a serial port through a jscript, they wanted a button that a user could push which would read the weight from scales and then submit it. I of-course replied confidently, yes – however you may need some fudging around to access the serial port – thinking in the order of using pinvoke.

As I was telling him about how when I last looked the .Net framework didn’t have direct functionality that supported interfacing to the COM ports, I searched msdn and came across a pleasant surprise, that pleasant surprise being System.IO.Ports and under that is a nice little object called SerialPort.

So, curious as I was I said I’d throw together a proof of concept.

As I didn’t have a set of scales to test, but I did have a Cisco switch handy I figured I’d just see what was involved in sending some data so it returned the initial command prompt. To be honest, the biggest hassle and nearly the most amount of time spent on this was moving the switch close enough to my computer and trying to find a power point!

Reading through the specifications that I was sent and some previous experience with retrieving data from serial devices that are dumb and just spew forth data, I decided that after each step I’d display a MessageBox. If you were looking at using this as a basis for your own solution you may want to look at saving things like the COM port settings, parity etc out to the registry or a configuration file rather than hard coding them as I did. Also there are some great examples of retrieving things like the available COM ports in the msdn documentation.

As mentioned, this is a proof of concept only, you can’t get much simpler than this but it should illustrate Opening/Closing and Reading/Writing from a serial port.

A few things to be wary of, when I was testing this I didn’t wrap any of the code in a try statement, when it crashed it took really nuked my Lawson Smart Office session. Getting an exception of the ReadLine is something I would expect to happen and potentially be a valid response due to a timeout. It would be prudent to also wrap the entire code in an exception handler.

Anyways, code commented as always.

import System;
import System.Windows;
import System.Windows.Controls;
import MForms;

import System.IO.Ports;

package MForms.JScript
{
    class SerialPortTest_000
    {
        public function Init(element: Object, args: Object, controller : Object, debug : Object)
        {
            // create our SerialPort Object
            // http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.aspx
            var spSerialPort = new SerialPort();

            if(null != spSerialPort)
            {
                spSerialPort.PortName = "COM1";          // the COM port we are going to use
                spSerialPort.BaudRate = 9600;            // the Baud
                spSerialPort.Parity = Parity.None;       // parity - http://msdn.microsoft.com/en-us/library/system.io.ports.parity.aspx
                spSerialPort.DataBits = 8;               // databits
                spSerialPort.StopBits = 1;               // stopbits
                spSerialPort.Handshake = Handshake.None; // Handshake - http://msdn.microsoft.com/en-us/library/system.io.ports.handshake.aspx

                // timeouts
                spSerialPort.ReadTimeout = 500;
                spSerialPort.WriteTimeout = 500;

                MessageBox.Show("About to Open");
                spSerialPort.Open();                     // Open the serial port

                MessageBox.Show("About to Write");
                spSerialPort.WriteLine("\n");            // Cisco switches like a linefeed to be sent before they return anything

                MessageBox.Show("About to Read");

                // we will read two lines of data and display them
                // it is important that you wrap things in an exception
                // handler, if you don't when things go wrong they will
                // go *VERY* wrong and will typically take out Lawson
                // Smart Office
                // infact, the entire serial port sequence should be wrapped
                // in a try statement 
               try
                {
                    var strData : String = spSerialPort.ReadLine();

 
                    strData += spSerialPort.ReadLine();
                }
                catch(ex)
                {
                }
                

                // show the data
                MessageBox.Show("Data = '" + strData + "'");

                // close the serialport
                spSerialPort.Close();
            }

        }
    }
}

Have fun!

This entry was posted in Development, M3 / MoveX, Misc and tagged . Bookmark the permalink.

2 Responses to JScripts and Serial Communications – Scales

  1. Heiko says:

    Hi Scott,

    I developed a LSO interface which connected 2 serial scanners to M3 some months ago, and unfortunately the real world is much more complicated compared to your example. The reason is, that the serial port communication has to be executed on an asynchronous background worker thread, which then invokes a GUI thread which can interact with the LSO user interface. WPF doesnt allow the direct access from a non-GUI thread. Additionally, all communication between the threads has to be done using the session cache – the threads don’t share variables. Also, the termination of the background threads as well as the initialization and the processing of the scanner output needs careful work – especially when 2 scanners push data to one M3 screen. But it is possible ! I needed weeks before the first solution of this kind was perfect – at that time I was not familiar with this kind of stuff and new to .Net. But then the second implementation was done in 2 hours.

    /Heiko

    • potatoit says:

      Hi Heiko,

      you’re totally right; depending on what you are trying to achieve, the equipment you are dealing with and the process being used the example provided may be a long way from what is needed. There was no intent on trivialising the potential complexity of reading from different devices in different scenarios.

      The question that prompted the investigation was for a very user interactive scenario.
      1). User clicks a button on the panel
      2). Weight is read and populates a TextBox
      3). User goes about the rest of their business

      The scales in question work by a code being sent to them and then they will respond with a newline terminated value. A simple write of a character then readline operation.

      This gives us the luxury of not needing to spin up any threads. If the UI becoming unresponsive is an issue then we can simply reduce the read and write timeouts and produce an error message to the user if the timeouts are hit without retrieving a value, maybe adding logic to prevent the user proceeding through the panel. The scenario is simple and in its original form doesn’t in my mind justify additional complexity or overheads.

      Not all external devices are created equal, I have seen devices that just sit there spitting out a value continuously – there is no interactive element so you need to build in additional logic to ensure that you aren’t reading partial data – no-where near as elegant a device as the scales in the scenario above.

      But the example is provided as proof of concept not a complete solution, and as with all the code on this site may require tweaking for specific environments or may not work at all 🙂

      I’m also sure that there are people that are interested in an example of how you have overcome the issues around worker threads and gui threads – I like the concept of using the session cache. I had a recent question where someone was trying to call mforms automation from a worker thread which as you point out won’t work. My brief investigation in to calling delegates from jscripts yielded some rather ‘interesting’ and unhelpful results.

      Thanks for the comment!

      Cheers,
      Scott

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s