Pages: 1 [2] 3   Go Down
Author Topic: Problems in TX/RX data between C# and Arduino  (Read 4697 times)
0 Members and 1 Guest are viewing this topic.
Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Now i only need to work on the buffer allocation
You are telling the SerialPort class to allocate a receive buffer. I don't see that you have anything more to do.

Quote
and properly writing to the file.
Is there a problem with this? Have you confirmed that you are getting all the data to the C# application?

Quote
Is it possible to program arduino's chip and take it out of the board and use it dirrectly from a bread board?
With a few extra pieces, yes. "standalone" is the search term you want.

Quote
Will the ADC still work?
But, of course.
Logged

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

By echoing the data I confirmed that Arduino is giving me all the values that I request, however, I have not manage to get all the data in the files created. Is there any better approach to writing the data into a file? I'm using the following C#
Code:
       private void StartArduinoButton_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen == true)//checking if any port is open in order to close it
            {
                //creating output file
                string ArduinoLogName = @"" + desktopPath + "\\" + "ArduinoData_" + DateTime.Now.ToString("MMM-d-yyyy") + ".txt";//creates the log file
                FileStream ArduinoLogFile = new FileStream(ArduinoLogName, FileMode.Create);//creates a new file or overwrites a previous file created
                StreamWriter writer = new StreamWriter(ArduinoLogFile);//variable to write

                serialPort1.Write("<TX>");//Sending arduino the transmitting command
                int NumberOfReadings = int.Parse(SelNumberOfReading.SelectedItem.ToString());//converting the selected number of readings from string to ints

                for (int count = 0; count <= NumberOfReadings; count++)
                {
                    try
                    {
                        RxData = serialPort1.ReadLine();//reading data from the port
                        writer.WriteLine(RxData);//writing the transmitted data
                        Console.WriteLine(RxData);
                    }
                    catch (Exception RzData)
                    {
                        RxData = RzData.ToString();
                        writer.WriteLine(RxData);//writing the transmitted data
                        Console.WriteLine(RxData);
                    }
                }

                MessageBox.Show("The Transmission from Arduino has ended.");
                ArduinoLogFile.Close();//Closing the data file
            }
            else
            {
                MessageBox.Show("There is no Serial Ports open.");//message box telling user that there is not ports open
                StartArduinoButton.Enabled = false;//disabling the start arduino button
            }

            serialPort1.Close();//closing the serial port
            this.Refresh();
            this.Close();//closing the application
        }//end of StartArduinoButton

Also, even though I close the port and the C# application, I still face the problem of needing to open the Serial Monitor for the Arduino to be reset. Is it manageable to have a function or something do that? would I experience the same problem if i use the ATmega328 as standalone?
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Go back and look at your Arduino code. How many lines is it sending if you request one reading? 2, by my count.

How many lines does it send if you request 5 readings. 10, by my count.

How many lines are you reading in the C# application using serialPort1.read(), after requesting 1 reading? 2, by my count (count == 0 and count == 1).

How many lines are you reading in the C# application using serialPort1.read(), after requesting 5 readings? 6, by my count (count == 0, count == 1, count ==2, count ==3, count == 4, and count == 5).

Also, notice that you open a file, and get a stream writer object from the file. After writing some stuff (buffered), you close the file, without closing the streams into that file. The streams might automatically be flushed and closed, but I never rely on that happening. Flush the streams and close them, before closing the file.
« Last Edit: November 28, 2010, 07:11:24 am by PaulS » Logged

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I did not manage to understand the comment below. I took care of the stream writer ( flush it and close it ), yet I do not manage to write all the data into the file. When I echo it, I see every point requested by the C# command.

Quote
Go back and look at your Arduino code. How many lines is it sending if you request one reading? 2, by my count.

How many lines does it send if you request 5 readings. 10, by my count.

How many lines are you reading in the C# application using serialPort1.read(), after requesting 1 reading? 2, by my count (count == 0 and count == 1).

How many lines are you reading in the C# application using serialPort1.read(), after requesting 5 readings? 6, by my count (count == 0, count == 1, count ==2, count ==3, count == 4, and count == 5).

This is how the reading part of C# is looking like, can some comments be done?
Code:
       //settings for the button that starts arduino serial transmission
        private void StartArduinoButton_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen == true)//checking if any port is open in order to close it
            {
                //creating output file
                string ArduinoLogName = @"" + desktopPath + "\\" + "ArduinoData_" + DateTime.Now.ToString("MMM-d-yyyy") + ".txt";//creates the log file
                FileStream ArduinoLogFile = new FileStream(ArduinoLogName, FileMode.Create);//creates a new file or overwrites a previous file created
                StreamWriter writer = new StreamWriter(ArduinoLogFile);//variable to write

                serialPort1.Write("<TX>");//Sending arduino the transmitting command
                int NumberOfReadings;

                if (SelNumberOfReading.SelectedItem == null)
                {
                    NumberOfReadings = 50;//default number of readings
                }
                else
                {
                    NumberOfReadings = int.Parse(SelNumberOfReading.SelectedItem.ToString());//converting the selected number of readings from string to ints
                }

                for (int count = 0; count <= NumberOfReadings; count++)
                {
                    try
                    {
                        RxData = serialPort1.ReadLine();//reading data from the port
                        writer.WriteLine(RxData);//writing the transmitted data
                        Console.WriteLine(RxData);
                    }
                    catch (Exception RzData)
                    {
                       RxData = RzData.ToString();
                       writer.WriteLine(RxData);//writing the transmitted data
                       Console.WriteLine(RxData);
                    }
                }

                MessageBox.Show("The Transmission from Arduino has ended.");
                writer.Flush();//flush the streams
                writer.Close();//close the streams
                ArduinoLogFile.Close();//Closing the data file
            }
            else
            {
                MessageBox.Show("There is no Serial Ports open.");//message box telling user that there is not ports open
                StartArduinoButton.Enabled = false;//disabling the start arduino button
            }

            serialPort1.Close();//closing the serial port
            this.Refresh();
            this.Close();//closing the application
        }//end of StartArduinoButton

Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your Arduino code contains:
Code:
     Serial.print("======================");
      Serial.print(atoiHolder);Serial.print("    ");Serial.print(N);
      Serial.println("======================");

      if(N == atoiHolder)
      {
                Serial.print("IM AT THE END OF COM");
            Serial.end(); // Presumably, this has been removed.
      }

<snip>

      Serial.print(N);Serial.print(';');
      Serial.print(Input0_Data,8);Serial.print(';');
      Serial.print(Input1_Data,8);Serial.print(';');
      Serial.print(Input2_Data,8);Serial.print(';');
      Serial.print(Input3_Data,8);Serial.println(';');
If one reading is requested, there will be 3 lines of output (not two as I suggested earlier).

If ten readings are requested, there will be 21 lines of output (not 20 as I suggested earlier.

Your C# code has this:
Code:
   for (int count = 0; count <= NumberOfReadings; count++)
If one reading is requested, NumberOfReadings will be 1, and the loop will execute when count = 0 and when count = 1, reading 2 of the three lines.

If ten readings are requested, NumberOfReadings will be 10, and the loop will execite when count = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10, reading 11 of the 21 lines sent.
Logged

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just changed that part of my Arduino code to avoid getting confused, now I have the code below. However, the problem remains. When I echo this with C#, all the points requested appear on the console.


Code:
     //-------------- Executing C# Commands --------------
      if(started && ended)
      {  
            if(buffer[0] == 'N')
            {
                  buffer[0] = '0';//replaces N by '0' and now buffer holds '0','X','X','X','X'
                  atoiHolder = atoi(buffer);//atoiHolder now holds XXXX (number of reads decided by user)
            }
            if(buffer[0] == 'T' && buffer[1] == 'X')//indication from C# to TX data
            {
                  while(N <= atoiHolder)
                  {
                        //ADC OPERATION
                        Input0_Data  = analogRead(Input0);//Reading inputs from analog inputs
                        Input1_Data  = analogRead(Input1);
                        Input2_Data  = analogRead(Input2);
                        Input3_Data  = analogRead(Input3);

                        Input0_Data = Input0_Data * ToAnalogCoefficient; //converting ASCII-encoded decimal back to Analog
                        Input1_Data = Input1_Data * ToAnalogCoefficient;
                        Input2_Data = Input2_Data * ToAnalogCoefficient;
                        Input3_Data = Input3_Data * ToAnalogCoefficient;

                        Serial.print(N);Serial.print(';');//Packaging the data to be outputted to the computer
                        Serial.print(Input0_Data,3);Serial.print(';');//The selected format  N;Input0_Data;Input1_Data;Input2_Data;Input3_Data;
                        Serial.print(Input1_Data,3);Serial.print(';');
                        Serial.print(Input2_Data,3);Serial.print(';');
                        Serial.print(Input3_Data,3);Serial.println(';');
                        N = N + 1; //Incrementing the N-Domain
                        delay(10);//delay of 10ms to let ADC recover ( SEARCH IF NECESSARY )
                  }
                        
            }//end of transmitting section

            serialIn = 0;//resetting serialIn
            buffer[serialIn] = '\0';//Null the buffer array
            started = false; //reset to false
            ended = false; //reset to false

      }//end of Executing C# Commands
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I was messing around with the board and I noticed that if I press the reset button everything works fine, all the data is copied into the file created by the C# application. Is there a way of making that automatic?  ;D
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pressing the reset button on the Arduino has no impact on the code running on your PC. If you are seeing all of the data appear in the console window, and it all appears correct, the problem is with how you are writing that data to the file on the PC.

Resetting the Arduino causes the serial port connection to close. What is YOUR application doing when that happens?
Logged

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When I press the reset button my application is not doing nothing ( not even open ). does closing the port by resetting the Arduino (pressing the button) means Serial.end() ?
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Resetting the Arduino causes the serial port connection to close.
I tried ending the port connection from the Arduino code and nothing good came out of it. Is it possible to do it within the code? I haven't found a command or a way to do the reset from the code. If I place the code into the chip (permanently??), would it get damage if I have some external way to do this reset (the reset will be made many times)? Also, does Arduino's chip have some minimum time requirement for the ADC to recover?

 I'm doing the following:
Code:
void loop()
{
Serial.begin();
      while(Serial.available() > 0)
      {
            char incomingData = Serial.read(); //reading from the serial ( data from C# )

            if(incomingData == '<')//check for started packet
            {
                  started = true;//the string started
                  ended = false;
            }
            else if(incomingData == '>')//check for ended packet
            {
                  ended = true;//indicated end of the reading
                  break; //break out of the loop
            }
            else
            {
                  buffer[serialIn] = incomingData;//begining to store data in the buffer
                  serialIn++;
                  buffer[serialIn] = '\0';// NULL terminate the array
            }
      }//end of while loop

      //-------------- Executing C# Commands --------------
      if(started && ended)
      {  
            if(buffer[0] == 'N')
            {
                  buffer[0] = '0';//replaces N by '0' and now buffer holds '0','X','X','X','X'
                  atoiHolder = atoi(buffer);//atoiHolder now holds XXXX (number of reads decided by user)
            }
            if(buffer[0] == 'T' && buffer[1] == 'X')//indication from C# to TX data
            {
                  while(N <= atoiHolder)
                  {
                        //ADC OPERATION
                        Input0_Data  = analogRead(Input0);//Reading inputs from analog inputs
                        Input1_Data  = analogRead(Input1);
                        Input2_Data  = analogRead(Input2);
                        Input3_Data  = analogRead(Input3);

                        Input0_Data = Input0_Data * ToAnalogCoefficient; //converting ASCII-encoded decimal back to Analog
                        Input1_Data = Input1_Data * ToAnalogCoefficient;
                        Input2_Data = Input2_Data * ToAnalogCoefficient;
                        Input3_Data = Input3_Data * ToAnalogCoefficient;

                        Serial.print(N);Serial.print(';');//Packaging the data to be outputted to the computer
                        Serial.print(Input0_Data,3);Serial.print(';');//The selected format  N;Input0_Data;Input1_Data;Input2_Data;Input3_Data;
                        Serial.print(Input1_Data,3);Serial.print(';');
                        Serial.print(Input2_Data,3);Serial.print(';');
                        Serial.print(Input3_Data,3);Serial.println(';');
                        N = N + 1; //Incrementing the N-Domain
                        delay(10);//delay of 10ms to let ADC recover ( SEARCH IF NECESSARY )
                  }
              
            }//end of transmitting section
Serial.end();
            serialIn = 0;//resetting serialIn
            buffer[serialIn] = '\0';//Null the buffer array
            started = false; //reset to false
            ended = false; //reset to false

      }//end of Executing C# Commands
}//end of loop
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your problem is on the PC side and how you are handling the data there, not on the Arduino. Closing the serial port on the Arduino side will effectively take it off-line, and your PC application will not be able to talk to it again (until it is reset).

Quote
I haven't found a command or a way to do the reset from the code.
There isn't one. There are some methods to cause the Arduino to appear to reset, but they are not supported, and the side effects depend on the method. I'm not going to comment further on how to do it, because it is NOT what you need to do.

Quote
Also, does Arduino's chip have some minimum time requirement for the ADC to recover?
Yes. You can check the Atmel data sheet for particulars. Somewhere between 10 and 100 milliseconds generally works, depending on what is being measured.
Logged

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Reset problem solved. Now i just need to make the code a bit more fault tolerant. thanks a lot for your help PaulS  smiley

Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Reset problem solved.
That's great. What was the problem?
Logged

New York, NY
Offline Offline
Newbie
*
Karma: 0
Posts: 41
Almighty Forum, help this newbie solve his problem
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just needed to set N = 0 before the while loop.
Logged

If you think you have it, you don't. If you think you don't have it, you still don't.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I just needed to set N = 0 before the while loop.
Ah, yes. The little things that trip you up.
Logged

Pages: 1 [2] 3   Go Up
Jump to: