Serial Communication

A forum devoted to the discussion of all topics having to do with scripting and other advanced programming using iX Developer.
ajack
Posts: 44
Joined: Wed Feb 22, 2012 12:01 am

Re: Serial Communication

Post by ajack »

I did try reading buffer as your advice:

Code: Select all

private static void SerialPortScan(Object sender, EventArgs e)
{
	_serialTimer.Enabled = false;
									
	//Read data from RXD buffer to _bufferReceive
	_bufferReceiveLength = _serialPort.BytesToRead;
			
	if (_bufferReceiveLength > 0)
	{
		if (_bufferReceiveLength < _serialPort.ReadBufferSize)
			_serialPort.Read(_bufferReceive, 0, _bufferReceiveLength);
	}
			
	_serialTimer.Enabled = true;
}
and I and display BytesToRead every 500ms, I found out that BytesToRead only has value > 0 after 3-4 SerialPortScan events.

So, I try to connect serial device with another device and it works properly. That means the mis-reading was caused by my script...

mark.monroe
Posts: 824
Joined: Tue Mar 13, 2012 9:53 am

Re: Serial Communication

Post by mark.monroe »

I would not be concerned by how long it initially takes to setup communication between a device and the HMI. It will always take a while for two peripherals to start to talk to each other.

How quickly does the device respond when you tell it to do something?

If you send it a command to give you data, how quickly does the device respond with the first data packet? The amount of data being sent will of course impact how long it takes to get the final data packet.

What are you trying to communicate with over the serial port and what is your Panel model? Does the device just stream data to the HMI or do you have to request data from the device?

You could always a loop back test on the serial port. That way you cut out the device.
Best Regards,
Mark Monroe

Beijer Electronics, Inc. | Applications Engineer

ajack
Posts: 44
Joined: Wed Feb 22, 2012 12:01 am

Re: Serial Communication

Post by ajack »

My HMI would send commands (up to 10 bytes - small packet!) to device and receive data (up to 10 bytes). But, in this test, my serial port just try to read data from serial device to HMI. I think it should be handle every 500ms... But it takes about 3-4 ticks, which means 1.5s-2s, I don't think this would be acceptable transceive...

And I try to use DataReceived event but it just raise event only one time!

Code: Select all

_serialPort.DataReceived += new SerialDataReceivedEventHandler(SerialDataReceivedEventHandler);

Code: Select all

private static void SerialDataReceivedEventHandler(Object sender, EventArgs e)
{
	//put counter here to check if Event Handler can raise everytime
	//serial device try to send packet
	if (Globals.Tags.timer.Value++ == 1000)
		Globals.Tags.timer.Value = 0;
			
	_bufferReceiveLength = _serialPort.BytesToRead;
			
	if (_bufferReceiveLength > 0)
		if (_bufferReceiveLength < _serialPort.ReadBufferSize)
			_serialPort.Read(_bufferReceive, 0, _bufferReceiveLength);

}

mark.monroe
Posts: 824
Joined: Tue Mar 13, 2012 9:53 am

Re: Serial Communication

Post by mark.monroe »

Why are you zeroing out the timer value when it reaches 1000? Why not for the test at least just let it count up.

Code: Select all

   //if (Globals.Tags.timer.Value++ == 1000)
      Globals.Tags.timer.Value = 0;

Code: Select all

   
   _bufferReceiveLength = _serialPort.BytesToRead;
         
   if (_bufferReceiveLength > 0)
      //We have data, but we will not read it unless it is less than
      // '_bufferReceiveLength < _serialPort.ReadBufferSize'
      //Why not read the data? Why wait for it to be less than ReadBufferSize?
      if (_bufferReceiveLength < _serialPort.ReadBufferSize)
         _serialPort.Read(_bufferReceive, 0, _bufferReceiveLength);
Try this code instead of the above:

Code: Select all

serialPort.ReadTimeout = 25;

//Check to make sure we have data to read in
if(serialPort.BytesToRead > 0)
{
      //Looks like we have data.
      //Now it is possible for the amount of data we have to be larger than the
      //ReadBufferSize.
      if(serialPort.BytesToRead > serialPort.ReadBufferSize)
      {
            //Only read in the ReadBufferSize, not more!
            serialPort.Read(buffer, 0, serialPort.ReadBufferSize);
      }
      else
      {
            serialPort.Read(buffer, 0, serialPort.BytesToRead);
      }
}
"Because the BytesToRead property represents both the SerialPort buffer and the Windows-created buffer, it can return a greater value than the ReadBufferSize property, which represents only the Windows-created buffer."
Best Regards,
Mark Monroe

Beijer Electronics, Inc. | Applications Engineer

ajack
Posts: 44
Joined: Wed Feb 22, 2012 12:01 am

Re: Serial Communication

Post by ajack »

At last, I can communicate with serial device smoothly without any errors.

Every 500ms, HMI would send a packet (10bytes + CRLF) to serial device, and a packet contains command which tell serial device to send back the data.

That's it!

I think the trouble is there's no handshake between serial device and HMI, and the "send back" command in send packet is used to tell exactly what time serial device should transmit data to HMI.

Thanks Mark and Ron for your help!

PS: I couldn't use DataReceived event and no matter how hard I try, I couldn't set baudrate faster than 19200

mark.monroe
Posts: 824
Joined: Tue Mar 13, 2012 9:53 am

Re: Serial Communication

Post by mark.monroe »

What software version of iX developer and what kind of Panel do you have? The only thing I can think of is that the system thinks the port can only handle buad rates up to 19200. Our panels can use higher buad rates. Have you gone into the 'Service Menu' and looked at the com port settings?

Have you tried setting the buad rate higher, and see if it works even though the '_serialPort.BaudRate' property returns zero?

Mark
Best Regards,
Mark Monroe

Beijer Electronics, Inc. | Applications Engineer

mark.monroe
Posts: 824
Joined: Tue Mar 13, 2012 9:53 am

Re: Serial Communication

Post by mark.monroe »

If you are saving the sPort.BaudRate into a tag for later display, make sure that the tag's data type is INT32. If you use INT16 the tag will just display 0 in the AnalogNumeric box when numbers greater than 32,767 are assigned to it.

Mark
Best Regards,
Mark Monroe

Beijer Electronics, Inc. | Applications Engineer

ajack
Posts: 44
Joined: Wed Feb 22, 2012 12:01 am

Re: Serial Communication

Post by ajack »

Dear Mark,

I'm so sorry for my stupidity. You were right: the Tag, which is used to display Baudrate, must be declare as INT32 cause faster baudrate (such as 38400, 115200) is larger than 32,767.

But, I don't know why I couldn't communicate 2 devices using baudrate faster than 19200, eventhough my serial device could send and receive with 115200.

Phong

Post Reply