6 Replies - 7519 Views - Last Post: 13 July 2011 - 07:51 AM Rate Topic: -----

#1 Mya555  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 11-July 11

Serial port communication help

Posted 11 July 2011 - 06:24 AM

Hello I am working on a biomedical project at University and
need to communicate with a fetal CTG machine that has a RS232
interface. I have some C# experience and also have C experience
plus my dad is a Java programmer and he is helping as much as he can!

The following is the code I have written so far


using System;
using System.IO.Ports;
using System.Collections.Generic;


namespace SerialCom
{
    class Program
    {
        //Created serial port object and initialised
        SerialPort com = new SerialPort(SerialPort.GetPortNames()[0],
          1200, Parity.None, 8, StopBits.One);
        
        static void Main(string[] args)
        { new Program(); }

        Program()
        {
            
            
            //Open com port
            com.Open();

            // Write Line writes string and new line value to output buffer
            // { <DLE> , <STX> , "G" , <DLE> , <ETX> , 16 BIT CRC CCITT split into two bytes}
           byte[] byteToSend = new byte[] {0x10,0x02,0x47,0x10,0x03,0x42,0x1F};
            

            
            com.Write(byteToSend, 0, byteToSend.Length);

            Console.WriteLine("Waiting for incoming data...");
            Console.ReadKey();

            com.DataReceived +=
              new SerialDataReceivedEventHandler(com_DataReceived);
        }

        private void com_DataReceived(object sender,
        SerialDataReceivedEventArgs e)
        {
            // Show all the incoming data in the port's buffer
            Console.WriteLine("Hello0"); // Checking if enter method
            Console.WriteLine(com.ReadExisting());
            
        }

           
    }
}



From the hardware specifications I need to send to the machine shown below:

After power up, the fetal monitor does not automatically send CTG data. There are two ways
of initiating transmission of the CTG data:

2. Let the fetal monitor send the CTG data automatically every second by issuing the G
command (sending a G data block without any additional data).
The data code for G-mode (auto send mode) is:
.
<DLE><STX>G<DLE><ETX><CRC><CRC>


So I know that my serial port is definitely initialised correctly. When compiled in VS10
command just says "Waiting for incoming data.."

I am worried that there is something wrong with the code particularly the writing to port,
I'm not sure that it is writing what is required to port , do I need to set the output buffer size?
I tried different CRC's using an online calculator and checked a few times, I guess there could
also be problems with the machine and/or the cable but wanted to check here if someone could see something
obviously wrong with the code? I am grateful for any help to make the next couple of days/weeks of debugging
easier :)

Is This A Good Question/Topic? 0
  • +

Replies To: Serial port communication help

#2 ragingben  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 170
  • View blog
  • Posts: 637
  • Joined: 07-October 08

Re: Serial port communication help

Posted 11 July 2011 - 06:37 AM

They may be obvious, but move the Console.ReadLine(); until after the line
com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);


Because the program is waiting for Enter to be pressed before it subrcribes to the event for data received, so until you press enter it is not handling incoming data. Then, when you press enter it will close, which obviosuly will not be desired behaviour.

It is defiently working at a baud rate of 1200?

Also, I have just noticed that your doing some weird stuff with your Program constructor, you shouldn't really have one for Console apps Program class.

Try this:
using System;
using System.IO.Ports;
using System.Collections.Generic;


namespace SerialCom
{
    class Program
    {
        //Created serial port object and initialised
        static SerialPort com = new SerialPort(SerialPort.GetPortNames()[0], 1200, Parity.None, 8, StopBits.One);

        static void Main(string[] args)
        {
            // initiate streaming
            initiateDataStreaming();

            // wait for input before closing
            Console.ReadKey();
        }

        private static void initiateDataStreaming()
        {
            //Open com port
            com.Open();

            // Write Line writes string and new line value to output buffer
            // { <DLE> , <STX> , "G" , <DLE> , <ETX> , 16 BIT CRC CCITT split into two bytes}
            byte[] byteToSend = new byte[] { 0x10, 0x02, 0x47, 0x10, 0x03, 0x42, 0x1F };

            com.Write(byteToSend, 0, byteToSend.Length);

            Console.WriteLine("Waiting for incoming data...");

            com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);    
        }

        private static void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Show all the incoming data in the port's buffer
            Console.WriteLine("Hello0"); // Checking if enter method
            Console.WriteLine(com.ReadExisting());
        }
    }
}



Notice how everything is static? Personally I would develop this app so that it has a class that communicates with the monitor thing and handles all input from it, say CTGMonitor, and your Program class, or whatever front end you develop, can have an instance of. This would be a much neater way of doing this in the long run.

This post has been edited by ragingben: 11 July 2011 - 06:46 AM

Was This Post Helpful? 1
  • +
  • -

#3 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5469
  • View blog
  • Posts: 11,749
  • Joined: 02-June 10

Re: Serial port communication help

Posted 11 July 2011 - 09:07 AM

PsychoCoder did a really nice tutorial on the serial port. It would be a shame to not use it.
Was This Post Helpful? 1
  • +
  • -

#4 Mya555  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 11-July 11

Re: Serial port communication help

Posted 11 July 2011 - 06:44 PM

Dear ragingBen, Thanks for the prompt reply! I have re-written like you recommended and it makes a lot of sense. In the beginning I was unsure of how to structure the program having only recently learnt C#. I was following an example from the net but this way makes a lot more sense. It will also help when I have to process the data eventually. Also the baud rate is definately 1200.

Here is my code now

using System;
using System.IO.Ports;
using System.Collections.Generic;


namespace SerialCom
{
    class Program
    {
        //Created serial port object and initialised
        static SerialPort com = new SerialPort(SerialPort.GetPortNames()[0],
          1200, Parity.None, 8, StopBits.One);
        
        static void Main(string[] args)
        { 
            
            initiateDataStreaming();
                        
            Console.ReadKey();
        
        }

        private static void initiateDataStreaming()
        {
                      
            //Open com port
            com.Open();

            // Write Line writes string and new line value to output buffer
            // { <DLE> , <STX> , "G" , <DLE> , <ETX> , 16 BIT CRC CCITT split into two bytes}
           byte[] byteToSend = new byte[] {0x10,0x02,0x47,0x10,0x03,0x42,0x1F};
            
                      
           com.Write(byteToSend, 0, byteToSend.Length);

            Console.WriteLine("Waiting for incoming data...");
            Console.ReadKey();

            com.DataReceived +=
              new SerialDataReceivedEventHandler(com_DataReceived);
        }

        private static void com_DataReceived(object sender,
        SerialDataReceivedEventArgs e)
        {
            // Show all the incoming data in the port's buffer
            Console.WriteLine("Hello0"); // Checking if enter method
            Console.WriteLine(com.ReadExisting());
            
        }

           
    }
}




It's still not working so I will go through all the CRC stuff again and see if there are any other bugs I guess.

To tlhIn`toq , Thanks I did see that tutorial hence why I'm posting on this forum :)

Thanks for all the help guys :D
Was This Post Helpful? 0
  • +
  • -

#5 ragingben  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 170
  • View blog
  • Posts: 637
  • Joined: 07-October 08

Re: Serial port communication help

Posted 12 July 2011 - 03:16 AM

On line 37 you have a ReadKey() which means the console app will wait for a key press before subscribing to the data received event, and thus processing input from the monitor. This means that input is not being processed from the monitor until you press a key. Also you only subscribe to the data received event at this point, which is too late, as some data may have been missed. I think you need a further re-jig so that this event is subscribed to before initiating the data stream...
using System;
using System.IO.Ports;
using System.Collections.Generic;

namespace SerialCom
{
    class Program
    {
        #region StaticFields

        /// <summary>
        /// Get or set the serial port used to communicate with the device
        /// </summary>
        private static SerialPort com;

        #endregion

        #region StaticMethods

        /// <summary>
        /// The applications main entry point
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            try
            {
                // create serial port
                Program.com = new SerialPort(SerialPort.GetPortNames()[0], 1200, Parity.None, 8, StopBits.One);

                // handle data received from com port
                Program.com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived);

                // open com port
                Program.com.Open();

                // initiate streaming
                Program.initiateDataStreaming();

                // wait for input before closing
                Console.ReadKey();
            }
            catch (Exception e)
            {
                // display exception
                Console.WriteLine("An exception occured: {0}", e.Message);

                // wait for enter to acknowledge error
                Console.ReadLine();
            }
            finally
            {
                // close the port
                Program.com.Close();

                // remove handle data received from com port
                Program.com.DataReceived -= new SerialDataReceivedEventHandler(com_DataReceived);

                // dispose port
                Program.com.Dispose();

                // release port
                Program.com = null;
            }
        }

        /// <summary>
        /// Initiate data streaming with the device on the serial port
        /// </summary>
        private static void initiateDataStreaming()
        {
            // Write Line writes string and new line value to output buffer
            // { <DLE> , <STX> , "G" , <DLE> , <ETX> , 16 BIT CRC CCITT split into two bytes}
            byte[] byteToSend = new byte[] { 0x10, 0x02, 0x47, 0x10, 0x03, 0x42, 0x1F };

            // display message to user
            Console.WriteLine("Initiating data streaming...");

            // write data to port - now that the event handler is subscribed to first nothing will be missed
            com.Write(byteToSend, 0, byteToSend.Length);
        }

        #endregion

        #region EventHandlers

        private static void com_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // show all the incoming data in the port's buffer
            Console.WriteLine(com.ReadExisting());
        }

        #endregion
    }
}


I have also added in some code to clean up the port when it is finished with and some simple error handling. Notice how now the data is ready to be received before the stream is initiated, and there is no ReadKey. I have pretty much just restructred your code to be more robust, and a little closer to what I suggest in my next point...) See if this works, if you copy and paste all the code into your project.

To reitterate my previous point, I strongly urge you to seperate UI and function by creating a class CTCMonitor that fully represents the CTG monitor. This is very good OO practice. I know you are just starting this project and trying to establish communications, but it is imperative to get your class structure right straight from the start.

Your CTG Moitor class could look like this

CTGMonitor
A class that fully represents the CTG monitor. This deals with all communications, and other functionality the monitor may have. For example, there may be settings that can be adjusted via serial coms. Any functionality of the CTG monitor belongs in this class.

Properties
CommunicationsPort - A serial port object that handles all communications. You may which to handle all event subscription/unsubscription, disposal and port opening/closing in this properties setter.

Events
DataReceived - You will need to create a new event args class that inherits from EventArgs and a delegate for handling DataReceived events. This should be dispatched when any data is received form the serial port.

Methods
SendData - send a variety (string, character, btye, byte[] etc) of data to the CTG monitor

There is probally lots more you could include in this class, but it should defiently exist in some form. Your constructors should be where you define the port, and it should not be able to be modified from outside the class in my opinion. It is vital you get the protection (private, protected, internal, public) for this class correct as it is dealing with a port.

I hope this makes some sense :) I typed out a much better reply, but got an internal server error, so this will have to do for now :)

This post has been edited by ragingben: 12 July 2011 - 03:21 AM

Was This Post Helpful? 0
  • +
  • -

#6 Mya555  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 11-July 11

Re: Serial port communication help

Posted 12 July 2011 - 10:36 PM

Dear ragingben, Thanks for taking the time to re-type your response :)
I copied and pasted the code and it is still not working. I think there is a problem
with the way the two byte CRC is split up into bytes. Basically the second byte is padded with three
zeros , or rather it should be and the way I am implementing it now it is not. I will try sort this out and let you know how it goes! :D
Was This Post Helpful? 0
  • +
  • -

#7 ragingben  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 170
  • View blog
  • Posts: 637
  • Joined: 07-October 08

Re: Serial port communication help

Posted 13 July 2011 - 07:51 AM

Ah I see, so something like this...
// Write Line writes string and new line value to output buffer
// { <DLE> , <STX> , "G" , <DLE> , <ETX> , 16 BIT CRC CCITT split into two bytes with 000 between}
byte[] byteToSend = new byte[] {0x10, 0x02 ,0x47, 0x10, 0x03, 0x42, 0x30, 0x30, 0x30, 0x1F};


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1