2

I am using the SerialPort.ReadLine() method to display the data received from a Serial Port (code below).

Previously the code looked like that and received data but it did not send data. Now it is the other way around:

Since I placed the port.DataReceived event within the if(port==null) statement and added SerialPort port; as field, I don't receive data anymore. Can placing the event within an if statement change the way data is received and displayed? How can I fix that?

 //Fields
        List<string> myReceivedLines = new List<string>();
        SerialPort port;

        //subscriber method for the port.DataReceived Event
        private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            while (sp.BytesToRead > 0)
            {
                try
                {
                    myReceivedLines.Add(sp.ReadLine());
                }
                catch (TimeoutException)
                {
                    break;
                }
            }
        }

        protected override void SolveInstance(IGH_DataAccess DA)
        {
           //Opening the port
            if (port == null)
            {

                string selectedportname = default(string);
                DA.GetData(1, ref selectedportname);
                int selectedbaudrate = default(int);
                DA.GetData(2, ref selectedbaudrate);
                bool connecttodevice = default(bool);
                DA.GetData(3, ref connecttodevice);

                //Assigning an object to the field within the SolveInstance method()
                port = new SerialPort(selectedportname, selectedbaudrate, Parity.None, 8, StopBits.One);

                //Event Handling Method
                if (connecttodevice == true)
                {
                    port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                    DA.SetDataList(0, myReceivedLines);
                }
                //Enables the data terminal ready (dtr) signal during serial communication (handshaking)
                port.DtrEnable = true;
                port.Open();
            }

            //Displays if port if opened
            if (port.IsOpen)
            {
                DA.SetData(1, "Port Open");
            }

            //If the port is open do all the rest
            if (port.IsOpen)
            {
                //Assigning the input to variables for the code.
                List<string> gcode = new List<string>();
                DA.GetDataList(0, gcode);
                bool sendtoprint = default(bool);
                DA.GetData(4, ref sendtoprint);
                bool homeall = default(bool);
                DA.GetData(5, ref homeall);

                //What happens when input is set
                if (sendtoprint == true)
                {

                if (homeall == true)
                {
                    port.Write("G28" + "\n");
                }

            }
            else
            {
                DA.SetData(1, "Port Closed");
            }
        }
Community
  • 1
  • 1
Arthur Mamou-Mani
  • 2,303
  • 10
  • 43
  • 69
  • What calls `SolveInstance`? If that caller doesn't set the `port` it's going to be `null` because you didn't set it when you defined it. – Mike Perrenoud Oct 15 '12 at 11:47
  • When you create the Port the first time is connecttodevice true? – Mark Hall Oct 15 '12 at 11:48
  • is connecttodevice set to true? – BugFinder Oct 15 '12 at 11:48
  • @MarkHall and @BugFinder `connecttodevice` is set to false by default when i open the program, I set it to true later on to connect to the specific port. In some cases, the port is already open when I open the program. Could that be the problem? – Arthur Mamou-Mani Oct 15 '12 at 11:50
  • Yes because since the port is created it will never attach your event if connecttodevice is false – Mark Hall Oct 15 '12 at 11:52
  • @Mike [SolveInstance](http://www.grasshopper3d.com/forum/topics/is-the-solveinstance-method-called-everytime-an-input-is-changed) is called everytime an input is defined within the program, in this case `connecttodevice` being set to `true` – Arthur Mamou-Mani Oct 15 '12 at 11:52
  • What does this mean "Added a port field"? Previously your program worked without SerialPort, and it was OK? – Alex F Oct 15 '12 at 11:53
  • @AlexFarber sorry I edited my question: I added `SerialPort port;` as field. Previously the code looked like [that](http://stackoverflow.com/questions/12886850/sending-the-right-gcode-string-to-a-serial-port) and received data but it did not send data. Now it is the other way around. – Arthur Mamou-Mani Oct 15 '12 at 11:55

1 Answers1

1

Try something like this, removing the attaching of the eventhandler out of the port creation section

if (port == null) 
{ 
    string selectedportname = default(string); 
    DA.GetData(1, ref selectedportname); 
    int selectedbaudrate = default(int); 
    DA.GetData(2, ref selectedbaudrate); 
    bool connecttodevice = default(bool); 
    DA.GetData(3, ref connecttodevice); 

    //Assigning an object to the field within the SolveInstance method() 
    port = new SerialPort(selectedportname, selectedbaudrate, Parity.None, 8, StopBits.One); 

    //Enables the data terminal ready (dtr) signal during serial communication (handshaking) 
    port.DtrEnable = true; 

} 

if (connecttodevice == true) 
{ 
    if(!port.IsOpen)
    {
        port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); 
        DA.SetDataList(0, myReceivedLines); 
        port.Open();
    }
} 
else
{
    if(port.IsOpen)
    {
        port.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler); 
       // DA.SetDataList(0, myReceivedLines); // Not sure how you want to remove this
        port.Close();
    } 
}
Mark Hall
  • 53,938
  • 9
  • 94
  • 111
  • Thanks a lot @MarkHall, it works but i get a message error saying `Solution exception: port is already open` in the program which prevents me from sending commands to the serial port. Also, the feedback only comes when I send a command such as `HomeAll`. Does feedback only come when the device receives data? Can I therefore send a dummy code to the machine to get feedback when connecting with it? – Arthur Mamou-Mani Oct 15 '12 at 12:17
  • 1
    @ArthurMamou-Mani What line are you getting the port is already open exception on? and are you sending a connecttodevice each time you send data? – Mark Hall Oct 15 '12 at 12:20
  • the exception happens within the program when making `HomeAll` true, is there a way I could find out where it happens in the code while debugging? – Arthur Mamou-Mani Oct 15 '12 at 12:23
  • @ArthurMamou-Mani I am not sure what type of device your are connecting to, but the port opening is usually only on the PC no data is sent to the device. – Mark Hall Oct 15 '12 at 12:25
  • 1
    @ArthurMamou-Mani see change to connecttodevice code, added a check to see if port is not open before opening it. You can also put a breakpoint on the port.Open statement to check if it is being hit each time you send a command – Mark Hall Oct 15 '12 at 12:27
  • I am sending the Gcode to a RepRap 3d Printer. I thought the SerialPort.Write() sent data to the firmware of the machine. I might be confused with terminology. Do you know why the port gets opened twice? Is it because the event `port.DataReceived ` gets called twice? – Arthur Mamou-Mani Oct 15 '12 at 12:28
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/18052/discussion-between-mark-hall-and-arthur-mamou-mani) – Mark Hall Oct 15 '12 at 12:38