Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

SerialSession.ReadByteArray(int) returns an unexpected number of bytes.

Hi,

   A SerialSession is setup to communicate with a device over an RS-232 cable. Command bytes are sent to the device and response bytes are received. 6512 bytes are received after the command bytes are sent. The code attempts to parse three sections of the received message into a header, body, and footer. SerialSession.ReadByteArray(16) is called, the bytes are parsed, the header values are good.

   For the body, when SerialSession.AvailableNumber >= 6484, SerialSession.ReadByteArray(6484) is called and the returned byte array is smaller than 6484. Each time the code is run SerialSession.ReadByteArray(6484) returns an array with a variable length less than 6484, sometimes, 52 bytes, sometimes 132 bytes, sometimes 54 bytes. No exception is thrown by the National Instruments VisaNS library. Why isn't an array of 6484 bytes being returned if SerialSession.AvailableNumber says there are 6484 bytes available? Am I setting up the SerialSession incorrectly?

Thanks in advance,

Rana




--- Portions of the code being run ---



        private const string VISA_RESOURCE_NAME = "ASRL1::INSTR";
        private const int BAUD_RATE = 115200;
        private const int DATA_BITS = 8;
        private const StopBitType STOP_BITS = StopBitType.Two;
        private const Parity PARITY = Parity.None;

--------------------
                //////////////////////////////////////
                // Constructor
                //////////////////////////////////////
            // Get SerialSession
            _SerialSession = (SerialSession)ResourceManager.GetLocalManager().Open(VISA_RESOURCE_NAME);
           
            // Set serial port parameters
            _SerialSession.SetBufferSize(BufferTypes.InBuffer, 8192);
            _SerialSession.BaudRate = BAUD_RATE;
            _SerialSession.Parity = PARITY;
            _SerialSession.DataBits = DATA_BITS;
            _SerialSession.StopBits = STOP_BITS;


---------------------
                //////////////////////////////////////
                // Parse Header (Works fine)
                //////////////////////////////////////
                while (_SerialSession.AvailableNumber < HEADER_LENGTH_IN_BYTES)
                {
                    // Check listen timeout
                    if (_ListenStopwatch.ElapsedMilliseconds > _ListenTimeInMilliseconds)
                    {
                        this.ThrowException();
                    }

                    Thread.Sleep(SLEEP_INTERVAL_IN_MILLISECONDS);
                }

                // Works fine, HEADER_LENGTH_IN_BYTES = 16
                byte[] received = _SerialSession.ReadByteArray(HEADER_LENGTH_IN_BYTES);


---------------------
                //////////////////////////////////////
                // Parse Body (Problem requires solution)
                //////////////////////////////////////

                // oim.HeaderLength = 6512
                // HEADER_LENGTH_IN_BYTES = 16
                // remainingMessageLength  = 6496
                int remainingMessageLength = oim.HeaderLength - HEADER_LENGTH_IN_BYTES;


                 // Wait for remaining message
                while (_SerialSession.AvailableNumber < remainingMessageLength)
                {
                    // Check listen timeout
                    if (_ListenStopwatch.ElapsedMilliseconds > _ListenTimeInMilliseconds)
                    {
                        this.ThrowInterrogatorException();
                    }

                    Thread.Sleep(SLEEP_INTERVAL_IN_MILLISECONDS);
                }

                // Read body
                int bodyLengthInBytes = remainingMessageLength - FOOTER_LENGTH_IN_BYTES;

                // Following line returns arrays with variable and unexpected lengths
                // bodyLengthInBytes = 6484, oim.Body usually equals 52 bytes! which is not what was requested....
                oim.Body = _SerialSession.ReadByteArray(bodyLengthInBytes);

0 Kudos
Message 1 of 4
(3,825 Views)

Hi Rana,

There may be a termination character set inadvertently somewhere in the response to cause the read to end without error.  If you read twice in a row, do you get the remainder of the response after the second read?  Also, have you tried any known working example code with this system?  Please try this out and post back with the results.  Have a great day!

Chris R.
Applications Engineer
National Instruments
0 Kudos
Message 2 of 4
(3,793 Views)
Hi Chris,

Thanks for the response. Termination character seems like a probable cadidate for the problem except SerialSession.TerminationCharacterEnabled indicates its set to false. Enclosed is trace output and trace output code demonstrating recent results. Since the number of bytes returned is always variable it would seem like the return stream might have a termination character at different point along the stream. Is it possible that the read is terminating even when SerialSession.TerminationCharacterEnabled is false?

I also tested getting bytes after the first read and there are more bytes to be had. We have tested the system with another SerialPort class and have verfied that the system works fine with other serial port software. So the issue is 100% isolated to NI.Visa.

Thanks for your time and interest.

Best Wishes,

Rana

--- Trace Output ---

remainingMessageLength: 6496
_SerialSession.AvailableNumber='320', _ListenStopwatch.ElapsedMilliseconds='827',
_SerialSession.AvailableNumber='544', _ListenStopwatch.ElapsedMilliseconds='847',
_SerialSession.AvailableNumber='796', _ListenStopwatch.ElapsedMilliseconds='869',
_SerialSession.AvailableNumber='1020', _ListenStopwatch.ElapsedMilliseconds='889',
_SerialSession.AvailableNumber='1258', _ListenStopwatch.ElapsedMilliseconds='909',
_SerialSession.AvailableNumber='1482', _ListenStopwatch.ElapsedMilliseconds='929',
_SerialSession.AvailableNumber='1706', _ListenStopwatch.ElapsedMilliseconds='950',
_SerialSession.AvailableNumber='1944', _ListenStopwatch.ElapsedMilliseconds='970',
_SerialSession.AvailableNumber='2280', _ListenStopwatch.ElapsedMilliseconds='1000',
_SerialSession.AvailableNumber='2518', _ListenStopwatch.ElapsedMilliseconds='1020',
_SerialSession.AvailableNumber='2742', _ListenStopwatch.ElapsedMilliseconds='1040',
_SerialSession.AvailableNumber='2966', _ListenStopwatch.ElapsedMilliseconds='1060',
_SerialSession.AvailableNumber='3218', _ListenStopwatch.ElapsedMilliseconds='1082',
_SerialSession.AvailableNumber='3442', _ListenStopwatch.ElapsedMilliseconds='1101',
_SerialSession.AvailableNumber='3876', _ListenStopwatch.ElapsedMilliseconds='1139',
_SerialSession.AvailableNumber='4100', _ListenStopwatch.ElapsedMilliseconds='1159',
_SerialSession.AvailableNumber='4324', _ListenStopwatch.ElapsedMilliseconds='1179',
_SerialSession.AvailableNumber='4562', _ListenStopwatch.ElapsedMilliseconds='1199',
_SerialSession.AvailableNumber='4786', _ListenStopwatch.ElapsedMilliseconds='1219',
_SerialSession.AvailableNumber='5010', _ListenStopwatch.ElapsedMilliseconds='1240',
_SerialSession.AvailableNumber='5388', _ListenStopwatch.ElapsedMilliseconds='1273',
_SerialSession.AvailableNumber='5626', _ListenStopwatch.ElapsedMilliseconds='1293',
_SerialSession.AvailableNumber='5850', _ListenStopwatch.ElapsedMilliseconds='1313',
_SerialSession.AvailableNumber='6074', _ListenStopwatch.ElapsedMilliseconds='1333',
_SerialSession.AvailableNumber='6312', _ListenStopwatch.ElapsedMilliseconds='1353',
_SerialSession.AvailableNumber='6496', _ListenStopwatch.ElapsedMilliseconds='1380',
bodyLengthInBytes: 6484
_SerialSession.TerminationCharacterEnabled: False
oim.Body: 224
secondAttempt: 109
_SerialSession.AvailableNumber='6163', _ListenStopwatch.ElapsedMilliseconds='1409',


--- Trace Output Code ---

                Debug.WriteLine("remainingMessageLength: " + remainingMessageLength);

                // Wait for remaining message
                while (_SerialSession.AvailableNumber < remainingMessageLength)
                {
                    // Check listen timeout
                    if (_ListenStopwatch.ElapsedMilliseconds > _ListenTimeInMilliseconds)
                    {
                        this.ThrowInterrogatorException();
                    }

                    StringBuilder sb = new StringBuilder(128);
                    sb.Append("_SerialSession.AvailableNumber='");
                    sb.Append(_SerialSession.AvailableNumber);
                    sb.Append("', _ListenStopwatch.ElapsedMilliseconds='");
                    sb.Append(_ListenStopwatch.ElapsedMilliseconds);
                    sb.Append("',");

                    Debug.WriteLine(sb.ToString());

                    Thread.Sleep(SLEEP_INTERVAL_IN_MILLISECONDS);
                }

                StringBuilder sb2 = new StringBuilder(128);
                sb2.Append("_SerialSession.AvailableNumber='");
                sb2.Append(_SerialSession.AvailableNumber);
                sb2.Append("', _ListenStopwatch.ElapsedMilliseconds='");
                sb2.Append(_ListenStopwatch.ElapsedMilliseconds);
                sb2.Append("',");

                Debug.WriteLine(sb2.ToString());

                // Read body
                int bodyLengthInBytes = remainingMessageLength - OcmInterrogatorMessage.FOOTER_LENGTH_IN_BYTES;

                Debug.WriteLine("bodyLengthInBytes: " + bodyLengthInBytes);

                Debug.WriteLine("_SerialSession.TerminationCharacterEnabled: " + _SerialSession.TerminationCharacterEnabled);
               
                oim.Body = _SerialSession.ReadByteArray(bodyLengthInBytes);

                Debug.WriteLine("oim.Body: " + oim.Body.Length);

                byte[] secondAttempt = _SerialSession.ReadByteArray(oim.Body.Length);

                Debug.WriteLine("secondAttempt: " + secondAttempt.Length);

                StringBuilder sb3 = new StringBuilder(128);
                sb3.Append("_SerialSession.AvailableNumber='");
                sb3.Append(_SerialSession.AvailableNumber);
                sb3.Append("', _ListenStopwatch.ElapsedMilliseconds='");
                sb3.Append(_ListenStopwatch.ElapsedMilliseconds);
                sb3.Append("',");
                Debug.WriteLine(sb3.ToString());
0 Kudos
Message 3 of 4
(3,781 Views)
Hi Chris,

      We just determined that the the byte array length is all the bytes up to the default defined SerialSession.TerminationCharacter of 0x0A. SerialSession.TerminationCharacterEnabled is equal to false. Is there a way to tell SerialSession.ReadByteArray(int) not to use the TerminationCharacter?

Best Wishes,

Rana
0 Kudos
Message 4 of 4
(3,757 Views)